--- name: milestone description: 单元(后端模块 / 前端阶段)全部 approve 后的收尾闸门:子会话跑测试 → 写完成报告 → 本地 merge 进默认分支 + 打 milestone/ tag + 回写 docs/08 → 自动回调 coding-start。phase 由当前分支推断。 user-invocable: false allowed-tools: Read Write Edit Skill Agent Bash(git *) --- **所有输出必须使用中文。** # milestone 单元(后端模块 / 前端阶段)所有功能完成、所有 approve 齐全后的唯一收尾闸门。把原来三个 skill 的职责合并为四个阶段依次执行: 1. **推断 phase**(分支名 → backend / frontend) 2. **测试闸门**(子会话跑测试,绿才能继续) 3. **完成报告**(6 节,commit 到当前分支) 4. **本地集成 + tag + 回写 docs/08 + 自动回调** ## 阶段 0:推断 phase 与关键变量 执行 `git branch --show-current`: - 匹配 `module-` → `phase=backend`,`phase_id=`(去掉 `module-` 前缀),`tag=milestone/`,`test_command=./scripts/test.sh` - 等于 `frontend-phase` → `phase=frontend`,`phase_id=frontend-phase`,`tag=milestone/frontend-phase`;`test_command` 从 `docs/04-技术规范.md § 零 frontend.test_command` / `frontend.e2e_command` 拼接(缺失则 `pnpm test:ci && pnpm e2e:ci`) - 其它任何分支 → **硬停**,打印以下诊断并终止(分支切换职责在上游 `phase-driver`,不在此处): ``` [milestone] ⛔ 当前分支 不满足执行条件。 milestone 只能在 module- 或 frontend-phase 分支上运行。 请检查 phase-driver 是否正确切换了分支。 ``` 记录变量:`branch`(原始分支名),`phase`,`phase_id`,`tag`,`test_command`。 ## 阶段 1:测试闸门(子会话硬门) > **护栏(绝对规则):绝不在主会话直接执行测试命令。必须通过 Agent 子会话(general-purpose)运行,主会话只接收结构化 JSON 结论。** 1. 派发 Agent 子会话,传入 `test_command`,要求子会话仅返回以下结构化 JSON(不输出任何描述文字): ```json { "command": "<实际执行的命令>", "exit_code": , "passed": , "failed": , "stdout_excerpt": "<最后 30 行,含 FAIL 摘要>" } ``` 2. 接收 JSON 后保存为本地变量(`test_json`),不写独立文件——测试证据将折叠进阶段 2 的报告 `## ② 测试证据` 节。 3. **`exit_code = 0`(绿色)** → 进入阶段 2。 4. **`exit_code ≠ 0`(红色)** → 打印以下横幅并**停止**,不进入任何下游阶段,不自动重试,不自动修复: ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ [milestone] ⚠️ 测试未通过 (phase=) 命令: 退出码: 失败: 摘要: 按失败类型选恢复路径: ① 测试脆弱(偶发 flakey)→ 重跑 /erp-workflow:coding-start (phase-driver 幂等:所有单元已 approve 会跳过功能循环,直接重跑本闸门) ② 真有回归 后端:rm docs/superpowers/reviews/*-.md → 重跑 /erp-workflow:coding-start(phase-driver 视该 REQ 未完成,重走功能循环) 前端:rm docs/superpowers/reviews/*-FE-.md → 重跑 /erp-workflow:coding-start(phase-driver 视该 FE 未完成,重走功能循环) ③ 环境 / 依赖问题(DB 连不上 / 外部 API 失败 / 证书失效 / Playwright 浏览器未装) → Skill(interrupt-check) 追加 Blocker → 修复环境 → 参考 .env.local / docs/04 § 零 环境配置 → 重跑 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ``` ## 阶段 2:完成报告 > **核心约束:只收集 git 摘要,绝不把 diff 正文读入主会话上下文。** ### 2.1 收集输入 **后端(phase=backend):** - §③ 文件变更: ```bash git diff --stat ..HEAD git diff --name-status ..HEAD git log --oneline ..HEAD ``` `` = 本模块分支从默认分支分叉的 commit(`git merge-base `) - §④ Migration:`git diff --name-only --diff-filter=A ..HEAD -- 'sql/migrations/V*.sql'` 列新增 migration 文件名;若有,逐个 Read 第一行作简短说明。 - §⑤ 偏离:Read `docs/superpowers/reviews/<日期>--*.md`(如存在),提取偏离与取舍说明。 - §① 覆盖单元:扫 `docs/superpowers/reviews/` 下属于本模块的 `<日期>-.md`,列出 REQ ID 与标题。 **前端(phase=frontend):** - §③ 文件变更:同上,区间为 `frontend-phase` 分支起点 → HEAD - §① 覆盖单元:扫 `docs/superpowers/reviews/<日期>-FE-*.md`,按 FE-NN 顺序列出 - §④ Migration:填 `N/A(前端阶段)` - §⑤ 偏离:除常规偏离外,额外审查"实际渲染 DOM 与各 FE 关联原型主结构的差异",逐 FE 列出(关联原型清单见每个 FE 的 spec) ### 2.2 渲染并 commit 报告 按 `${CLAUDE_SKILL_DIR}/templates/milestone-report-template.md` 渲染 6 节。`{{milestone_tag}}` 先填占位符 `{{milestone_tag}}`(阶段 3 步骤 6 回写)。 写入 `docs/superpowers/milestone-reports/-.md`。 ```bash git add docs/superpowers/milestone-reports/-.md git commit -m "docs(): add completion report" ``` **此 commit 是必需的**——阶段 3 的 worktree-clean 前置检查依赖于此。 ## 阶段 3:本地集成 + tag + 回写 docs/08 ### 3.1 验证 worktree 干净 ```bash git status --porcelain ``` 输出非空 → **停止**,打印 dirty 文件清单: ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ [milestone] ⚠️ worktree 不干净,无法集成 + 打里程碑 集成前所有 evidence 必须已 commit。检查点: - 阶段 2 是否已 commit 完成报告? (阶段 1 测试证据已折叠进报告,无单独文件需 commit) 修复:git add && git commit -m "...",然后重跑 /erp-workflow:coding-start。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ``` ### 3.2 探测本地默认分支 用 `git rev-parse --verify` 依次探测本地 `main`、`master`,取第一个存在的作为 `default_branch`。两者都不存在 → 停止报错(不自动创建分支)。 ### 3.3 本地 merge ```bash git checkout git merge --no-ff -m "merge(): integrate " ``` 合并冲突 → 停止,打印冲突文件清单,引导人工解决后重跑 `/erp-workflow:coding-start`(不自动 `--abort`,不强制覆盖)。 ### 3.4 回写 docs/08 里程碑字段 在 `default_branch` 上 `Edit docs/08-模块任务管理.md`: - **phase=backend**:在 § 二 找到当前模块行 ` - 里程碑: —` → ` - 里程碑: milestone/` - **phase=frontend**:在 § 三 找到 `- 整体里程碑: —` → `- 整体里程碑: milestone/frontend-phase` ```bash git add docs/08-模块任务管理.md git commit -m "chore(): record milestone/ in docs/08" ``` ### 3.5 打 annotated tag ```bash git tag -a milestone/ -m "milestone(): 阶段完成" ``` tag 已存在(重跑场景)→ 跳过,不重复打。 ### 3.6 追加 tag 到报告 §⑥ 并 commit `Edit docs/superpowers/milestone-reports/-.md`,把 `{{milestone_tag}}` 替换为 `milestone/`(已替换则跳过)。 ```bash git add docs/superpowers/milestone-reports/-.md git commit -m "docs(): record milestone/ in completion report" ``` ## 阶段 4:自动回调 本阶段已集成 + 打 tag,**不停下等人工**。立即调用: ``` Skill(coding-start) ``` coding-start 重新检查后端 / 前端完成性(按 `里程碑:` 字段 + `git tag -l`),未完则推进下一模块 / 前端阶段;全部完成则打印"所有阶段已完成"。 ## 护栏 - **绝不**在主会话直接执行 `./scripts/test.sh` / `pnpm test` / `pnpm e2e`——必须通过 Agent 子会话 - 本闸门是里程碑 tag 前唯一的硬测试门——红色时**绝不**跳过直接进入集成 / 打 tag - worktree 不干净时不执行 merge(停下,不修复) - 合并冲突时不自动解决(停下,指引人工) ## 参考 - `${CLAUDE_SKILL_DIR}/templates/milestone-report-template.md`(6 节完成报告) - 上游:`phase-driver`(后端所有 REQ / 前端所有 FE 全部 approve 后派发到此) - 下游:`coding-start`(自治回调,由其路由下一阶段)