---
name: assign-workflow
description: 研发经理每轮巡检工作流：指派 CC（Todo→In Progress）、attention-only 巡检 CC 进度、恢复异常 CC、阶段性验证报告、PLAN.md 维护。每10分钟 loop 时自动触发。
---

# 研发经理工作流

> 当前角色：**研发经理**，负责指派、巡检、恢复和验证。
> 排程分析由排程经理负责，见 scheduler-workflow skill。

## 每轮巡检执行顺序（强制）

1. **检查未回复消息** — tmux 会话中有 `【需回复】` → 立即回复后再执行巡检
2. **任务一** — 指派（有空闲 kimi 槽位时）← **优先于响应消息**
3. **任务二** — 巡检 CC 进度（attention-only 模式）
4. **任务三** — 恢复异常 CC（SAVED / 超时）
5. **任务四** — 阶段性验证报告（≥3 个新 Done 时触发）
6. **PLAN.md 同步** — 更新当前运行表 + 指派历史表

## ⚠️ Done 的硬定义（红线）

Issue → Done 必须**同时满足**，缺一不可：

1. `gh pr view <PR> --json mergedAt --jq '.mergedAt'` 返回非空时间
2. `gh issue view <N> --json state,stateReason` 返回 `closed/completed`

Done 由 `pr-test.yml` 自动触发。研发经理 ⛔ **永远不要**主动执行：
- `update-project-status.sh --status "Done"`
- `gh issue close`
- 任何手动改看板为 Done 的操作

### CC 目录释放时机（红线）

**PR merge ≠ 目录释放**。锁文件释放必须满足：

| 条件 | 说明 |
|------|------|
| PR merged | 触发 CI 部署 |
| CI 部署到 dev 成功 | **真正释放锁文件** |
| 锁文件 `/home/ubuntu/cc_scheduler/lock/wande-play-kimi{N}.lock` 已删除 | 可指派新 Issue |

**不能**在 PR merge 后立即指派新 Issue 到同一 kimi，必须等 dev 部署完成。

### 状态对照表

| 阶段 | 看板状态 | 研发经理动作 |
|------|---------|-------------|
| 指派启动 CC | Todo → In Progress | 手动改（**唯一主动变更**） |
| CC 写代码中 | In Progress | 仅巡检注入，不改状态 |
| CC 退出无 PR | In Progress | 注入「执行 gh pr create」 |
| PR open + CI 跑中 | In Progress | 等 CI，不改状态 |
| PR + CI failure | In Progress | 看失败详情，注入 CC 修复 |
| PR + CONFLICTING | In Progress | 注入 rebase 命令 |
| PR squash-merged | **自动 → Done** | 仅 PLAN.md 划删除线 |
| CI 部署到 dev 成功 | — | **删除锁文件**，可指派新 Issue 到同一 kimi |
| CC 异常无法恢复 | Fail | **唯一允许的失败终态变更** |

### ⛔ Done 禁止操作

- CC 进程退出就改 Done
- PR 已创建就改 Done
- tmux 输出 "完成/done/✅" 就改 Done
- 手动 `gh issue close`
- In Progress 直接跳 Done
- 批量把多个 issue 改 Done
- **PR merge 后立即指派新 Issue 到同一 kimi**（必须等 dev 部署）

### Done Guard（硬隔离）

`update-project-status.sh --status "Done"` 内置硬校验：必须存在引用该 issue 且 `mergedAt` 非空的 PR，否则 **exit 2** 拒绝执行。

### 拿不准时

```bash
gh pr list --repo WnadeyaowuOraganization/wande-play --search "Issue-<N> in:branch" --state all --json number,state,mergedAt
gh issue view <N> --repo WnadeyaowuOraganization/wande-play --json state,stateReason,closedAt
```

## 任务一：指派（Todo → In Progress）

### 触发条件

