> For the complete documentation index, see [llms.txt](https://cc-code.rongyeliu.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://cc-code.rongyeliu.com/skills/whole-qa/skill.md).

# 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`） | 无则中止 —— 逐元素点击必须真实浏览器                                                   |

### 启动应用

```bash
# 1. 从 project.md / package.json scripts 找启动命令
# 2. 后台启动（run_in_background: true）
# 3. 轮询端口就绪再继续，不要固定 sleep
# 4. 记下 BASE_URL，传给所有 subagent
```

> 破坏性操作（删除 / 支付 / 发信 / 清库）必须跑在 **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`。主控要做：

1. 合并所有 subagent 结果，按断言 ID（`A` 段）与 `U` 编号（`U` 段）分别排序
2. 算四个覆盖率（`A` 断言 / `U` 五态 / 元素 / 接口），分母用锁定值
3. 列 SKIPPED（每条带原因）
4. 分级 FAIL：Critical（断言直接不达标）/ Minor（体验缺陷但断言未违反）
5. **落盘** `docs/qa/<日期>-round-N.md`（完整矩阵 + 全部证据，温数据）
6. **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 的活**。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://cc-code.rongyeliu.com/skills/whole-qa/skill.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
