# Audit Agent（流程文档）

> 本文件由主 agent 在阶段 3 入口 Read 后按其流程执行,**不是独立 subagent**。Claude Code skill 内嵌的 `r/*.md` 不会被加载为可调用 subagent。

阶段 3 入口。三个职责:

1. **完整性审计**:校验所有 [a01.txt](../a01.txt) G5 条件
2. **系统级审计**:独立执行 CORS / 响应头 / 调试端点等系统级检查
3. **报告**:校验通过后直接生成 docx 报告(主体是"每个功能测了哪些威胁")

---

## 审计流程

1. Read `module_queue.json` — 确认 `module_queue` 为空,所有模块移入 `tested_modules`
2. Read 所有 `modules/*.json`,执行校验:

   - 每个 feature 的 `threat_model` 所有项,在 `validation_results.tests[]` 中都有对应 `threat_id` 且 `status !== null`?
   - 每个模块的 `cross_role_verification.tested=true`？（`role_pairs_tested` 可为空数组，无越权面的模块不受此限制，见 a01.txt G4）
   - `confirmed` 漏洞含完整 `request_response` + `access_path`?
   - **每个 feature 有非空 `coverage_note`(三问);每条 `not_vulnerable` 有非空 `unruled_out`**(G2)。这是反遗漏的最终账,缺一项即列入缺口
   - **`js_analysis.channels_covered` 含全部六渠道**(G7)。某渠道缺 → 列入缺口

3. 生成 `coverage.json`:

   - `features_summary` 段:遍历所有 module × feature,从 `threat_model` + `validation_results` 推导
   - `system_audits` 段:**Audit Agent 自行执行系统级审计**,不读 modules/*.json。逐项检查 CORS / SecurityHeaders / DebugEndpoints / VersionLeak / ConsoleLeak / WAF
   - 配置类观察（CORS 宽松、安全响应头缺失等）**禁止计入 `summary.json.confirmed_vulns`**，不出现在报告第 5 节漏洞详情，不分配 VULN 编号，仅在第 3 节系统级审计列出
   - `blindspots` 段:汇总所有 `blocked` 状态 + 跨角色降级 NEEDS
   - `page_coverage` 段:从 `pages.json` 汇总——`pages_total`/`pages_visited`、`functions_total`/`functions_triggered`、`untriggered[]`。任一未触发且无 BLOCKED 说明 → G6 不过,回跳 Attack。

4. 校验 a01.txt G5 所有项(含 G6 页面功能覆盖,见 a01.txt)

**任一项不满足** → 输出缺口报告,回跳 Attack Agent 补测。

### 缺口报告格式

```markdown
# Audit Gate — 测试完整性缺口报告

## Threat Model 未覆盖项

| 模块 | Feature | Threat ID | 威胁类型 | 缺失原因 |
|------|---------|-----------|---------|---------|
| 用户管理 | user_edit_001 | T2 | 垂直越权-普通用户访问管理接口 | validation_results 中无对应 test |

## 系统级审计未完成项

| 项目 | 状态 | 需要的操作 |
|------|------|-----------|
| DebugEndpoints | blocked | WAF 拦截探测请求 |

## 反遗漏缺口(G2 / G7)

| 类型 | 缺口 | 需要的操作 |
|------|------|-----------|
| G2 coverage_note | user/search_001 的 coverage_note 三问只答了两问 | 回 Attack 补全 |
| G2 unruled_out | T3(not_vulnerable,SQL注入)无 unruled_out | 回 Attack 列未排除面或重新测 |
| G7 渠道 | channels_covered 缺 inline_script(profile 页内联脚本未解析) | 回 Discovery 补 |

> 结论:N 个缺口,回跳 Attack/Discovery 补测后重新审计。
```

---

## coverage.json features_summary 推导规则

对每个 feature:

- `threats_total` = `threat_model.length`
- `threats_tested` = `validation_results[本 feature].tests[]` 中 `threat_id` 能对得上 `threat_model` 的数量
- `results[]` 每项 = `{threat_id, vuln_type, status, vuln_id?(仅 confirmed)}`
- 若 `threats_total === 0`,加 `note` 字段说明为什么没有威胁面(纯展示、无外部输入、无状态变更 等)

`confirmed` 项的 `vuln_id` 从 summary.json 的 `confirmed_vulns[]` 反向查(同 feature_id + 同 vuln_type)。

`system_audits` 段每项 `status` 用 `audited` / `blocked` / `not_applicable`,`result` 写具体发现。`blocked` 的项自动进 `blindspots`。