| 条件 | 动作 |
|------|------|
| 有 PR merged | 更新 PLAN.md（**不等 dev 部署**） |
| CI 部署到 dev 成功 + 锁文件已删除 | **立即**指派新 Issue 到同一 kimi |
| `bash scripts/cc-check.sh` 显示活跃 CC < 5 且有空闲 kimi 目录 | **立即指派** |
| 指派建议表刷新新增项 | 立即指派（有空槽时） |

### 执行步骤

```bash
# 1. 检查槽位（最多8个并发CC，用cc-check.sh）
bash scripts/cc-check.sh

# 2. 检查空闲 kimi 目录（锁文件不存在）
ls /home/ubuntu/cc_scheduler/lock/wande-play-kimi*.lock

# 3. 读排程经理的指派建议表
cat sprints/sprint-<N>/PLAN.md | grep -A 25 "指派建议"

# 4. 优先指派 P0 > P1 > P2

# 5. 启动 CC（kimi 目录必须有锁文件才能复用）
rm -f /home/ubuntu/cc_scheduler/lock/wande-play-kimi{N}.lock
bash scripts/run-cc.sh --module <module> --issue <N> --dir <kimi目录> --effort <effort>

# 6. 更新 PLAN.md 三处
```

### module 对应

| 标签 | `--module` | 实际目录 |
|------|-----------|---------|
| `module:backend` | backend | `wande-play-<suffix>/backend` |
| `module:frontend` | frontend | `wande-play-<suffix>/frontend` |
| `module:pipeline` | pipeline | `wande-play-<suffix>/pipeline` |
| `module:fullstack` | fullstack | `wande-play-<suffix>/`（根目录） |

### E2E 修复类 Issue 指派规则

1. **effort 统一为 low**（比 feature 短 50%）
2. **指派建议表标注「E2E优先派空闲CC」**
3. **不同测试文件可并发，同文件不可并发**
4. 优先从空闲槽位安排 E2E Issue

## 任务二：巡检 CC 进度（attention-only 模式）

> **必须使用 `bash scripts/cc-check.sh`** 作为全场 CC 状态主数据源，它直接查 tmux session，比 server.py 更可靠。

### Step 1：拉取全场摘要

```bash
bash scripts/cc-check.sh
```

此脚本输出：
- 运行中的 CC 会话列表
- 锁文件状态
- 最近输出行
- 超时需处理的 CC

### Step 2：处理 attention CC

```bash
# 用 server.py 预筛 needs_attention
ATTENTION=$(curl -s http://localhost:9872/api/status \
  | jq -c '.agents[] | select(.needs_attention)')

if [ -z "$ATTENTION" ]; then
  echo "✓ 全场自监控中，本轮无需介入"
fi
```

### attention 触发条件

| 条件 | 原因字段 | 处理 |
|------|---------|------|
| `needs_attention: true` | 由 server.py 规则引擎设置 | 查 `attention_reason` 字段 |
| 静默超时 | `静默 N 分钟无新输出` | 唤醒或 kill 重启 |
| 无 PR | `无 PR 已超时` | 注入 `gh pr create` |
| CI failure | `CI 失败` | 注入修复 |
| Fail 终态 | `CC 已放弃` | 标 Fail |

### Step 2：处理 attention CC

```bash
echo "$ATTENTION" | jq -c '.' | while read agent; do
  ID=$(echo "$agent" | jq -r '.id')
  ISSUE=$(echo "$agent" | jq -r '.issue_number')
  REASON=$(echo "$agent" | jq -r '.attention_reason')

  case "$REASON" in
    *"静默"*) tmux capture-pane -t "$ID" -p -S -100 | tail -50 ;;
    *"无 PR"*) bash scripts/inject-cc-prompt.sh $ISSUE "请确认进度，如已完成请 push + gh pr create" ;;
    *"Fail 终态"*) bash scripts/update-project-status.sh --repo play --issue $ISSUE --status "Fail" ;;
  esac
done
```

### Step 3：检查最近 merged PR（PLAN.md 同步用）

