Commit f0cff74ca4a0874233c9dfb0533f48d6dae78490

Authored by zichun
1 parent cb2e2bf3

feat(lite): unify backend+frontend feature loops into one phase-parameterized 3-step chain

- Add feature-spec (brainstorm+plan merged, phase switch for backend/frontend)
- Overwrite feature-tdd with dual-phase support (path guards, test dispatch, commit trailers)
- Overwrite feature-review with verify+review merged, both reviewer agents, phase-driver callback, 5-round cap
- Delete 8 superseded skills: feature-{brainstorm,plan,verify} + fe-feature-{brainstorm,plan,tdd,verify,review}
skills/coding/fe-feature-brainstorm/SKILL.md deleted
1   ----
2   -name: fe-feature-brainstorm
3   -description: 前端功能循环第 1 步。针对单个 FE-NN 页面(prototype/*.html)做交互式 Q&A + 写前端规格,产出到 docs/superpowers/specs/,链入 fe-feature-plan。
4   -user-invocable: false
5   -allowed-tools: Read Write Skill AskUserQuestion Glob Grep
6   ----
7   -
8   -**所有输出必须使用中文。**
9   -
10   -# fe-feature-brainstorm
11   -
12   -## 阶段范围(前端)
13   -
14   -本 skill 服务于**前端阶段**。产出范围限定为:组件树 / 页面状态机 / 交互流程 / API 调用 / Design Tokens 引用 / 业务校验前端复刻。**不涉及** SQL / migration / controller / service / DTO(这些已在后端阶段完成)。
15   -
16   -一个 FE 是**业务功能**粒度,可能关联多个 prototype 文件区域和多个 REQ。
17   -
18   -## 占位符规则
19   -
20   -本 skill 写的 spec 是 CC 内部推理产物,不是用户审阅文档。**不允许** `【人工填写:...】` 占位符——A 阶段标记。需要具体值时:
21   -
22   -1. **先查** `.env.local` / `docs/07-环境配置.md` / `docs/04-技术规范.md` / `docs/06-UI交互规范.md` / `CLAUDE.md` / 现有代码 / 关联 prototype。值已落地某处 → 在 spec 中引用源
23   -2. **再问**:查不到 → `AskUserQuestion` 问用户,记录答案到 spec
24   -3. **绝不**留 `【人工填写:】` 占位符
25   -
26   -## 执行步骤
27   -
28   -1. **收集上下文**:确定本次 FE(由 `frontend-start` 派发时传入 `{ fe_id, name, associated_reqs[], associated_prototypes[] }`),读取证据:
29   - - **页面骨架**:Read 所有 `associated_prototypes[]`(如 `prototype/dashboard.html` + `prototype/dashboard.html#metrics-section`;含 anchor 时聚焦相应区域),作为本 FE 涉及页面的布局权威
30   - - **业务规则**:Read 所有 `associated_reqs[]` 对应的 `docs/01-需求清单/<module>/<REQ-id>.md`,提取业务校验规则、acceptance、UI 描述
31   - - **API 契约**:Read `docs/05-API接口契约.md`,按 `associated_reqs[]` 过滤出本 FE 消费的端点
32   - - **Design Tokens**:Read `docs/06-UI交互规范.md § 二`,作为色值/状态色的引用源
33   - - **前端组件库**:Read `docs/04-技术规范.md § 零` 找 `frontend.ui_lib`(如 Ant Design / Element Plus),决定组件选型
34   -
35   -2. **交互式 Q&A**(参考下方"Q&A 原则",本次为**前端阶段**头脑风暴):
36   - - 关注:组件树、页面状态机、交互流程、API 调用一致性、Design Tokens 引用、业务校验前端复刻
37   - - **不要**讨论 SQL / migration / controller / service / DTO(后端阶段已定)
38   - - **一次一问** `AskUserQuestion`,仅对真模糊点;多选题优先
39   - - trade-off 直接内嵌 spec,**不设确认 gate**
40   -
41   -3. **写 spec 到 `docs/superpowers/specs/<YYYY-MM-DD>-<fe_id>.md`**:
42   - - 按 `${CLAUDE_SKILL_DIR}/templates/fe-feature-spec-template.md` 渲染
43   - - 规格至少含:
44   - - 关联 REQ + 关联原型(来自 frontend-start 派发的入参)
45   - - 组件树(多个 prototype 文件 / 区域则按页面分块;推导自 prototype DOM)
46   - - 页面状态机(loading / empty / error / 正常 / 表单提交中 至少 5 态;多页则按页列出)
47   - - 消费的后端端点(与 docs/05 对齐,按本 FE 的 `associated_reqs[]` 过滤)
48   - - 业务规则前端复刻清单(逐条,每条标注:规则描述 / 触发时机 / 报错文案 / 来源 REQ)
49   - - Design Tokens 引用清单(本 FE 用到的 `var(--color-*)` 名称)
50   - - 文件已存在 → 征求用户确认后覆盖
51   -
52   -4. **Spec 自审**(inline 修,无须用户等待):
53   - - 所有顶级节非空
54   - - **全文不得出现** `TBD` / `@todo` / `controller` / `SQL` / `service` / `migration` 字样——前者代表 spec 未完成,后五者属于后端范畴不应出现。命中 → 修正后重渲染
55   - - **内部一致性** / **范围检查** / **歧义检查**(按 Q&A 原则)
56   -
57   -5. **输出 + 链 fe-feature-plan**(**直接做这两件事,不要输出"回交父 skill / 交给 caller / 等下一步 / 准备好了请检查"之类的桥接叙述**——那些会被解读为 turn 结束信号):
58   - - 输出一行 `fe-feature-brainstorm: <fe_id> → <path>`
59   - - **同一 turn 内立即** `Skill(fe-feature-plan)`
60   -
61   -## Q&A 原则
62   -
63   -- **一次一问** — 不堆问题
64   -- **多选题优先** — 答更快
65   -- **仅对真模糊点问** — 不造确认问题
66   -- **YAGNI** — 删不必要的功能
67   -- **渐进理解** — 不明白就问
68   -- **无审批 gate** — 写 spec 即 commit
69   -
70   -## 参考
71   -
72   -- `${CLAUDE_SKILL_DIR}/templates/fe-feature-spec-template.md`
73   -- 上游:`frontend-start`(每个未完成 FE 派发到此)
74   -- 下游:`fe-feature-plan`
skills/coding/fe-feature-brainstorm/templates/fe-feature-spec-template.md deleted
1   -# 前端功能规格 — {{fe_id}} {{name}}
2   -
3   -> 关联 REQ:{{associated_reqs}}
4   -> 关联原型:{{associated_prototypes}}
5   -> 日期:{{date}}
6   -
7   -## 一、功能概述
8   -
9   -{{feature_overview}}
10   -
11   -## 二、组件树
12   -
13   -<!-- 基于关联原型的 DOM 结构推导。多页则按页面分块;每层缩进表示嵌套关系。 -->
14   -
15   -```
16   -{{component_tree}}
17   -```
18   -
19   -## 三、页面状态机
20   -
21   -| # | 状态 | 触发条件 | 视觉表现 | 用户可执行操作 |
22   -|---|------|---------|---------|--------------|
23   -{{state_machine_rows}}
24   -
25   -至少包含:loading / empty / error / 正常 / 提交中 五态。
26   -
27   -## 四、消费的后端端点
28   -
29   -| # | 方法 | 路径 | 触发时机 | 关联 REQ |
30   -|---|------|------|---------|---------|
31   -{{endpoint_rows}}
32   -
33   -## 五、业务规则前端复刻清单
34   -
35   -| # | 规则描述 | 触发时机 | 报错文案 | 来源 REQ |
36   -|---|---------|---------|---------|---------|
37   -{{validation_rows}}
38   -
39   -> **要求**:每条规则必须在前端 form-level 校验中复刻,不仅依赖后端报错。文案与后端语义一致。
40   -
41   -## 六、Design Tokens 引用清单
42   -
43   -<!-- 列出本页面用到的 token 变量名(不写 hex),如 var(--color-primary) / var(--color-bg-card)。来源见 docs/06 § 二。 -->
44   -
45   -```
46   -{{token_list}}
47   -```
48   -
49   -## 七、交互流程关键路径
50   -
51   -{{interaction_flow}}
52   -
53   -## 八、备注与开放问题
54   -
55   -{{open_questions}}
skills/coding/fe-feature-plan/SKILL.md deleted
1   ----
2   -name: fe-feature-plan
3   -description: 前端功能循环第 2 步。将 FE 规格转任务级实现计划(每任务 2-5 分钟,含组件路径、props 契约、测试意图),产出到 docs/superpowers/plans/,链入 fe-feature-tdd。
4   -user-invocable: false
5   -allowed-tools: Read Write Grep Skill AskUserQuestion
6   ----
7   -
8   -**所有输出必须使用中文。**
9   -
10   -# fe-feature-plan
11   -
12   -## 阶段范围(前端)
13   -
14   -把当前 FE 的规格转成任务级实现计划。任务粒度限定为:**组件文件 / 路由配置 / store hook / API client 包装函数**。**不允许**生成涉及后端文件(controller / service / repository / SQL)的任务。
15   -
16   -## 计划写作原则
17   -
18   -- Plan 告诉 TDD 执行者**做什么**,不是**怎么写代码**——执行者是 `fe-feature-tdd`(同一模型,全上下文)
19   -- Plan 锁定**文件边界 + 测试意图 + props 契约 + 完成判据**;代码由 TDD 红绿循环产出
20   -- **禁止 dump 整个文件内容**(vue/react 组件源码、config 文件)到 plan
21   -- 每个任务标注"测试先行类型" = **jsdom 组件测试** OR **Playwright E2E**
22   -- DRY、YAGNI、TDD、frequent commits
23   -
24   -## 占位符规则
25   -
26   -每个 step 必须写实际内容。以下绝不出现:
27   -
28   -- `TBD` / `TODO` / `implement later` / `fill in details`
29   -- **`【人工填写:】`** — A 阶段标记。需要具体值时:先查 `.env.local` / `docs/07` / `docs/04` / `docs/09` / 现有代码并引用源;否则 `AskUserQuestion`
30   -- 涉及后端文件(`backend/` / `sql/` / `scripts/`)的任务——**硬护栏**
31   -- 未在任何 task 定义的组件 / hook / API client 函数
32   -
33   -## 执行步骤
34   -
35   -1. **收集输入**:
36   - - 当前 FE 的规格 `docs/superpowers/specs/<YYYY-MM-DD>-<fe_id>.md`(不存在则报错)
37   - - `docs/04-技术规范.md § 一前端架构`(路由 / 状态库 / 组件目录约定 / 测试栈)
38   - - `docs/09-项目目录结构.md § 前端目录结构`(文件落盘位置规范)
39   - - 相关代码指针(通过 `Grep` 在 `frontend/` 下定位现有前端文件)
40   -
41   -2. **范围检查**:spec 跨多页/多业务 → 提示拆分
42   -
43   -3. **文件结构推导**:
44   - - 组件 / 路由 / hook / API client 各放哪里(依 docs/09 § 前端目录结构)
45   - - 每个文件单一职责
46   - - 同 feature 的相关文件放一起
47   -
48   -4. **任务粒度推导**(参考下方"任务原则"):
49   - - 每个任务 = 一个 red-green-commit 单元
50   - - 4 个 step:写失败测试 → 实现最小代码 → 子会话验证 PASS → commit
51   - - 任务粒度 2-5 分钟
52   - - 每个任务必须含:`test_file::test_name` + `impl_file` + 完成判据 + "测试先行类型"标注
53   -
54   -5. **写 plan 到 `docs/superpowers/plans/<YYYY-MM-DD>-<fe_id>.md`**:
55   - - 按 `${CLAUDE_SKILL_DIR}/templates/fe-feature-plan-template.md` 渲染
56   - - 文件已存在 → 征求用户确认后覆盖
57   -
58   -6. **Plan 自审**(inline 修,无须用户等待):
59   - - 每个任务必须含 `test_file::test_name`、`impl_file`、完成标准
60   - - **每个任务的 `impl_file` 路径必须以 `frontend/` 开头**(或 `docs/09` 声明的前端根目录);命中 `backend/` / `sql/` / `scripts/` → 修正后重渲染
61   - - **占位符扫描**:`TBD` / `【人工填写:】` → 修
62   - - **Spec coverage**:spec 每节能指向至少一个 task 吗
63   - - **类型一致性**:组件 props 类型 / hook 签名跨 task 一致
64   -
65   -7. **输出 + 链 fe-feature-tdd**(**直接做这两件事,不要输出"回交父 skill / 交给 caller / 等下一步 / 准备好了请检查"之类的桥接叙述**——那些会被解读为 turn 结束信号):
66   - - 输出一行 `fe-feature-plan: <fe_id> → <path>`
67   - - **同一 turn 内立即** `Skill(fe-feature-tdd)`
68   -
69   -## 任务原则
70   -
71   -### Plan 文件头
72   -
73   -每个 plan 必须以以下头部开始:
74   -
75   -```markdown
76   -# [FE Feature Name] Implementation Plan
77   -
78   -> **Execution:** Parent skill `fe-feature-tdd` executes this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
79   -
80   -**Goal:** [一句话描述]
81   -
82   -**Architecture:** [2-3 句方法论]
83   -
84   -**Tech Stack:** [关键技术 / 库]
85   -
86   ----
87   -```
88   -
89   -### Task 结构
90   -
91   -每个 task 是 red-green-commit 单元:
92   -
93   -````markdown
94   -### Task N: [组件名]
95   -
96   -**Files:**
97   -- Create: `frontend/src/components/LoginForm.tsx`
98   -- Test: `frontend/src/components/LoginForm.test.tsx`
99   -- 测试先行类型: jsdom 组件测试
100   -
101   -**Props/API shape**(只写需要约束实现的签名):
102   -- `<LoginForm onSubmit={(username: string, password: string) => Promise<void>} loading={boolean} />`
103   -
104   -- [ ] **Step 1: 写失败测试**
105   - - 测试名: `LoginForm renders username and password fields`
106   - - 意图: 验证组件渲染 username / password input,submit button disabled when empty
107   - - 子会话确认 FAIL(组件不存在)
108   -
109   -- [ ] **Step 2: 实现最小代码**
110   - - 目标: 让 Step 1 测试通过;不多做
111   - - 涉及文件: `frontend/src/components/LoginForm.tsx`
112   -
113   -- [ ] **Step 3: 子会话验证 PASS**
114   -
115   -- [ ] **Step 4: Commit**
116   - - `git add <文件>`
117   - - `git commit -m "feat(fe): LoginForm 组件 FE-01"`
118   -````
119   -
120   -### 允许的代码块场景
121   -
122   -少数例外,需要写死而非让 TDD 自由发挥:
123   -
124   -- **路由配置**:`routes.ts` 中 path 注册(路径是契约级)
125   -- **API client 契约**:fetch 包装函数签名 + headers + 错误码 mapping
126   -- **Design Tokens 名称**:`var(--color-primary)` 列表(跨组件复用)
127   -- **测试断言形状**(可选)
128   -
129   -除此之外一律散文 + 签名描述,**不贴完整组件源码**。
130   -
131   -### 记住
132   -
133   -- Exact file paths always(必须以 `frontend/` 开头)
134   -- 测试先行类型必须明确(jsdom / Playwright)
135   -- 组件 props / hook 签名 / API client 函数签名 — **必须写死**
136   -- Internal implementation code — **不写**;留给 TDD 阶段
137   -
138   -## 参考
139   -
140   -- `${CLAUDE_SKILL_DIR}/templates/fe-feature-plan-template.md`
141   -- 上游:`fe-feature-brainstorm`
142   -- 下游:`fe-feature-tdd`
skills/coding/fe-feature-plan/templates/fe-feature-plan-template.md deleted
1   -# 前端功能计划 — {{fe_id}} {{name}}
2   -
3   -> 规格:docs/superpowers/specs/{{date}}-{{fe_id}}.md
4   -> 关联原型:{{associated_prototypes}}
5   -> 关联 REQ:{{associated_reqs}}
6   -> 日期:{{date}}
7   -
8   -## 一、依赖与前置条件
9   -
10   -- 前置 FE:{{prerequisite_fes}}
11   -- 共享组件:{{shared_components}}
12   -- 路由配置文件:{{router_file}}
13   -
14   -## 二、任务清单
15   -
16   -每行一个任务,2-5 分钟可完成。`test_file::test_name` 先行写失败测试,`impl_file` 写最小实现使其通过。
17   -
18   -| # | 任务 | 测试先行类型 | test_file::test_name | impl_file | 完成判据 |
19   -|---|------|-------------|---------------------|-----------|---------|
20   -{{task_rows}}
21   -
22   -> **路径约束**:所有 `impl_file` 必须以 `frontend/`(或 docs/09 声明的前端根目录)开头。
23   -> **测试先行类型**:`jsdom`(组件单测,vitest/jest)或 `e2e`(Playwright)。
24   -
25   -## 三、组件 props 契约
26   -
27   -| 组件 | props | 类型 | 必填 | 说明 |
28   -|------|-------|------|------|------|
29   -{{props_rows}}
30   -
31   -## 四、状态管理
32   -
33   -<!-- store hook 名 / 持有的 state 字段 / 暴露的 actions。如本 FE 不引入新 store,写"复用 <既有 store>"。 -->
34   -
35   -{{state_management}}
36   -
37   -## 五、API client 包装
38   -
39   -| 函数名 | HTTP 方法 | 路径 | 入参 | 返回 |
40   -|--------|----------|------|------|------|
41   -{{api_client_rows}}
42   -
43   -> 函数实现必须基于项目统一 API client(见 docs/04 § 一),不允许直接 `fetch` / `axios` 拼路径。
44   -
45   -## 六、风险与回退
46   -
47   -{{risks}}
skills/coding/fe-feature-review/SKILL.md deleted
1   ----
2   -name: fe-feature-review
3   -description: 前端功能循环第 5 步。AI 自审 FE 的 diff(专用前端 reviewer),approve 则回 frontend-start;request-changes 则自修复 + 重 verify,循环上限 5 轮。
4   -user-invocable: false
5   -allowed-tools: Read Write Edit Skill Agent Bash(git add *) Bash(git commit *)
6   ----
7   -
8   -**所有输出必须使用中文。**
9   -
10   -# fe-feature-review
11   -
12   -委托 `fe-code-reviewer` agent(前端专用 reviewer,不复用 superpower-code-reviewer)对当前 FE 引入的代码改动做 AI 自审。`approve` 回 frontend-start 推进下一 FE;`request-changes` 自修复 must-fix 并重新 verify,最多 5 轮。
13   -
14   -## 执行步骤
15   -
16   -1. 派发 `Agent(subagent_type=fe-code-reviewer)`,把本 FE 引入的代码 diff、规格(`docs/superpowers/specs/<date>-<fe_id>.md`)、本 FE 关联的所有 prototype 文件(spec 顶部的 `关联原型` 列表)作为输入。
17   -
18   -2. 按 `${CLAUDE_SKILL_DIR}/templates/fe-feature-review-template.md` 渲染审阅报告,写入 `docs/superpowers/reviews/<YYYY-MM-DD>-<fe_id>.md`。`verdict` 取 `approve` 或 `request-changes`。
19   -
20   -3. 按 `verdict` 分派:
21   -
22   - **approve**
23   - - `Edit docs/08-模块任务管理.md § 三`,把本 FE 下 `- [ ] <fe_id> ...` 改为 `- [x] <fe_id> ...`(仅 FE 级可视化;前端阶段完成仍以 `整体里程碑:` 字段 + 本地 `git tag -l` 为准)
24   - - 输出 `fe-feature-review: <fe_id> round <N> 通过`,调用 `Skill(frontend-start)` 推进下一 FE 或进入 test-gate(phase=frontend)
25   -
26   - **request-changes(round < 5)**
27   - - 逐项编辑 `must_fix[]` 指向的代码文件
28   - - 按 `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md` 格式 commit:`fix(<scope>): 修复 review round <N> must-fix REQ_ID: <fe_id>`
29   - - 调用 `Skill(fe-feature-verify)` 重新验证;verify 通过后会再次链回本 skill,round `<N+1>` 重审
30   -
31   - **request-changes(round == 5)**
32   - - 停止并打印摘要,升级给用户手工介入;不再自动修复,不回调 frontend-start
33   -
34   -## 参考
35   -
36   -- `${CLAUDE_SKILL_DIR}/templates/fe-feature-review-template.md`
37   -- `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md`
38   -- 委托:`fe-code-reviewer` agent(本插件 `agents/fe-code-reviewer.md`,前端专用,硬编码 7 维 review checklist)
39   -- 上游:`fe-feature-verify`
40   -- 下游:`frontend-start`(approve)/ `fe-feature-verify`(request-changes 时重验)
skills/coding/fe-feature-review/templates/fe-feature-review-template.md deleted
1   ----
2   -fe_id: {{fe_id}}
3   -date: {{date}}
4   -round: {{round}}
5   -reviewer: fe-code-reviewer
6   ----
7   -
8   -# Review: {{fe_id}} — round {{round}}
9   -
10   -## 结论
11   -{{verdict}} (approve / request-changes)
12   -
13   -## Must-fix
14   -{{#each must_fix}}
15   -- [{{severity}}] {{file}}:{{line}} — {{issue}}(建议:{{suggestion}})
16   -{{/each}}
17   -
18   -## Nice-to-have
19   -{{#each nice_to_have}}
20   -- {{file}}:{{line}} — {{suggestion}}
21   -{{/each}}
22   -
23   -## 维度核查(fe-code-reviewer 7 维)
24   -
25   -| # | 维度 | 状态 | 备注 |
26   -|---|------|------|------|
27   -| 1 | prototype 一致性 | {{dim_prototype}} | {{dim_prototype_note}} |
28   -| 2 | Design Tokens | {{dim_tokens}} | {{dim_tokens_note}} |
29   -| 3 | 无障碍 | {{dim_a11y}} | {{dim_a11y_note}} |
30   -| 4 | 响应式 | {{dim_responsive}} | {{dim_responsive_note}} |
31   -| 5 | 业务校验前端复刻 | {{dim_validation}} | {{dim_validation_note}} |
32   -| 6 | API 调用一致性 | {{dim_api}} | {{dim_api_note}} |
33   -| 7 | 状态机覆盖 | {{dim_state}} | {{dim_state_note}} |
34   -
35   -## 反例 / 测试覆盖缺口
36   -
37   -{{gaps}}
skills/coding/fe-feature-tdd/SKILL.md deleted
1   ----
2   -name: fe-feature-tdd
3   -description: 前端功能循环第 3 步。按 plan 逐任务做 TDD(失败测试 → 实现 → 通过 → commit),组件测试用 jsdom,E2E 派子会话跑 Playwright。
4   -user-invocable: false
5   -allowed-tools: Read Write Edit Agent Skill Bash(git add *) Bash(git commit *)
6   ----
7   -
8   -**所有输出必须使用中文。**
9   -
10   -# fe-feature-tdd
11   -
12   -按 plan 文件逐任务做 TDD:写失败测试 → 写最小实现 → 确认通过 → commit。**所有测试运行强制派发到 Agent 子会话**,主会话只接收 JSON 结果。
13   -
14   -## 路径护栏(前端阶段)
15   -
16   -- 任务的 `impl_file` 路径若**不以** `frontend/`(或项目实际前端根目录,从 `docs/09-项目目录结构.md § 前端目录结构` 取)开头 → 硬停并打印:`fe-feature-tdd 不允许写非前端文件:<impl_file>。前端阶段任务的 impl_file 必须落在前端目录下。`
17   -- 命中 `backend/` / `sql/` / `scripts/` → 同上硬停
18   -- 不允许在主会话直接 `pnpm playwright` / `pnpm test` / `pnpm e2e`,必须派发子会话
19   -
20   -## 执行步骤
21   -
22   -1. 加载计划文件 `docs/superpowers/plans/<YYYY-MM-DD>-<fe_id>.md`。
23   -
24   -2. 从 `docs/04-技术规范.md § 零 frontend` 取测试栈:
25   - - `frontend.unit_test_runner`:vitest / jest(默认 vitest)
26   - - `frontend.e2e_runner`:playwright(默认 playwright)
27   - - `frontend.test_command` / `frontend.e2e_command`:执行命令(缺失则用 `pnpm test:ci` / `pnpm e2e:ci`)
28   -
29   -3. 按顺序处理每个任务:
30   -
31   - a. 在 `test_file::test_name` 处写**失败**测试:
32   - - `测试先行类型 = jsdom`:在 jsdom 环境下用 vitest/jest 写组件单测(render + 断言 DOM / 交互后状态变化)
33   - - `测试先行类型 = e2e`:在 `frontend/e2e/` 写 Playwright 测试(headless)
34   -
35   - b. 派发 Agent 子会话(general-purpose)运行该测试,子会话只返回 `{command, exit_code, failing_assertion}` JSON,确认失败。
36   -
37   - c. 在 `impl_file` 处写**最小**实现使测试通过。**严格遵守**:
38   - - 路径必须以 `frontend/`(或 docs/09 声明的前端根)开头(违反 → 硬停,见护栏)
39   - - 色值用 `var(--color-*)`(来自 spec § 六),不硬编码 hex
40   - - 业务校验按 spec § 五 在 form-level 复刻
41   -
42   - d. 再次派发子会话确认通过。
43   -
44   - e. 同一测试 >10 次修复仍失败 → 调用 `Skill(interrupt-check)`(中断 #1:测试反复失败)。
45   -
46   - f. 按 `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md` 格式 commit:
47   - - `scope` = 任务模块(如组件名 `dashboard` / `user-form`)
48   - - `subject` ≤ 50 字符
49   - - 必含 trailer `REQ_ID: <fe_id>`(如 `REQ_ID: FE-01`)
50   -
51   -4. 全部任务完成 → 调用 `Skill(fe-feature-verify)`。
52   -
53   -## 护栏
54   -
55   -- **绝不**在主会话直接跑 `pnpm test` / `pnpm e2e` / `pnpm playwright`,必须通过子会话
56   -- **绝不**在 `impl_file` 中写非 `frontend/` 路径(路径护栏会硬停)
57   -- 每次 commit 必须含 `REQ_ID: FE-NN` trailer;不混合无关改动到同一 commit
58   -- 不硬编码颜色 hex;token 引用必须对齐 spec § 六
59   -
60   -## 参考
61   -
62   -- `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md`
63   -- 守门:`interrupt-check`(仅在步骤 3.e 触发,条件 1)
64   -- 上游:`fe-feature-plan`
65   -- 下游:`fe-feature-verify`
skills/coding/fe-feature-tdd/templates/commit-message-template.md deleted
1   -{{type}}({{scope}}): {{subject}} {{req_id}}
skills/coding/fe-feature-verify/SKILL.md deleted
1   ----
2   -name: fe-feature-verify
3   -description: 前端功能循环第 4 步。把 FE 的组件测试 + E2E 派发到子会话执行,按模板渲染证据。无证据不声称完成。
4   -user-invocable: false
5   -allowed-tools: Skill Read Agent
6   ----
7   -
8   -**所有输出必须使用中文。**
9   -
10   -# fe-feature-verify
11   -
12   -把当前 FE 的测试派发到 Agent 子会话执行,按模板把结构化结果渲染成证据。**主会话从不直接跑测试**,也不自由编写证据。
13   -
14   -## 执行步骤
15   -
16   -1. 从 plan 文件确定本 FE 的测试目标:
17   - - 单测目标:plan § 二中所有 `测试先行类型 = jsdom` 的 test_file 列表 → 拼成 vitest/jest 过滤模式
18   - - E2E 目标:所有 `测试先行类型 = e2e` 的 test_file 列表 → 拼成 Playwright spec 过滤模式
19   -
20   -2. 派发 Agent 子会话(general-purpose)依次运行两个目标,子会话只返回结构化 JSON(不输出描述文字):
21   -
22   - ```json
23   - {
24   - "unit": {
25   - "command": "<vitest/jest 命令>",
26   - "exit_code": <int>,
27   - "passed": <int>,
28   - "failed": <int>,
29   - "failed_list": ["<test>", ...],
30   - "stdout_excerpt": "<最后 30 行或最相关的失败片段>"
31   - },
32   - "e2e": {
33   - "command": "<playwright 命令>",
34   - "exit_code": <int>,
35   - "passed": <int>,
36   - "failed": <int>,
37   - "failed_list": ["<spec>", ...],
38   - "stdout_excerpt": "<最后 30 行或最相关的失败片段>"
39   - }
40   - }
41   - ```
42   -
43   - 命令从 `docs/04-技术规范.md § 零 frontend.test_command` / `frontend.e2e_command` 取,缺失则用默认 `pnpm test:ci` / `pnpm e2e:ci`。
44   -
45   -3. 按 `${CLAUDE_SKILL_DIR}/templates/fe-feature-verify-evidence-template.md` 渲染证据并打印到会话。
46   -
47   -4. **任一目标 `exit_code != 0` 或 `failed > 0`** → 停止,不进入 review。
48   -
49   -5. 全部通过 → 调用 `Skill(fe-feature-review)`。
50   -
51   -## 护栏
52   -
53   -- **绝不**在主会话直接跑测试,必须通过子会话
54   -- **绝不**自由编写证据正文,必须从模板渲染
55   -- 不要把原始 stdout 全文塞进主会话(`stdout_excerpt` ≤ 30 行)
56   -
57   -## 参考
58   -
59   -- `${CLAUDE_SKILL_DIR}/templates/fe-feature-verify-evidence-template.md`
60   -- 上游:`fe-feature-tdd`
61   -- 下游:`fe-feature-review`
skills/coding/fe-feature-verify/templates/fe-feature-verify-evidence-template.md deleted
1   -## Verify evidence — {{fe_id}}
2   -
3   -### 单元测试(jsdom)
4   -
5   -- 命令: `{{unit.command}}`
6   -- 子会话: {{unit.subagent_id}}
7   -- 退出码: {{unit.exit_code}}
8   -- 通过用例数: {{unit.passed}}
9   -- 失败用例数: {{unit.failed}}
10   -- 失败列表: {{unit.failed_list}}
11   -
12   -关键 stdout 片段 (≤30 行):
13   -
14   -```
15   -{{unit.stdout_excerpt}}
16   -```
17   -
18   -### E2E 测试(Playwright)
19   -
20   -- 命令: `{{e2e.command}}`
21   -- 子会话: {{e2e.subagent_id}}
22   -- 退出码: {{e2e.exit_code}}
23   -- 通过用例数: {{e2e.passed}}
24   -- 失败用例数: {{e2e.failed}}
25   -- 失败列表: {{e2e.failed_list}}
26   -
27   -关键 stdout 片段 (≤30 行):
28   -
29   -```
30   -{{e2e.stdout_excerpt}}
31   -```
32   -
33   -结论: {{conclusion}} (pass = 两段都 pass / fail = 任一 fail)
skills/coding/feature-brainstorm/SKILL.md deleted
1   ----
2   -name: feature-brainstorm
3   -description: 功能循环第 1 步。针对单个 REQ-XXX-NNN 做交互式 Q&A + 写规格,产出到 docs/superpowers/specs/,链入 feature-plan。
4   -user-invocable: false
5   -allowed-tools: Read Write Skill AskUserQuestion Bash(mysql *)
6   ----
7   -
8   -**所有输出必须使用中文。**
9   -
10   -# feature-brainstorm
11   -
12   -## 阶段范围(后端)
13   -
14   -本 skill 服务于**后端阶段**。产出范围限定为 controller / service / repository / DTO / 校验 / SQL migration / REST 契约。读 docs/01 REQ 卡片时**忽略 UI 描述**(输入控件类型、按钮位置、列表布局等),但**校验规则、业务规则**仍要落到后端 DTO + service。UI 实现统一推迟到前端阶段(fe-feature-*)。
15   -
16   -## 占位符规则
17   -
18   -本 skill 写的 spec 是 CC 内部推理产物,不是用户审阅文档。**不允许** `【人工填写:...】` 占位符——A 阶段 `docs/01~10` / `CLAUDE.md` / `.env.local` 才用那个标记。需要具体值时:
19   -
20   -1. **先查** `.env.local` / `docs/07-环境配置.md` / `CLAUDE.md` / 现有代码。值已落地某处 → 在 spec 中引用源(例 "JWT_SECRET 从 `.env.local` 读取,`application.yml` 用 `${JWT_SECRET}` 注入")
21   -2. **再问**:查不到 → `AskUserQuestion` 问用户,记录答案到 spec
22   -3. **绝不**留 `【人工填写:】` 占位符;若 1 + 2 都解决不了,spec 必须写出具体阻塞点(不是泛化的人工填写标记),Q&A 继续直到解决
23   -
24   -## 执行步骤
25   -
26   -1. **收集上下文**:确定本次 REQ-XXX-NNN(由 module-start 派发时指定),读取:
27   - - REQ 卡片 `docs/01-需求清单/<module>/<req_id>.md`
28   - - 涉及的数据表定义(取自 docs/03 或实时 mysql 查询)
29   -
30   -2. **交互式 Q&A**(参考下方"Q&A 原则"):
31   - - **先评估 scope**:单 spec 容纳得下吗?跨多个独立子系统(如"含登录 + 文件存储 + 计费 + 分析")→ 先提示分解,每个子项目独立 brainstorm
32   - - **一次一问** `AskUserQuestion`,仅对真模糊点;多选题优先
33   - - 决策完成后挑一种 approach;trade-off 直接内嵌 spec,**不设确认 gate**
34   -
35   -3. **写 spec 到 `docs/superpowers/specs/<YYYY-MM-DD>-<REQ-id>.md`**:
36   - - 按 `${CLAUDE_SKILL_DIR}/templates/feature-spec-template.md` 渲染
37   - - 覆盖:goal / 输入输出 / 业务规则 / 约束 / schema / API 引用 / acceptance criteria
38   - - 文件已存在 → 征求用户确认后覆盖
39   -
40   -4. **Spec 自审**(inline 修,无须用户等待):
41   - - **占位符扫描**:`TBD` / `TODO` / `【人工填写:】` / 含糊段 → 修(按"占位符规则"流程解决)
42   - - **内部一致性**:节与节是否矛盾?架构是否匹配功能描述?
43   - - **范围检查**:单 plan 能消化吗?还是需要分解
44   - - **歧义检查**:任何 requirement 两种解读?挑一个写明
45   -
46   - fix inline,无须 re-review。
47   -
48   -5. **输出 + 链 feature-plan**(**直接做这两件事,不要输出"回交父 skill / 交给 caller / 等下一步 / 准备好了请检查"之类的桥接叙述**——那些会被解读为 turn 结束信号):
49   - - 输出一行 `feature-brainstorm: <REQ> → <path>`
50   - - **同一 turn 内立即** `Skill(feature-plan)`
51   -
52   -## Q&A 原则
53   -
54   -- **一次一问** — 不堆问题
55   -- **多选题优先** — 答更快
56   -- **仅对真模糊点问** — 不造确认问题
57   -- **YAGNI** — 删 spec 中不必要的功能
58   -- **渐进理解** — 不明白就问
59   -- **无审批 gate** — 写 spec 即 commit;分歧落地为具体 Q&A 项,不靠"等用户确认"
60   -
61   -## 参考
62   -
63   -- `${CLAUDE_SKILL_DIR}/templates/feature-spec-template.md`
64   -- 上游:`module-start`
65   -- 下游:`feature-plan`
skills/coding/feature-brainstorm/templates/feature-spec-template.md deleted
1   ----
2   -req_id: {{req_id}}
3   -date: {{date}}
4   -module: {{module}}
5   ----
6   -
7   -# Spec: {{req_id}} — {{title}}
8   -
9   -## 目标
10   -{{goal}}
11   -
12   -## 输入 / 触发
13   -{{input}}
14   -
15   -## 输出 / 结果
16   -{{output}}
17   -
18   -## 业务规则
19   -{{rules}}
20   -
21   -## 边界与约束
22   -{{constraints}}
23   -
24   -## 依赖的 schema 表 / 字段
25   -{{schema_refs}}
26   -
27   -## 依赖的接口
28   -{{api_refs}}
29   -
30   -## 验收标准
31   -{{acceptance}}
skills/coding/feature-plan/SKILL.md deleted
1   ----
2   -name: feature-plan
3   -description: 功能循环第 2 步。将 spec 转任务级 TDD 计划(每任务 2-5 分钟),产出到 docs/superpowers/plans/,链入 feature-tdd。
4   -user-invocable: false
5   -allowed-tools: Read Write Grep Skill AskUserQuestion
6   ----
7   -
8   -**所有输出必须使用中文。**
9   -
10   -# feature-plan
11   -
12   -## 阶段范围(后端)
13   -
14   -本 skill 服务于**后端阶段**。任务粒度限定为后端模块文件:controller / service / repository / DTO / 校验 / SQL migration。**禁止**生成 `frontend/` 路径下的实现任务——UI 实现统一推迟到前端阶段(fe-feature-*)。
15   -
16   -## 计划写作原则
17   -
18   -- Plan 告诉 TDD 执行者**做什么**,不是**怎么写代码**——执行者是 `feature-tdd`(同一模型,全上下文),不是机械复制粘贴员
19   -- Plan 锁定**文件边界 + 测试意图 + API 形状 + 完成判据**;代码由 TDD 红绿循环产出
20   -- **禁止 dump 整个文件内容**(pom.xml / entity 类 / config 文件)到 plan——plan 和代码会成为两个 source of truth 并漂移;2000+ 行 plan 浪费上下文
21   -- DRY、YAGNI、TDD、frequent commits
22   -
23   -## 占位符规则
24   -
25   -每个 step 必须写实际内容。以下属于 **plan failures**,绝不出现:
26   -
27   -- `TBD` / `TODO` / `implement later` / `fill in details`
28   -- **`【人工填写:】`** — 这是 A 阶段标记(`docs/01~10` / `CLAUDE.md` / `.env.local`),B 阶段 plan **绝不能出现**。需要具体值时:
29   - 1. 先查 `.env.local` / `docs/07-环境配置.md` / `CLAUDE.md` / 现有代码并在 plan 中引用源
30   - 2. 否则 `AskUserQuestion` 问用户并记录答案
31   -- "Add appropriate error handling" / "add validation"(要具体到哪些错误码 / 哪些字段)
32   -- "Similar to Task N"(相似任务各自写清楚测试意图 + 完成判据,不互相链接)
33   -- 未在任何 task 定义的 types / functions / methods(类/方法首次出现的 task 必须给出 API 签名)
34   -
35   -> 散文级"做什么"是 OK 的——执行器(`feature-tdd`)会在 TDD 循环里决定"怎么写"。plan 的义务是**约束范围**,不是**替 TDD 写代码**。
36   -
37   -## 执行步骤
38   -
39   -1. **收集输入**:
40   - - spec 文件 `docs/superpowers/specs/<YYYY-MM-DD>-<REQ-id>.md`(不存在则报错)
41   - - 相关代码指针(通过 `Grep` 在现有代码定位待修改文件)
42   - - `docs/04-技术规范.md` 与 `docs/09-项目目录结构.md`(编码规范 + 目录规范)
43   -
44   -2. **范围检查**:spec 跨多个独立子系统 → 提示拆分,每个 plan 应能独立产出可工作、可测试的软件
45   -
46   -3. **文件结构推导**:
47   - - 哪些文件 create / modify
48   - - 每个文件单一职责,well-defined interface
49   - - 一起变化的文件放一起;不按技术层切分
50   -
51   -4. **任务粒度推导**(参考下方"任务原则"):
52   - - 每个任务 = 一个 red-green-commit 单元
53   - - 4 个 step:写失败测试 → 实现最小代码 → 子会话验证 PASS → commit
54   - - 任务粒度 2-5 分钟
55   -
56   -5. **写 plan 到 `docs/superpowers/plans/<YYYY-MM-DD>-<REQ-id>.md`**:
57   - - 按 `${CLAUDE_SKILL_DIR}/templates/feature-plan-template.md` 渲染
58   - - 文件已存在 → 征求用户确认后覆盖
59   -
60   -6. **Plan 自审**(inline 修,无须用户等待):
61   - - **占位符扫描**:按"占位符规则"清单逐项 grep;命中即修
62   - - **Spec coverage**:skim spec 每节,能指向至少一个 task 吗?list gaps 并补 task
63   - - **类型一致性**:tasks 之间签名 / 方法名 / 属性名 / 错误码是否一致(Task 3 的 `clearLayers()` 和 Task 7 的 `clearFullLayers()` 是 bug)
64   -
65   -7. **输出 + 链 feature-tdd**(**直接做这两件事,不要输出"回交父 skill / 交给 caller / 等下一步 / 准备好了请检查"之类的桥接叙述**——那些会被解读为 turn 结束信号):
66   - - 输出一行 `feature-plan: <REQ> → <path>`
67   - - **同一 turn 内立即** `Skill(feature-tdd)`
68   -
69   -## 任务原则
70   -
71   -### Plan 文件头
72   -
73   -每个 plan 必须以以下头部开始:
74   -
75   -```markdown
76   -# [Feature Name] Implementation Plan
77   -
78   -> **Execution:** Parent skill `feature-tdd` executes this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
79   -
80   -**Goal:** [一句话描述]
81   -
82   -**Architecture:** [2-3 句方法论]
83   -
84   -**Tech Stack:** [关键技术 / 库]
85   -
86   ----
87   -```
88   -
89   -### Task 结构
90   -
91   -每个 task 是 red-green-commit 单元。捕获意图和边界,代码留给 TDD:
92   -
93   -````markdown
94   -### Task N: [组件名]
95   -
96   -**Files:**
97   -- Create: `exact/path/to/File.java`
98   -- Modify: `exact/path/to/Existing.java:123-145`
99   -- Test: `tests/exact/path/to/FileTest.java`
100   -
101   -**API shape**(只写需要约束实现的签名;内部实现留给 TDD):
102   -- `LoginService#login(LoginRequest req) : LoginResponse`
103   -- `throws AccountLockedException when iLoginFailCount ≥ 5 within tLockUntil window`
104   -
105   -- [ ] **Step 1: 写失败测试**
106   - - 测试名: `LoginServiceTest#loginWithBadPassword_incrementsFailCount_returns40101`
107   - - 意图: 错误密码 → `iLoginFailCount += 1`;第 5 次 → 设置 `tLockUntil = now + 15min`;返回码 40101
108   - - 子会话确认 FAIL(函数/类不存在)
109   -
110   -- [ ] **Step 2: 实现最小代码**
111   - - 目标: 让 Step 1 测试通过;不多做
112   - - 涉及文件: `LoginService.java`, `SftLoginInfoMapper.java`
113   -
114   -- [ ] **Step 3: 子会话验证 PASS**
115   -
116   -- [ ] **Step 4: Commit**
117   - - `git add <文件>`
118   - - `git commit -m "feat(sys): 登录失败计数 + 锁定 REQ-SYS-001"`
119   -````
120   -
121   -### 允许的代码块场景
122   -
123   -少数例外,需要写死而非让 TDD 自由发挥:
124   -
125   -- **DDL / migration 文件**:`V_n__*.sql` 的 ALTER/CREATE 语句——schema 是事实源、不是 TDD 红绿产物
126   -- **合同级常量**:API 错误码表、JWT claim 名、Redis key 模式——跨模块消费,必须在 plan 锁定
127   -- **测试断言形状**(可选):一句话说不清"测什么"时,给个 3-5 行断言 sketch 是 OK 的
128   -
129   -除此之外一律散文 + 签名描述,**不贴完整文件**。
130   -
131   -### 记住
132   -
133   -- Exact file paths always
134   -- Exact commands with expected output(测试运行 + git 操作)
135   -- API signatures / class names / error codes / contract values — **必须写死**
136   -- Internal implementation code — **不写**;留给 TDD 阶段
137   -- DRY、YAGNI、TDD、frequent commits
138   -
139   -## 参考
140   -
141   -- `${CLAUDE_SKILL_DIR}/templates/feature-plan-template.md`
142   -- 上游:`feature-brainstorm`
143   -- 下游:`feature-tdd`
skills/coding/feature-plan/templates/feature-plan-template.md deleted
1   ----
2   -req_id: {{req_id}}
3   -date: {{date}}
4   -spec_ref: docs/superpowers/specs/{{date}}-{{req_id}}.md
5   ----
6   -
7   -# Plan: {{req_id}}
8   -
9   -## Schema 改动
10   -{{schema_change_decision}} <!-- "无" 或 "需要 migration:V<n>__<snake_case>.sql,作用:<一行描述>" -->
11   -
12   -## 文件变更清单
13   -{{#each files}}
14   -- `{{path}}` — {{action}}({{rationale}})
15   -{{/each}}
16   -
17   -## 任务步骤
18   -{{#each tasks}}
19   -### Task {{index}}: {{title}}
20   -- 失败测试: `{{test_file}}::{{test_name}}` — {{test_intent}}
21   -- 实现路径: `{{impl_file}}`
22   -- 完成判据: {{done_when}}
23   -{{/each}}
24   -
25   -## 提交计划
26   -{{#each commits}}
27   -- `{{message}}`(覆盖 Task {{task_index}})
28   -{{/each}}
skills/coding/feature-review/SKILL.md
1 1 ---
2 2 name: feature-review
3   -description: 功能循环第 5 步。AI 自审 REQ 的 diff,approve 则回调 module-start;request-changes 则自修复 + 重 verify,循环上限 5 轮。
  3 +description: 统一功能循环第 3 步(后端 REQ / 前端 FE 共用,由 phase 参数区分)。先派子会话跑验证测试(verify 阶段),通过后再派相应 reviewer agent 做 AI 自审(review 阶段),approve 回 phase-driver;request-changes 自修复 + 重验,最多 5 轮。
4 4 user-invocable: false
5 5 allowed-tools: Read Write Edit Skill Agent Bash(git add *) Bash(git commit *)
6 6 ---
... ... @@ -9,29 +9,128 @@ allowed-tools: Read Write Edit Skill Agent Bash(git add *) Bash(git commit *)
9 9  
10 10 # feature-review
11 11  
12   -委托 `superpower-code-reviewer` agent 对当前 REQ 引入的代码改动做 AI 自审,渲染审阅报告。`approve` 回模块主循环;`request-changes` 则自修复 must-fix 并重新 verify,最多 5 轮。
  12 +统一功能循环第 3 步(verify + review 合并)。先派子会话运行功能测试(verify 阶段),通过后再委托对应 reviewer agent 做 AI 自审(review 阶段),渲染合并报告。`approve` 回 `phase-driver` 推进;`request-changes` 自修复 must-fix 并从 verify 阶段重新开始,最多 5 轮。
  13 +
  14 +**入参(由 feature-tdd 传入):**
  15 +- `phase`:`backend` | `frontend`
  16 +- `id`:`REQ-XXX-NNN`(backend)或 `FE-NN`(frontend)
  17 +
  18 +内部维护 `round` 计数器(首次 = 1)。
  19 +
  20 +---
  21 +
  22 +## 阶段差异
  23 +
  24 +| 项目 | phase=backend | phase=frontend |
  25 +|------|-------------|----------------|
  26 +| 测试目标 | `./scripts/test.sh`(plan 确认)| vitest/jest 单测 + Playwright E2E(从 `docs/04 §零 frontend.test_command` / `frontend.e2e_command` 取;缺失用 `pnpm test:ci` / `pnpm e2e:ci`)|
  27 +| 测试 JSON 结构 | 单层 JSON(见"验证阶段")| 两层 JSON:`unit` + `e2e`(见"验证阶段")|
  28 +| Reviewer agent | `superpower-code-reviewer` | `fe-code-reviewer` |
  29 +| approve 写 docs/08 | §二 该 REQ 行 `[ ]`→`[x]` | §三 该 FE 行 `[ ]`→`[x]` |
  30 +| approve 输出 | `feature-review: <REQ> round <N> 通过` | `feature-review: <FE-NN> round <N> 通过` |
  31 +
  32 +---
13 33  
14 34 ## 执行步骤
15 35  
16   -1. 派发 `Agent(subagent_type=superpower-code-reviewer)`,把本 REQ 引入的代码 diff 与规格作为输入。
17   -2. 按 `${CLAUDE_SKILL_DIR}/templates/feature-review-template.md` 渲染审阅报告,写入 `docs/superpowers/reviews/<YYYY-MM-DD>-<REQ-id>.md`。`verdict` 取 `approve` 或 `request-changes`。
18   -3. 按 `verdict` 分派:
  36 +### 阶段一:验证(Verify)
  37 +
  38 +1. **确定测试目标**:
  39 + - `phase=backend`:从 plan 文件或项目标准命令确定(如 Maven profile / `scripts/test.sh` path)
  40 + - `phase=frontend`:从 `docs/04-技术规范.md § 零 frontend` 取测试栈和测试命令;按 plan 中 task 的"测试先行类型"拆分单测目标(jsdom)和 E2E 目标(playwright)
  41 +
  42 +2. **派发 Agent 子会话(general-purpose)** 运行测试目标,子会话只返回结构化 JSON(不输出描述文字):
  43 +
  44 + `phase=backend`:
  45 + ```json
  46 + {
  47 + "command": "<cmd>",
  48 + "exit_code": <int>,
  49 + "passed": <int>,
  50 + "failed": <int>,
  51 + "failed_list": ["<test>", ...],
  52 + "stdout_excerpt": "<最后 30 行或最相关的失败片段>"
  53 + }
  54 + ```
  55 +
  56 + `phase=frontend`:
  57 + ```json
  58 + {
  59 + "unit": {
  60 + "command": "<vitest/jest 命令>",
  61 + "exit_code": <int>,
  62 + "passed": <int>,
  63 + "failed": <int>,
  64 + "failed_list": ["<test>", ...],
  65 + "stdout_excerpt": "<最后 30 行>"
  66 + },
  67 + "e2e": {
  68 + "command": "<playwright 命令>",
  69 + "exit_code": <int>,
  70 + "passed": <int>,
  71 + "failed": <int>,
  72 + "failed_list": ["<spec>", ...],
  73 + "stdout_excerpt": "<最后 30 行>"
  74 + }
  75 + }
  76 + ```
  77 +
  78 +3. 渲染 `## 验证证据` 节(填入 `${CLAUDE_SKILL_DIR}/templates/feature-review-template.md` 的 verify 部分)。
  79 +
  80 +4. **`exit_code != 0` 或 `failed > 0`**(任一目标失败)→ **停止,不进入 review 阶段**。等待下轮或用户介入。
  81 +
  82 +5. 全部通过 → 进入 review 阶段。
  83 +
  84 +---
  85 +
  86 +### 阶段二:审阅(Review)
  87 +
  88 +6. **派发 reviewer agent**(把本 id 引入的代码 diff 与规格作为输入):
  89 + - `phase=backend` → `Agent(subagent_type=superpower-code-reviewer)`
  90 + - `phase=frontend` → `Agent(subagent_type=fe-code-reviewer)`(同时提供规格文件 + 关联 prototype 文件列表,见 spec 顶部 `关联原型`)
  91 +
  92 +7. 渲染 `## 自审结论` 节(填入 `${CLAUDE_SKILL_DIR}/templates/feature-review-template.md` 的 review 部分),写入合并报告 `docs/superpowers/reviews/<YYYY-MM-DD>-<id>.md`。`verdict` 取 `approve` 或 `request-changes`。
  93 +
  94 +---
  95 +
  96 +### 阶段三:按 verdict 分派
  97 +
  98 +**approve**
19 99  
20   - **approve**
21   - - `Edit docs/08-模块任务管理.md § 二`,把本模块下 `- [ ] <REQ-id> ...` 改为 `- [x] <REQ-id> ...`(仅功能级可视化;模块完成仍以 `里程碑:` 字段 + 本地 `git tag -l` 为准,不依赖此勾选)
22   - - 输出 `feature-review: <REQ> round <N> 通过`,调用 `Skill(module-start)`
  100 +- `Edit docs/08-模块任务管理.md`:
  101 + - `phase=backend`:在 §二 找 `- [ ] <REQ-id> ...` 改为 `- [x] <REQ-id> ...`
  102 + - `phase=frontend`:在 §三 找 `- [ ] <fe_id> ...` 改为 `- [x] <fe_id> ...`
  103 + - (仅功能级可视化;模块 / 阶段完成仍以 `里程碑:` 字段 + 本地 `git tag -l` 为准,不依赖此勾选)
  104 +- 输出状态行(见上方阶段差异表),调用 `Skill(phase-driver)` 传入 `{ phase }`
23 105  
24   - **request-changes(round < 5)**
25   - - 逐项编辑 `must_fix[]` 指向的代码文件
26   - - 按 `feature-tdd/templates/commit-message-template.md` 格式 commit:`fix(<module_id>): 修复 review round <N> must-fix <REQ-id>`
27   - - 调用 `Skill(feature-verify)` 重新验证;verify 通过后会再次链回本 skill,round `<N+1>` 重审
  106 +**request-changes(round < 5)**
28 107  
29   - **request-changes(round == 5)**
30   - - 停止并打印摘要,升级给用户手工介入;不再自动修复,不回调 module-start
  108 +- 逐项编辑 `must_fix[]` 指向的代码文件
  109 +- 按 `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md` 格式 commit:
  110 + `fix(<module_id 或 scope>): 修复 review round <N> must-fix <id>`
  111 +- **重新执行本 skill 的验证阶段**(阶段一);通过后进入 round `<N+1>` 的 review 阶段
  112 +
  113 +**request-changes(round == 5)**
  114 +
  115 +- 停止并打印摘要(本 id、5 轮 must-fix 列表汇总),升级给用户手工介入
  116 +- 不再自动修复,不回调 `phase-driver`
  117 +
  118 +---
  119 +
  120 +## 护栏
  121 +
  122 +- **绝不**在主会话直接跑测试,必须通过子会话
  123 +- **绝不**自由编写证据正文,必须从模板渲染
  124 +- 不要把原始 stdout 全文塞进主会话(`stdout_excerpt` ≤ 30 行)
  125 +- verify 失败(exit_code≠0 或 failed>0)→ 硬停,不进 review
  126 +
  127 +---
31 128  
32 129 ## 参考
33 130  
34   -- `${CLAUDE_SKILL_DIR}/templates/feature-review-template.md`
35   -- 委托:`superpower-code-reviewer`(本插件 `agents/superpower-code-reviewer.md`)
36   -- Fix commit 格式与 `feature-tdd/templates/commit-message-template.md` 一致
37   -- 上游:`feature-verify`;下游:`module-start`(approve)/ `feature-verify`(request-changes)
  131 +- `${CLAUDE_SKILL_DIR}/templates/feature-review-template.md`(verify 证据 + review 结论合并文档)
  132 +- `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md`(fix commit 格式)
  133 +- 委托:`superpower-code-reviewer`(backend,本插件 `agents/superpower-code-reviewer.md`)
  134 +- 委托:`fe-code-reviewer`(frontend,本插件 `agents/fe-code-reviewer.md`,前端专用,硬编码 7 维 review checklist)
  135 +- 上游:`feature-tdd`
  136 +- 下游:`phase-driver`(approve)/ 本 skill 验证阶段(request-changes 重验)
... ...
skills/coding/fe-feature-review/templates/commit-message-template.md renamed to skills/coding/feature-review/templates/commit-message-template.md
skills/coding/feature-review/templates/feature-review-template.md
1 1 ---
2 2 req_id: {{req_id}}
3 3 date: {{date}}
  4 +phase: {{phase}}
4 5 round: {{round}}
5   -reviewer: superpower-code-reviewer
6 6 ---
7 7  
8   -# Review: {{req_id}} — round {{round}}
  8 +# 验证 + 审阅:{{req_id}} — round {{round}}
9 9  
10   -## 结论
  10 +## 验证证据
  11 +
  12 +- 命令: `{{command}}`
  13 +- 子会话: {{subagent_id}}
  14 +- 退出码: {{exit_code}}
  15 +- 通过用例数: {{passed}}
  16 +- 失败用例数: {{failed}}
  17 +- 失败列表: {{failed_list}}
  18 +
  19 +关键 stdout 片段 (≤30 行):
  20 +
  21 +```
  22 +{{stdout_excerpt}}
  23 +```
  24 +
  25 +结论: {{verify_conclusion}} (pass / fail)
  26 +
  27 +---
  28 +
  29 +## 自审结论
  30 +
  31 +审阅者: {{reviewer}} <!-- phase=backend → superpower-code-reviewer;phase=frontend → fe-code-reviewer -->
  32 +
  33 +### 结论
11 34 {{verdict}} (approve / request-changes)
12 35  
13   -## Must-fix
  36 +### Must-fix
14 37 {{#each must_fix}}
15 38 - [{{severity}}] {{file}}:{{line}} — {{issue}}(建议:{{suggestion}})
16 39 {{/each}}
17 40  
18   -## Nice-to-have
  41 +### Nice-to-have
19 42 {{#each nice_to_have}}
20 43 - {{file}}:{{line}} — {{suggestion}}
21 44 {{/each}}
22 45  
23   -## 反例 / 测试覆盖缺口
  46 +### 反例 / 测试覆盖缺口
24 47 {{gaps}}
... ...
skills/coding/feature-spec/SKILL.md 0 → 100644
  1 +---
  2 +name: feature-spec
  3 +description: 统一功能循环第 1 步(后端 REQ / 前端 FE 共用,由 phase 参数区分)。交互式 Q&A → 产出"规格 + 任务级 TDD 计划"合并文档到 docs/superpowers/specs/,链入 feature-tdd。
  4 +user-invocable: false
  5 +allowed-tools: Read Write Grep Glob Skill AskUserQuestion Bash(mysql *)
  6 +---
  7 +
  8 +**所有输出必须使用中文。**
  9 +
  10 +# feature-spec
  11 +
  12 +统一功能循环第 1 步,后端(REQ-XXX-NNN)和前端(FE-NN)共用,由 `phase` 参数区分范围与上下文。交互式 Q&A → 产出"规格 + 任务级 TDD 计划"合并文档 → 链入 `feature-tdd`。
  13 +
  14 +**入参(由上游 skill 传入):**
  15 +- `phase`:`backend` | `frontend`
  16 +- `id`:`REQ-XXX-NNN`(backend)或 `FE-NN`(frontend)
  17 +- `name`:功能名称
  18 +- `associated_reqs[]`:(仅 frontend)关联的 REQ 卡片 id 列表
  19 +- `associated_prototypes[]`:(仅 frontend)关联的 prototype 文件路径列表
  20 +
  21 +---
  22 +
  23 +## 占位符规则
  24 +
  25 +本 skill 写的 spec 是 CC 内部推理产物,不是用户审阅文档。**不允许** `【人工填写:...】` 占位符——A 阶段标记只在 `docs/01~10` / `CLAUDE.md` / `.env.local` 使用。需要具体值时:
  26 +
  27 +1. **先查** `.env.local` + `docs/04 §零环境` / `CLAUDE.md` / 现有代码 / 关联 prototype(frontend 时)。值已落地某处 → spec 中引用源(例 "JWT_SECRET 从 `.env.local` 读取,`application.yml` 用 `${JWT_SECRET}` 注入")
  28 +2. **再问**:查不到 → `AskUserQuestion` 问用户,记录答案到 spec
  29 +3. **绝不**留 `【人工填写:】` 占位符;若 1 + 2 都解决不了,spec 必须写出具体阻塞点(不是泛化占位符),Q&A 继续直到解决
  30 +
  31 +---
  32 +
  33 +## 阶段范围
  34 +
  35 +### phase=backend
  36 +
  37 +产出范围限定为:controller / service / repository / DTO / 校验 / SQL migration / REST 契约。
  38 +
  39 +读 `docs/01-需求清单/<module>/<req_id>.md` 时**忽略 UI 描述**(输入控件类型、按钮位置、列表布局等),但**校验规则、业务规则**仍要落到后端 DTO + service。UI 实现统一推迟到前端阶段(`phase=frontend`)。
  40 +
  41 +上下文来源:
  42 +- REQ 卡片 `docs/01-需求清单/<module>/<id>.md`
  43 +- 涉及的数据表定义(取自 `docs/03-数据库设计文档.md` 或实时 `mysql` 查询)
  44 +
  45 +### phase=frontend
  46 +
  47 +产出范围限定为:组件树 / 页面状态机 / 交互流程 / API 调用 / Design Tokens 引用 / 业务校验前端复刻。**不涉及** SQL / migration / controller / service / DTO(后端阶段已完成)。
  48 +
  49 +一个 FE 是**业务功能**粒度,可能关联多个 prototype 文件区域和多个 REQ。
  50 +
  51 +上下文来源:
  52 +- **页面骨架**:Read 所有 `associated_prototypes[]`(含 anchor 时聚焦相应区域),作为布局权威
  53 +- **业务规则**:Read 所有 `associated_reqs[]` 对应的 `docs/01-需求清单/<module>/<REQ-id>.md`,提取业务校验规则、acceptance、UI 描述
  54 +- **API 契约**:Read `docs/05-API接口契约.md`,按 `associated_reqs[]` 过滤出本 FE 消费的端点
  55 +- **Design Tokens**:Read `docs/06-UI交互规范.md § 二`,作为色值 / 状态色的引用源
  56 +- **前端组件库**:Read `docs/04-技术规范.md § 零` 找 `frontend.ui_lib`(如 Ant Design / Element Plus),决定组件选型
  57 +
  58 +---
  59 +
  60 +## 执行步骤
  61 +
  62 +### 步骤 1:收集上下文
  63 +
  64 +按上方"阶段范围"对应的上下文来源读取所有相关文档。
  65 +
  66 +### 步骤 2:评估 scope
  67 +
  68 +- 单 spec 容纳得下吗?
  69 +- `phase=backend`:跨多个独立子系统(如"含登录 + 文件存储 + 计费 + 分析")→ 先提示分解,每个子项目独立 brainstorm
  70 +- `phase=frontend`:跨多页 / 多业务 → 提示拆分,每个 FE 应独立可测试
  71 +
  72 +### 步骤 3:交互式 Q&A
  73 +
  74 +参考下方"Q&A 原则"进行交互式问答:
  75 +
  76 +- `phase=backend`:聚焦 goal / 输入输出 / 业务规则 / 约束 / schema / API 引用 / acceptance criteria
  77 +- `phase=frontend`:聚焦组件树、页面状态机、交互流程、API 调用一致性、Design Tokens 引用、业务校验前端复刻。**不要**讨论 SQL / migration / controller / service / DTO
  78 +
  79 +**一次一问** `AskUserQuestion`,仅对真模糊点;多选题优先。决策完成后挑一种 approach;trade-off 直接内嵌 spec,**不设确认 gate**。
  80 +
  81 +### 步骤 4:写合并文档
  82 +
  83 +写到 `docs/superpowers/specs/<YYYY-MM-DD>-<id>.md`(`id` = `REQ-XXX-NNN` 或 `FE-NN`):
  84 +
  85 +- 按 `${CLAUDE_SKILL_DIR}/templates/feature-spec-plan-template.md` 渲染
  86 +- **只填写当前 phase 对应的规格小节**(另一 phase 的小节留空或删除)
  87 +- 规格后紧接任务级计划(plan 部分)
  88 +- 计划粒度:每任务 2-5 分钟,= 一个 red-green-commit 单元
  89 +
  90 +**计划写作原则(两 phase 通用):**
  91 +- Plan 告诉 TDD 执行者**做什么**,不是**怎么写代码**
  92 +- Plan 锁定**文件边界 + 测试意图 + API / Props 形状 + 完成判据**;代码由 TDD 红绿循环产出
  93 +- **禁止 dump 整个文件内容**到 plan(pom.xml / entity 类 / vue 组件源码 / config 文件)
  94 +- `phase=backend` 任务:`impl_file` 禁止以 `frontend/` 开头;`phase=frontend` 任务:`impl_file` 必须以 `frontend/` 开头
  95 +- 每个任务含 4 步:写失败测试 → 实现最小代码 → 子会话验证 PASS → commit
  96 +- `phase=frontend` 每个任务必须标注"测试先行类型":`jsdom 组件测试` 或 `Playwright E2E`
  97 +
  98 +文件已存在 → 征求用户确认后覆盖。
  99 +
  100 +### 步骤 5:Spec + Plan 自审(inline 修,无须用户等待)
  101 +
  102 +**Spec 部分:**
  103 +- **占位符扫描**:`TBD` / `TODO` / `【人工填写:】` / 含糊段 → 修(按"占位符规则"流程解决)
  104 +- **内部一致性**:节与节是否矛盾?架构是否匹配功能描述?
  105 +- **范围检查**:单 plan 能消化吗?还是需要分解
  106 +- **歧义检查**:任何 requirement 两种解读?挑一个写明
  107 +- `phase=frontend` 额外检查:全文不得出现 `TBD` / `@todo` / `controller` / `SQL` / `service` / `migration` → 命中则修正后重渲染
  108 +
  109 +**Plan 部分:**
  110 +- **占位符扫描**:`TBD` / `TODO` / `implement later` / `fill in details` / `【人工填写:】` → 修
  111 +- **Spec coverage**:skim spec 每节,能指向至少一个 task 吗?list gaps 并补 task
  112 +- **类型一致性**:tasks 之间签名 / 方法名 / 属性名 / 错误码一致(Task 3 的 `clearLayers()` 和 Task 7 的 `clearFullLayers()` 是 bug)
  113 +- `phase=frontend`:每个任务的 `impl_file` 路径必须以 `frontend/` 开头;命中 `backend/` / `sql/` / `scripts/` → 修正后重渲染
  114 +
  115 +### 步骤 6:输出 + 链 feature-tdd
  116 +
  117 +(**直接做这两件事,不要输出"回交父 skill / 交给 caller / 等下一步 / 准备好了请检查"之类的桥接叙述**——那些会被解读为 turn 结束信号)
  118 +
  119 +- 输出一行 `feature-spec: <id> → <path>`
  120 +- **同一 turn 内立即** `Skill(feature-tdd)` 传入 `{ phase, id }`
  121 +
  122 +---
  123 +
  124 +## Q&A 原则
  125 +
  126 +- **一次一问** — 不堆问题
  127 +- **多选题优先** — 答更快
  128 +- **仅对真模糊点问** — 不造确认问题
  129 +- **YAGNI** — 删 spec 中不必要的功能
  130 +- **渐进理解** — 不明白就问
  131 +- **无审批 gate** — 写 spec 即 commit;分歧落地为具体 Q&A 项,不靠"等用户确认"
  132 +
  133 +---
  134 +
  135 +## 任务原则
  136 +
  137 +### Plan 文件头
  138 +
  139 +每个合并文档的 plan 部分必须以以下头部开始:
  140 +
  141 +```markdown
  142 +# [Feature Name] Implementation Plan
  143 +
  144 +> **Execution:** Parent skill `feature-tdd` executes this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
  145 +
  146 +**Goal:** [一句话描述]
  147 +
  148 +**Architecture:** [2-3 句方法论]
  149 +
  150 +**Tech Stack:** [关键技术 / 库]
  151 +
  152 +---
  153 +```
  154 +
  155 +### Task 结构
  156 +
  157 +每个 task 是 red-green-commit 单元。捕获意图和边界,代码留给 TDD:
  158 +
  159 +````markdown
  160 +### Task N: [组件名 / 类名]
  161 +
  162 +**Files:**
  163 +- Create: `exact/path/to/File.java`(或 `frontend/src/...`)
  164 +- Modify: `exact/path/to/Existing.java:123-145`
  165 +- Test: `tests/exact/path/to/FileTest.java`
  166 +- 测试先行类型: jsdom 组件测试(仅 phase=frontend 需标注)
  167 +
  168 +**API shape / Props shape**(只写需要约束实现的签名;内部实现留给 TDD):
  169 +- `LoginService#login(LoginRequest req) : LoginResponse`
  170 +
  171 +- [ ] **Step 1: 写失败测试**
  172 + - 测试名: `LoginServiceTest#loginWithBadPassword_incrementsFailCount_returns40101`
  173 + - 意图: 错误密码 → `iLoginFailCount += 1`;第 5 次 → 设置 `tLockUntil = now + 15min`;返回码 40101
  174 + - 子会话确认 FAIL(函数/类不存在)
  175 +
  176 +- [ ] **Step 2: 实现最小代码**
  177 + - 目标: 让 Step 1 测试通过;不多做
  178 + - 涉及文件: `LoginService.java`, `SftLoginInfoMapper.java`
  179 +
  180 +- [ ] **Step 3: 子会话验证 PASS**
  181 +
  182 +- [ ] **Step 4: Commit**
  183 + - `git add <文件>`
  184 + - `git commit -m "feat(sys): 登录失败计数 + 锁定 REQ-SYS-001"`
  185 +````
  186 +
  187 +### 允许的代码块场景
  188 +
  189 +少数例外,需要写死而非让 TDD 自由发挥:
  190 +
  191 +- **DDL / migration 文件**(phase=backend):`V_n__*.sql` 的 ALTER/CREATE 语句——schema 是事实源
  192 +- **合同级常量**:API 错误码表、JWT claim 名、Redis key 模式——跨模块消费,必须锁定
  193 +- **路由配置**(phase=frontend):`routes.ts` 中 path 注册(路径是契约级)
  194 +- **API client 契约**(phase=frontend):fetch 包装函数签名 + headers + 错误码 mapping
  195 +- **Design Tokens 名称**(phase=frontend):`var(--color-primary)` 列表
  196 +- **测试断言形状**(可选):一句话说不清"测什么"时,给个 3-5 行断言 sketch
  197 +
  198 +除此之外一律散文 + 签名描述,**不贴完整文件**。
  199 +
  200 +### 记住
  201 +
  202 +- Exact file paths always
  203 +- Exact commands with expected output(测试运行 + git 操作)
  204 +- API signatures / class names / error codes / contract values — **必须写死**
  205 +- Internal implementation code — **不写**;留给 TDD 阶段
  206 +- DRY、YAGNI、TDD、frequent commits
  207 +
  208 +---
  209 +
  210 +## 参考
  211 +
  212 +- `${CLAUDE_SKILL_DIR}/templates/feature-spec-plan-template.md`
  213 +- 上游(backend):`module-start`
  214 +- 上游(frontend):`frontend-start`
  215 +- 下游:`feature-tdd`
... ...
skills/coding/feature-spec/templates/feature-spec-plan-template.md 0 → 100644
  1 +<!-- 填写说明:仅填写当前 phase 对应的规格小节;另一 phase 小节留空或删除。-->
  2 +阶段: {{phase}}
  3 +
  4 +---
  5 +
  6 +# 规格 + 计划:{{id}} — {{title}}
  7 +
  8 +> 日期:{{date}}
  9 +
  10 +---
  11 +
  12 +## 规格
  13 +
  14 +### (phase=backend 填写)后端规格
  15 +
  16 +---
  17 +req_id: {{req_id}}
  18 +date: {{date}}
  19 +module: {{module}}
  20 +---
  21 +
  22 +#### 目标
  23 +{{goal}}
  24 +
  25 +#### 输入 / 触发
  26 +{{input}}
  27 +
  28 +#### 输出 / 结果
  29 +{{output}}
  30 +
  31 +#### 业务规则
  32 +{{rules}}
  33 +
  34 +#### 边界与约束
  35 +{{constraints}}
  36 +
  37 +#### 依赖的 schema 表 / 字段
  38 +{{schema_refs}}
  39 +
  40 +#### 依赖的接口
  41 +{{api_refs}}
  42 +
  43 +#### 验收标准
  44 +{{acceptance}}
  45 +
  46 +---
  47 +
  48 +### (phase=frontend 填写)前端规格
  49 +
  50 +<!-- 仅 phase=frontend 时填写以下各节;phase=backend 时忽略。-->
  51 +
  52 +> 关联 REQ:{{associated_reqs}}
  53 +> 关联原型:{{associated_prototypes}}
  54 +
  55 +#### 功能概述
  56 +{{feature_overview}}
  57 +
  58 +#### 组件树
  59 +
  60 +<!-- 基于关联原型的 DOM 结构推导。多页则按页面分块;每层缩进表示嵌套关系。 -->
  61 +
  62 +```
  63 +{{component_tree}}
  64 +```
  65 +
  66 +#### 页面状态机
  67 +
  68 +| # | 状态 | 触发条件 | 视觉表现 | 用户可执行操作 |
  69 +|---|------|---------|---------|--------------|
  70 +{{state_machine_rows}}
  71 +
  72 +至少包含:loading / empty / error / 正常 / 提交中 五态。
  73 +
  74 +#### 消费的后端端点
  75 +
  76 +| # | 方法 | 路径 | 触发时机 | 关联 REQ |
  77 +|---|------|------|---------|---------|
  78 +{{endpoint_rows}}
  79 +
  80 +#### 业务规则前端复刻清单
  81 +
  82 +| # | 规则描述 | 触发时机 | 报错文案 | 来源 REQ |
  83 +|---|---------|---------|---------|---------|
  84 +{{validation_rows}}
  85 +
  86 +> **要求**:每条规则必须在前端 form-level 校验中复刻,不仅依赖后端报错。文案与后端语义一致。
  87 +
  88 +#### Design Tokens 引用清单
  89 +
  90 +<!-- 列出本页面用到的 token 变量名(不写 hex),如 var(--color-primary) / var(--color-bg-card)。来源见 docs/06 § 二。 -->
  91 +
  92 +```
  93 +{{token_list}}
  94 +```
  95 +
  96 +#### 交互流程关键路径
  97 +{{interaction_flow}}
  98 +
  99 +#### 备注与开放问题
  100 +{{open_questions}}
  101 +
  102 +---
  103 +
  104 +## 任务级计划
  105 +
  106 +> **Execution:** Parent skill `feature-tdd` executes this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
  107 +
  108 +**Goal:** {{plan_goal}}
  109 +
  110 +**Architecture:** {{plan_architecture}}
  111 +
  112 +**Tech Stack:** {{plan_tech_stack}}
  113 +
  114 +---
  115 +
  116 +### Schema 改动
  117 +{{schema_change_decision}} <!-- "无" 或 "需要 migration:V<n>__<snake_case>.sql,作用:<一行描述>" — 仅 phase=backend 适用 -->
  118 +
  119 +### 文件变更清单
  120 +{{#each files}}
  121 +- `{{path}}` — {{action}}({{rationale}})
  122 +{{/each}}
  123 +
  124 +### 任务步骤
  125 +{{#each tasks}}
  126 +#### Task {{index}}: {{title}}
  127 +
  128 +**Files:**
  129 +{{task_files}}
  130 +
  131 +**API shape / Props shape**(只写需要约束实现的签名):
  132 +{{api_shape}}
  133 +
  134 +- [ ] **Step 1: 写失败测试**
  135 + - 测试名: `{{test_file}}::{{test_name}}`
  136 + - 意图: {{test_intent}}
  137 + - 子会话确认 FAIL
  138 +
  139 +- [ ] **Step 2: 实现最小代码**
  140 + - 目标: 让 Step 1 测试通过;不多做
  141 + - 涉及文件: `{{impl_file}}`
  142 +
  143 +- [ ] **Step 3: 子会话验证 PASS**
  144 +
  145 +- [ ] **Step 4: Commit**
  146 + - `git add <文件>`
  147 + - `git commit -m "{{commit_message}}"`
  148 +{{/each}}
  149 +
  150 +### 提交计划
  151 +{{#each commits}}
  152 +- `{{message}}`(覆盖 Task {{task_index}})
  153 +{{/each}}
... ...
skills/coding/feature-tdd/SKILL.md
1 1 ---
2 2 name: feature-tdd
3   -description: 功能循环第 3 步。按 plan 逐任务做 TDD(失败测试 → 实现 → 通过 → commit),测试运行强制派发到子会话
  3 +description: 统一功能循环第 2 步(后端 REQ / 前端 FE 共用,由 phase 参数区分)。按 plan 逐任务做 TDD(失败测试 → 实现 → 通过 → commit),所有测试运行强制派发到 Agent 子会话,主会话只接收 JSON 结果
4 4 user-invocable: false
5 5 allowed-tools: Read Write Edit Agent Skill Bash(git add *) Bash(git commit *)
6 6 ---
... ... @@ -9,34 +9,92 @@ allowed-tools: Read Write Edit Agent Skill Bash(git add *) Bash(git commit *)
9 9  
10 10 # feature-tdd
11 11  
12   -按 plan 文件逐任务做 TDD:写失败测试 → 写最小实现 → 确认通过 → commit。**所有测试运行强制派发到 Agent 子会话**,主会话只接收 JSON 结果。
  12 +按合并文档(spec + plan)的任务级计划逐任务做 TDD:写失败测试 → 写最小实现 → 确认通过 → commit。**所有测试运行强制派发到 Agent 子会话**,主会话只接收 JSON 结果。
  13 +
  14 +**入参(由 feature-spec 传入):**
  15 +- `phase`:`backend` | `frontend`
  16 +- `id`:`REQ-XXX-NNN`(backend)或 `FE-NN`(frontend)
  17 +
  18 +---
  19 +
  20 +## 阶段差异
  21 +
  22 +### phase=backend
  23 +
  24 +- 工作分支:`module-<module_id>`
  25 +- `impl_file` 不得以 `frontend/` 开头(见护栏)
  26 +- 测试命令:`./scripts/test.sh`(由子会话执行)
  27 +- Schema 改动前置:有 migration 需求时,第一个任务必须是写 migration + 同步 docs/03
  28 +- 提交 trailer:`REQ-XXX-NNN` 标签(内嵌在 commit subject 中)
  29 +
  30 +### phase=frontend
  31 +
  32 +- 工作分支:`frontend-phase`
  33 +- `impl_file` 必须以 `frontend/` 开头(见护栏)
  34 +- 测试命令:从 `docs/04-技术规范.md § 零 frontend` 取:
  35 + - `frontend.unit_test_runner`:vitest / jest(默认 vitest)
  36 + - `frontend.e2e_runner`:playwright(默认 playwright)
  37 + - `frontend.test_command` / `frontend.e2e_command`(缺失则用 `pnpm test:ci` / `pnpm e2e:ci`)
  38 +- **无** SQL migration 步骤
  39 +- 提交 trailer:`REQ_ID: FE-NN`(作为 commit trailer 行)
  40 +
  41 +---
13 42  
14 43 ## 执行步骤
15 44  
16   -1. 加载计划文件 `docs/superpowers/plans/<YYYY-MM-DD>-<REQ-id>.md`。
17   -2. **Schema 改动前置**(仅当 plan 声明需要):第一个任务必须是写 migration 文件 + 同步更新 docs/03,并一起 commit。
  45 +1. **加载 spec + plan**:读取 `docs/superpowers/specs/<YYYY-MM-DD>-<id>.md`,定位 `## 任务级计划` 节。
  46 +
  47 +2. **Schema 改动前置**(仅 `phase=backend`,且 plan 声明需要时):第一个任务必须是写 migration 文件 + 同步更新 docs/03,并一起 commit。
18 48 - 文件命名 `V<n>__<snake_case>.sql`,`<n>` = 现有 `sql/migrations/V*.sql` 最大版本号 + 1;文件只含 DDL
19 49 - **同步**把新 CREATE / ALTER 反向更新到 `docs/03-数据库设计文档.md` 对应表小节,保持 docs/03 是 schema 的 SSoT;新增表按表小节模板追加
20 50 - migration + docs/03 改动**同一 commit**,避免 SSoT 与 migration 分裂
21   - - 测试运行时 Spring Boot 启动 Flyway 会自动 apply 这个新 migration;`scripts/setup-test-db.sh` 只负责清库
22   -3. 按顺序处理每个代码类任务:
23   - a. 在 `test_file::test_name` 处写**失败**测试
24   - b. 派发 Agent 子会话(general-purpose)运行测试确认失败,子会话只返回 `{command, exit_code, failing_assertion}` JSON
25   - c. 在 `impl_file` 处写**最小**实现使测试通过
  51 + - 测试运行时 Spring Boot 启动 Flyway 会自动 apply 新 migration
  52 +
  53 +3. **按顺序处理每个代码类任务**:
  54 +
  55 + a. 在 `test_file::test_name` 处写**失败**测试:
  56 + - `phase=backend`:JUnit / 框架测试
  57 + - `phase=frontend`,`测试先行类型=jsdom`:在 jsdom 环境下用 vitest/jest 写组件单测(render + 断言 DOM / 交互后状态变化)
  58 + - `phase=frontend`,`测试先行类型=e2e`:在 `frontend/e2e/` 写 Playwright 测试(headless)
  59 +
  60 + b. 派发 Agent 子会话(general-purpose)运行该测试,子会话只返回 `{command, exit_code, failing_assertion}` JSON,确认失败
  61 +
  62 + c. 在 `impl_file` 处写**最小**实现使测试通过。**严格遵守**:
  63 + - `phase=backend`:`impl_file` 不得以 `frontend/` 开头(违反 → 护栏硬停)
  64 + - `phase=frontend`:`impl_file` 必须以 `frontend/` 开头(违反 → 护栏硬停);色值用 `var(--color-*)`(来自 spec §六),不硬编码 hex;业务校验按 spec §五 在 form-level 复刻
  65 +
26 66 d. 再次派发子会话确认通过
27   - e. 同一测试 >10 次修复仍失败 → 调用 `interrupt-check`(中断 #1:测试反复失败)
28   - f. 按 `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md` 格式 commit(`scope` = 任务模块;`subject` ≤ 50 字符;`req_id` 必填)
29   -4. 全部任务完成 → 调用 `Skill(feature-verify)`。
  67 +
  68 + e. 同一测试 >10 次修复仍失败 → 调用 `Skill(interrupt-check)`(中断 #1:测试反复失败)
  69 +
  70 + f. 按 `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md` 格式 commit:
  71 + - `phase=backend`:`scope` = 任务模块;`subject` ≤ 50 字符;内含 `REQ-XXX-NNN` 标签
  72 + - `phase=frontend`:`scope` = 组件名(如 `dashboard` / `user-form`);`subject` ≤ 50 字符;必含 trailer `REQ_ID: FE-NN`
  73 +
  74 +4. **全部任务完成** → 调用 `Skill(feature-review)` 传入 `{ phase, id }`
  75 +
  76 +---
30 77  
31 78 ## 护栏
32 79  
33   -- **绝不**在主会话直接跑 `mvn test` / `pnpm test` / `scripts/test.sh`,必须通过子会话
  80 +- **绝不**在主会话直接跑任何测试命令(`mvn test` / `pnpm test` / `scripts/test.sh` / `pnpm playwright` / `vitest`),必须通过子会话
34 81 - **绝不**在主会话直接 `mysql -e "ALTER ..."`;业务 schema 改动一律走 `sql/migrations/V*.sql` 文件(只读查询 / 临时调试除外)
35   -- 每次 commit 必须含 `REQ-XXX-NNN` 标签;不混合无关改动到同一 commit
36   -- **后端阶段路径硬护栏**:任务表里的 `impl_file` 路径以 `frontend/` 开头 → 硬停并打印 `feature-tdd 后端阶段不允许写前端代码:<impl_file>。请检查 plan 任务定义;UI 推迟到前端阶段(fe-feature-*)`,不再继续 TDD 循环
  82 +- **后端阶段路径硬护栏(phase=backend)**:任务表里的 `impl_file` 路径以 `frontend/` 开头 → 硬停并打印:
  83 + ```
  84 + feature-tdd 后端阶段不允许写前端代码:<impl_file>。请检查 plan 任务定义;UI 推迟到前端阶段(phase=frontend)。
  85 + ```
  86 +- **前端阶段路径硬护栏(phase=frontend)**:`impl_file` 路径**不以** `frontend/` 开头,或命中 `backend/` / `sql/` / `scripts/` → 硬停并打印:
  87 + ```
  88 + feature-tdd 前端阶段不允许写非前端文件:<impl_file>。前端阶段任务的 impl_file 必须落在 frontend/ 目录下。
  89 + ```
  90 +- 不硬编码颜色 hex(`phase=frontend`);token 引用必须对齐 spec §六
  91 +
  92 +---
37 93  
38 94 ## 参考
39 95  
40 96 - `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md`
41 97 - 守门:`interrupt-check`(仅在步骤 3.e 触发,条件 1)
42 98 - 原则参考:`superpowers:test-driven-development`(外部 TDD 原则手册,本 skill 已固化"子会话跑测试 + REQ-tagged commit"流程,不做运行时 invoke)
  99 +- 上游:`feature-spec`
  100 +- 下游:`feature-review`
... ...
skills/coding/feature-verify/SKILL.md deleted
1   ----
2   -name: feature-verify
3   -description: 功能循环第 4 步。把功能测试派发到子会话跑,按模板渲染证据。无证据不声称完成。
4   -user-invocable: false
5   -allowed-tools: Skill Read Agent
6   ----
7   -
8   -**所有输出必须使用中文。**
9   -
10   -# feature-verify
11   -
12   -把当前 REQ 的功能测试派发到 Agent 子会话执行,按模板把结构化结果渲染成证据。**主会话从不直接跑测试**,也不自由编写证据。
13   -
14   -## 执行步骤
15   -
16   -1. 从 plan 文件或项目标准命令中确定功能的测试目标(如 Maven profile / pnpm script / pytest path)。
17   -2. 派发 Agent 子会话(general-purpose)运行该目标,子会话只返回结构化 JSON(不输出描述文字):
18   - ```json
19   - {
20   - "command": "<cmd>",
21   - "exit_code": <int>,
22   - "passed": <int>,
23   - "failed": <int>,
24   - "failed_list": ["<test>", ...],
25   - "stdout_excerpt": "<最后 30 行或最相关的失败片段>"
26   - }
27   - ```
28   -3. 按 `${CLAUDE_SKILL_DIR}/templates/feature-verify-evidence-template.md` 渲染证据并打印到会话。
29   -4. **`exit_code != 0` 或 `failed > 0`** → 停止,不进入 review。
30   -5. 通过 → 调用 `Skill(feature-review)`。
31   -
32   -## 护栏
33   -
34   -- **绝不**在主会话直接跑测试,必须通过子会话
35   -- **绝不**自由编写证据正文,必须从模板渲染
36   -- 不要把原始 stdout 全文塞进主会话(`stdout_excerpt` ≤ 30 行)
37   -
38   -## 参考
39   -
40   -- `${CLAUDE_SKILL_DIR}/templates/feature-verify-evidence-template.md`
41   -- 原则参考:`superpowers:verification-before-completion`(外部"证据先于断言"原则手册,本 skill 已固化子会话派发 + 模板渲染流程,不做运行时 invoke)
skills/coding/feature-verify/templates/feature-verify-evidence-template.md deleted
1   -## Verify evidence — {{req_id}}
2   -
3   -- 命令: `{{command}}`
4   -- 子会话: {{subagent_id}}
5   -- 退出码: {{exit_code}}
6   -- 通过用例数: {{passed}}
7   -- 失败用例数: {{failed}}
8   -- 失败列表: {{failed_list}}
9   -
10   -关键 stdout 片段 (≤30 行):
11   -
12   -```
13   -{{stdout_excerpt}}
14   -```
15   -
16   -结论: {{conclusion}} (pass / fail)