| name | whole-qa |
| description | cc-code 全量验收 + 修复闭环编排器。MVP 收口前使用:穷尽测试所有页面/所有可交互元素/所有接口,按 prd.md 模块分组 fan-out 到 qa subagent,FAIL 清单自动回环给 dev subagent 修复,≤3 轮收敛。本 skill 自身是编排器 —— 不碰代码、不碰需求,只做清点/分发/汇总/循环控制。手动触发 /cc-code:whole-qa,不自动加载。 |
| allowed-tools | Read, Write, Edit, Bash, Glob, Grep, Agent, TaskCreate, TaskUpdate, TaskList, mcp__codegraph__codegraph_explore, mcp__codegraph__codegraph_search, mcp__codegraph__codegraph_node, mcp__codegraph__codegraph_callers |
| disable-model-invocation | true |
whole-qa — 全量验收 + 修复闭环编排器
手动触发:仅由用户显式输入 /cc-code:whole-qa 调用。
与 qa agent 的关系:qa 是「单模块测一次」的原子能力;本 skill 是「全模块 × 多轮 + 修复回环」的编排层,复用 qa,不重写测试逻辑。
与 agent-to-mvp 的关系:agent-to-mvp 每阶段用 qa 做增量验收;本 skill 用于 MVP 收口前的一次性全量清算。
⛔ 六条硬约束(违反任一即本次验收无效)
1. 你是编排器,不是执行者
❌ 错:whole-qa 自己测、自己修
→ 测的人知道修的人怎么想,修的人知道测的人怎么测 → 互相糊弄
✅ 对:whole-qa 只做 清点 / 分发 / 汇总 / 循环控制
whole-qa(不碰代码,不碰需求)
├─ Agent(subagent_type=qa) ──► 测(只拿到断言,不知道谁会修)
└─ Agent(subagent_type=dev) ──► 修(只拿到 FAIL 清单,不知道怎么测的)
主控绝不自己写测试、自己改代码。发现自己在写 expect(...) 或改 src/ 就是越界了。
2. 分母先锁定,再开测
INVENTORY 阶段的产物落盘后本轮分母不可变更。禁止中途以「这个按钮不用测」「这个接口是内部的」为由缩小分母。要改分母,只能作废本轮重新开始。
3. 禁止修需求
本 skill 及其派生的 dev subagent 对以下文件【只读,绝对禁写】:
active/prd.md active/ux.md active/api.md
修不动 → 标记 ESCALATE 交人决策
这是 AI 修 bug 时最常走的偷懒路径:改断言让测试变绿。不用规则堵死,它一定会走。
4. 收敛门控
第 N 轮 FAIL 数 必须 < 第 N-1 轮 FAIL 数
├─ 不递减 → 停止,报告「未收敛」,交人决策
├─ 出现新增 FAIL → 停止(修 A 坏 B),报告震荡点,建议回滚本轮
└─ 最多 3 轮
5. 回归门(每轮必跑)
每轮修完,重跑范围 = 本轮 FAIL 项 + affected 算出的真实影响面
↑ 缺这半段就会「越修越坏」而毫不知情
⭐0.10.0:影响面从「同模块已 PASS 项」升级为 codegraph affected 算出的
传递闭包 —— 同模块是人凭直觉画的圈,affected 是沿 import 图算出的事实,
跨模块的隐式依赖只有后者抓得到。
codegraph affected <本轮修改的源文件...>
非 .spec/.test 命名的测试补跑 --filter "<project.md §六 登记的 glob>"
返回空 → 报一行「未匹配到测试,本轮用全量」+ 自查三点:
① 测试代码是否被 .gitignore 屏蔽(被 ignore 则不进索引)
② 测试是否 import 被测源码(纯 HTTP 型无 import 边,追不到)
③ 命名是否需 --filter
CLI 未装 → 静默退回「同模块已 PASS 项」,不报
6. 禁止静默截断
未测的元素/接口/断言,必须逐条列入 SKIPPED 并给原因。同构重复元素若做了组内抽样,必须写明「同构组 N 个,实测 M 个」—— 报告里出现「全部覆盖」而分母被悄悄缩小,是最严重的失职。
生命周期总览
┌ ⓿ PREFLIGHT 前置检查 ──────────────────────────────────────────┐
│ .cc_code/ 存在 · prd.md 有模块清单与验收断言 · 应用能起来 │
└───────────────────────┬────────────────────────────────────────┘
▼
┌ ❶ INVENTORY 清点(主控,只做一次,落盘即锁死分母)─────────────┐
│ 路由发现 → 页面 P[] │
│ ux.md §2.4 声明 ∪ 逐页 DOM snapshot → 元素 E[] ⭐取并集,差集必报│
│ 接口发现 → 接口 A[] │
│ prd.md §1.5 主表 → 断言 ASSERT[] │
│ ux.md §2.3 U编号矩阵 → 五态判定项 USTATE[] │
│ 按 prd.md 模块清单分组 → 模块 M[] │
│ codegraph 扫冗余 → DEAD/ORPHAN/DUP[] │
│ ↓ 落盘 .cc_code/docs/qa/<日期>-inventory.md │
└───────────────────────┬────────────────────────────────────────┘
▼
┌ ❷ FAN-OUT 分模块并发(每模块 1 个 qa subagent,独立上下文)────┐
│ 模块 M1 ──► 逐元素点击 + 五态断言 + 截图 + console 捕获 │
│ 模块 M2 ──► 同上 (并发,单消息多 Agent) │
│ 接口批 ──► 每接口 5 类断言 │
│ 每个只回 {断言ID, verdict, 证据, 复现步骤} │
└───────────────────────┬────────────────────────────────────────┘
▼
┌ ❸ REDUCE 汇总(主控)────────────────────────────────────────┐
│ 四个分母各算覆盖率:A断言 / U五态 / 元素 / 接口 │
│ SKIPPED 逐条列明原因 │
│ ↓ 落盘 docs/qa/<日期>-round-N.md │
│ ↓ gates.md 就地更新矩阵对应行 ⛔禁新开轮次章节 │
└───────────────────────┬────────────────────────────────────────┘
▼
┌─ 全 PASS ─► ❺ 收口
│
└─ 有 FAIL ─┐
▼
┌ ❹ FIX 轮(dev subagent,独立上下文)──────────────────────────┐
│ 输入:FAIL 清单原文(不含测法细节,防针对性糊弄) │
│ 禁写:prd.md / ux.md / api.md │
│ 修不动 → ESCALATE │
│ ↓ 回归门:重跑 FAIL + 同模块已 PASS │
│ ↓ 收敛检查(约束 4)→ 通过则回 ❸,否则停止交人 │
└────────────────────────────────────────────────────────────────┘
▼
┌ ❺ 收口 ──────────────────────────────────────────────────────┐
│ gates.md 矩阵定稿 · 归档索引+1行 · status.md 记里程碑 │
└────────────────────────────────────────────────────────────────┘
⓿ PREFLIGHT 前置检查
| # | 检查 | 不满足时 |
|---|
| 1 | .cc_code/active/ 存在 | 提示先 /cc-code:init,中止 |
| 2 | prd.md 有「模块清单」表 | 提示先 /cc-code:plan-prd-mvp 或切 PM 补,中止 |
| 3 | prd.md 各模块有 §1.5 验收断言(编号 A1..An) | 中止 —— 没有尺子不能验收,绝不自己编断言 |
| 3b | ux.md §2.3 有 U 编号五态矩阵(0.9.0 起) | UI 侧无尺子 —— 报主人:切 PM 补 U 编号,或本轮 UI/五态维度标 SKIPPED(缺U编号规格),⛔ 不许自己编 |
| 3c | gates.md 有「§二 验收追溯矩阵」骨架 | 格式落后 —— 提示 /cc-code:init 走 D4 格式体检归位,或本轮按新模板重建骨架(旧内容零删除迁 docs/qa/) |
| 4 | 读 project.md 拿到:启动命令 / 测试命令 / 测试目录 / 端口 | 缺失则问用户,不猜 |
| 5 | 应用可启动 | 见下方「启动应用」 |
| 6 | 有浏览器 MCP(chrome-devtools 或 Playwright) | 无则中止 —— 逐元素点击必须真实浏览器 |
启动应用
破坏性操作(删除 / 支付 / 发信 / 清库)必须跑在 seed 数据 + 独立库/独立环境。无法隔离的元素,标 SKIPPED(需隔离环境),不许在生产或共享库上点。
❶ INVENTORY 清点
详细规则见 references/inventory.md。要点:
| 维度 | 来源 | 关键原则 |
|---|
页面 P[] | 路由文件系统扫描 + 路由配置 | 含动态路由,需准备样本参数 |
元素 E[] | ux.md §2.4 声明清单 ∪ 运行时 DOM snapshot | ⭐取并集,差集必报:声明未实现(规格有代码没有)/ 实现未声明(代码有规格没有,即野生元素)。运行时那半保黑盒精神与穷尽性,声明那半给稳定编号 |
五态 USTATE[] | ux.md §2.3 的 U 编号矩阵 | ⭐编号原样引用,禁止另起。N/A 态不计入分母但要在报告留行 |
接口 A[] | 路由目录扫描 + api.md 契约表 + 页面操作时的真实网络请求 | 三来源取并集,差集要报告(契约有代码没有 = 未实现;代码有契约没有 = 影子接口) |
断言 ASSERT[] | prd.md §1.5 主表,逐模块 | 编号原样引用,禁止另起编号 |
模块 M[] | prd.md 模块清单 | 页面/元素/接口归属到模块,孤儿项单列「未归属」组 |
冗余 DEAD[]/ORPHAN[]/DUP[] | codegraph 扫代码 | ⭐测「不该有的有没有」:死代码/孤儿文件/重复实现,详见 inventory.md §六 |
同构重复元素处理(诚实优先):
唯一元素 → 必须逐个点,无例外
同构重复元素 → 归为「同构组」,测 首 / 末 / 边界样本
(如列表行内按钮) 报告必须写明:同构组 N 个,实测 M 个
落盘:.cc_code/docs/qa/<YYYY-MM-DD>-inventory.md
落盘后声明:本轮分母已锁定,并把四个分母数字(A 断言 / U 五态 / 元素 / 接口)告知用户。
❷ FAN-OUT 分模块并发
每模块一个 qa subagent。在单条消息里发出多个 Agent 调用以并发执行。
派给 qa subagent 的 prompt 骨架
你是本模块的验收执行者。只做测试取证,不改业务代码,不改需求文档。
【真相源】(只读)
.cc_code/active/prd.md 的模块 M{n}(规则 + §1.5 验收断言)
.cc_code/active/ux.md 的对应页面(§2.3 U 编号五态矩阵 + §2.4 可交互元素清单)
.cc_code/active/api.md 的对应接口段
.cc_code/active/project.md(仅取技术栈/测试框架/契约风格)
【本轮分母】(已锁定,不可增删)
页面:{P 列表}
可交互元素:{E 列表,含 testid 与同构组标注}
接口:{A 列表}
断言:{ASSERT 列表}
【BASE_URL】{url}
【必做】
1. 逐个点击分母内每一个元素(同构组按 首/末/边界 取样并标注)
2. 逐条判定分母内每一个 U 编号(正常 i / 加载 l / 完成 s / 错误 e / 空 m)
—— 结果必须挂在 U 编号上,禁止只报「某页部分通过」
3. 每接口 5 类断言:正常 / 缺参 / 越权 / 边界 / 错误码
4. 全程捕获 console 错误与失败网络请求,任一非预期报错即 FAIL
5. 破坏性操作若无法隔离,标 SKIPPED(需隔离环境),不许硬点
【禁止】
✗ 抽样跳过唯一元素 ✗ 修改 prd.md / ux.md / api.md
✗ 改业务代码 ✗ 把 FAIL 说成「大概没问题」
✗ 自己编造分母外的断言
【只回结构化结果】
| 断言ID/元素ID | verdict | 证据(测试名或截图路径) | 复现步骤 | 涉及文件:行 |
外加:SKIPPED 清单 + 原因
不要告诉 qa subagent「稍后会有 dev 来修」 —— 保持它对下游无知,才不会手下留情。
❸ REDUCE 汇总
模板见 references/report-template.md。主控要做:
- 合并所有 subagent 结果,按断言 ID(
A 段)与 U 编号(U 段)分别排序
- 算四个覆盖率(
A 断言 / U 五态 / 元素 / 接口),分母用锁定值
- 列 SKIPPED(每条带原因)
- 分级 FAIL:Critical(断言直接不达标)/ Minor(体验缺陷但断言未违反)
- 落盘
docs/qa/<日期>-round-N.md(完整矩阵 + 全部证据,温数据)
- gates.md 就地更新(⛔ 禁新开「第 N 轮」章节):
- §一 本轮结论:改写轮次 / 日期 / Verdict / 通过率
- §二 追溯矩阵:逐行更新
A 段与 U 段对应行的 Verdict / 轮次 / 测试位置 / 实测结果
- §三~§五:只留未关闭项,本轮修好的从清单移出(历史在
docs/qa/)
- §六 覆盖率:改写四个分母与覆盖率
- 附录 轮次归档索引:追加 1 行指向本轮
docs/qa/ 报告
gates.md 行数 = 分母(A 条数 + U 条数),不随轮次增长
❹ FIX 轮
派给 dev subagent 的 prompt 骨架
你是修复执行者。只修代码,不改需求。
【必读】
.cc_code/active/prd.md(规则与断言 —— 只读!)
.cc_code/active/ux.md / api.md / project.md / data.md(只读)
【待修 FAIL 清单】
{原样粘贴 Critical Failures,含 Required / Actual / Repro / 涉及文件}
【⛔ 绝对禁止】
✗ 修改 prd.md / ux.md / api.md 的任何一行
✗ 修改或删除测试用例让它变绿
✗ 顺手重构无关代码(扩大爆炸半径 = 引入新 FAIL)
修不动 → 输出 ESCALATE + 说明卡在哪、需要什么决策
【必做】
1. 逐条修,每条对应到 FAIL 编号
2. 新踩的坑写进 commit message(git 天然留痕)
3. 自检:lint → 类型检查 → 单测(命令以 project.md 为准)
4. 回报:修了哪些 / ESCALATE 哪些 / 改动文件清单
回归门 + 收敛检查
修完 ──► ⭐先算范围: codegraph affected <本轮 dev 改动的源文件...>
└─ 空/未装 → 退回「同模块已 PASS 项」并在报告标注来源
│
▼
派 qa subagent 重跑:本轮 FAIL 项 + 上面算出的影响面
│
├─ 新增 FAIL? ──► 停止。报告震荡点 + 建议回滚本轮,交人
├─ FAIL 数未递减? ──► 停止。报告「未收敛」,交人
├─ 轮次 > 3? ──► 停止。标记升级:回 plan-prd-mvp 重规划 或 交人
└─ 递减且 ≤3 轮 ──► 回 ❸ 汇总,继续下一轮
❺ 收口
| 步骤 | 动作 |
|---|
| 1 | gates.md 就地更新:§一 Verdict + §二 矩阵全行 + §六 四分母覆盖率 + §三~五 只留未关闭项 + 附录归档索引 +1 行。⛔ 禁新开轮次章节 |
| 2 | status.md 追加里程碑:YYYY-MM-DD:whole-qa 全量验收 第N轮 PASS,覆盖率 x/y |
| 3 | 向用户报告:四个覆盖率(A / U / 元素 / 接口)、SKIPPED 清单、ESCALATE 清单、轮次消耗 |
| 4 | ⛔ 不报告归档细节(Hook 静默) |
主控行为准则
- 只报结果与决策点,不复述 subagent 的过程日志。
- 进度以
status.md 为准,规则以 prd.md 为准,实测以 gates.md 为准。
- 用
TaskCreate / TaskUpdate 追踪模块级进度,让用户能看到「M3/M7 完成」。
- 任何时候发现自己在写测试代码或改业务代码 —— 停下,那是 subagent 的活。