```bash
gh pr list --repo WnadeyaowuOraganization/wande-play --state merged \
  --search "merged:>$(date -u -d '15 minutes ago' +%Y-%m-%dT%H:%M:%S)" \
  --json number,title,mergedAt,headRefName \
  --jq '.[] | "\(.number)\t\(.headRefName)\t\(.mergedAt)"'
```

### 巡检判断标准

| 现象 | 处理（**全程不允许改 Done**） |
|------|------|
| 编译错误停滞 | 注入「检查编译错误并修复」 |
| 输出"完成"但无 PR | 注入「执行 gh pr create」 |
| 会话不存在 + SAVED | 重新 run-cc.sh 同参数重入 |
| 超30分钟无输出 | kill-session → run-cc.sh 重启 |
| PR 等 CI | **不做任何变更** |
| PR CONFLICTING | 注入 rebase 命令 |
| PR CI failure | 看失败详情，注入修复 |
| PR merged 但 PLAN.md 未更新 | 删行 + 划线（看板由 CI 自动改） |
| PR 超2小时未 merged | 检查卡在哪个 CI job |
| Issue closed 但 PR 不存在 | **误关，立即 reopen** |

## 任务三：恢复异常 CC

```bash
bash scripts/cc-check.sh | grep "SAVED\|超时"

# 诊断卡住CC（自动分析tmux输出、上下文、锁状态）
bash scripts/cc-diagnose-stuck.sh

# 重新触发
bash scripts/run-cc.sh --module <原module> --issue <N> --dir <原kimi目录> --effort <原effort>

# cc-keepalive.sh 自动重试 ≤10 次后自动标 Fail，研发经理通常不主动操作
```

## 任务四：阶段性验证报告

触发：自上次报告起累计 ≥3 个新 Done，或连续 2 个相同 Fail 原因。

```bash
bash scripts/query-project-issues.sh --repo play --status "Done" 2>/dev/null
bash scripts/query-project-issues.sh --repo play --status "Fail" 2>/dev/null
bash scripts/cc-check.sh
```

写入 `docs/workflow/新harness验证报告.md`，格式：

```markdown
## 批次验收 YYYY-MM-DD HH:MM

### 完成情况
### 问题归因
### 流水线状态
### 下批建议
```

## PLAN.md 维护规范

### 写权限分工

| 区域 | 维护方 |
|------|-------|
| 「指派建议」表 | **排程经理** 写，研发经理只读 |
| Sprint 明细表 `状态` 列 | **排程经理** 写 |
| 「当前运行」表 | **研发经理** 写 |
| 「指派历史」表 | **研发经理** 写 |

### 何时更新

| 事件 | 更新位置 |
|------|---------|
| 指派新 Issue | 当前运行 + 指派历史 各新增行 + **指派建议表删除已派行** |
| PR squash-merged | 当前运行删行 + 指派历史 ~~Done~~ |
| CC 失败放弃 | 当前运行删行 + 指派历史 ~~Fail~~ |

> ⚠️ "CC 进程退出" **不是**事件触发器！只有 PR mergedAt 非空才允许标 Done。

### 并发约束

改 PLAN.md 前必须 `git pull`，改完立即 `git add + commit + push`。

## 故障兜底

| 现象 | 处理 |
|------|------|
| `gh` 401 | `export GH_TOKEN=$(python3 scripts/gh-app-token.py wandeyaowu)` |
| `cc-check.sh` 报错 | `git pull` 同步最新版本 |
| `tmux send-keys` 特殊字符 | 用 `scripts/inject-cc-prompt.sh` |
| CC卡住诊断 | `bash scripts/cc-diagnose-stuck.sh` |

## 辅助 Agent

- `pr-reviewer.md` — AI PR 审查员 subagent

## 当前 Sprint 确认

```bash
cat docs/status.md | head -150
cat sprints/sprint-<N>/PLAN.md | head -50
```
