SKILL.md 8.91 KB

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-<id>phase=backendphase_id=<id>(去掉 module- 前缀),tag=milestone/<id>test_command=./scripts/test.sh
  • 等于 frontend-phasephase=frontendphase_id=frontend-phasetag=milestone/frontend-phasetest_commanddocs/04-技术规范.md § 零 frontend.test_command / frontend.e2e_command 拼接(缺失则 pnpm test:ci && pnpm e2e:ci
  • 其它任何分支 → 硬停,打印以下诊断并终止(分支切换职责在上游 phase-driver,不在此处):
  [milestone] ⛔ 当前分支 <branch> 不满足执行条件。
  milestone 只能在 module-<id> 或 frontend-phase 分支上运行。
  请检查 phase-driver 是否正确切换了分支。

记录变量:branch(原始分支名),phasephase_idtagtest_command

阶段 1:测试闸门(子会话硬门)

护栏(绝对规则):绝不在主会话直接执行测试命令。必须通过 Agent 子会话(general-purpose)运行,主会话只接收结构化 JSON 结论。

  1. 派发 Agent 子会话,传入 test_command,要求子会话仅返回以下结构化 JSON(不输出任何描述文字):
   {
     "command": "<实际执行的命令>",
     "exit_code": <int>,
     "passed": <int>,
     "failed": <int>,
     "stdout_excerpt": "<最后 30 行,含 FAIL 摘要>"
   }
  1. 接收 JSON 后保存为本地变量(test_json),不写独立文件——测试证据将折叠进阶段 2 的报告 ## ② 测试证据 节。

  2. exit_code = 0(绿色) → 进入阶段 2。

  3. exit_code ≠ 0(红色) → 打印以下横幅并停止,不进入任何下游阶段,不自动重试,不自动修复:

   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    [milestone] ⚠️ 测试未通过 (phase=<phase>)
    命令:   <test_command>
    退出码: <exit_code>
    失败:   <failed>
    摘要:   <stdout_excerpt>

    按失败类型选恢复路径:
    ① 测试脆弱(偶发 flakey)→ 重跑 /erp-workflow:coding-start
       (phase-driver 幂等:所有单元已 approve 会跳过功能循环,直接重跑本闸门)
    ② 真有回归
       后端:rm docs/superpowers/reviews/*-<REQ-id>.md
            → 重跑 /erp-workflow:coding-start(phase-driver 视该 REQ 未完成,重走功能循环)
       前端:rm docs/superpowers/reviews/*-FE-<NN>.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 <branch_start>..HEAD git diff --name-status <branch_start>..HEAD git log --oneline <branch_start>..HEAD <branch_start> = 本模块分支从默认分支分叉的 commit(git merge-base <branch> <default_branch>
  • §④ Migration:git diff --name-only --diff-filter=A <branch_start>..HEAD -- 'sql/migrations/V*.sql' 列新增 migration 文件名;若有,逐个 Read 第一行作简短说明。
  • §⑤ 偏离:Read docs/superpowers/reviews/<日期>-<phase_id>-*.md(如存在),提取偏离与取舍说明。
  • §① 覆盖单元:扫 docs/superpowers/reviews/ 下属于本模块的 <日期>-<REQ-id>.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/<YYYY-MM-DD>-<phase_id>.md

git add docs/superpowers/milestone-reports/<YYYY-MM-DD>-<phase_id>.md
git commit -m "docs(<phase_id>): add completion report"

此 commit 是必需的——阶段 3 的 worktree-clean 前置检查依赖于此。

阶段 3:本地集成 + tag + 回写 docs/08

3.1 验证 worktree 干净

git status --porcelain

输出非空 → 停止,打印 dirty 文件清单:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 [milestone] ⚠️ worktree 不干净,无法集成 + 打里程碑

 <git status 输出>

 集成前所有 evidence 必须已 commit。检查点:
 - 阶段 2 是否已 commit 完成报告?
 (阶段 1 测试证据已折叠进报告,无单独文件需 commit)

 修复:git add <files> && git commit -m "...",然后重跑 /erp-workflow:coding-start。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

3.2 探测本地默认分支

git rev-parse --verify 依次探测本地 mainmaster,取第一个存在的作为 default_branch。两者都不存在 → 停止报错(不自动创建分支)。

3.3 本地 merge

git checkout <default_branch>
git merge --no-ff <branch> -m "merge(<phase_id>): integrate <branch>"

合并冲突 → 停止,打印冲突文件清单,引导人工解决后重跑 /erp-workflow:coding-start(不自动 --abort,不强制覆盖)。

3.4 回写 docs/08 里程碑字段

default_branchEdit docs/08-模块任务管理.md

  • phase=backend:在 § 二 找到当前模块行 - 里程碑: —- 里程碑: milestone/<phase_id>
  • phase=frontend:在 § 三 找到 - 整体里程碑: —- 整体里程碑: milestone/frontend-phase
git add docs/08-模块任务管理.md
git commit -m "chore(<phase_id>): record milestone/<phase_id> in docs/08"

3.5 打 annotated tag

git tag -a milestone/<phase_id> -m "milestone(<phase_id>): <phase> 阶段完成"

tag 已存在(重跑场景)→ 跳过,不重复打。

3.6 追加 tag 到报告 §⑥ 并 commit

Edit docs/superpowers/milestone-reports/<YYYY-MM-DD>-<phase_id>.md,把 {{milestone_tag}} 替换为 milestone/<phase_id>(已替换则跳过)。

git add docs/superpowers/milestone-reports/<YYYY-MM-DD>-<phase_id>.md
git commit -m "docs(<phase_id>): record milestone/<phase_id> 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(自治回调,由其路由下一阶段)