code-review-zh · git:20261101.11b8bb9 · 2026-11-01 · sha256 d29e7554ca8dd2ce

code-review-zh git:20261101.11b8bb9A

Immutable. This exact content never changes and is served at /api/v1/blob/d29e7554ca8dd2ce.

---
name: code-review-zh
description: 写完代码、提交前或合并 PR 时使用;用户说“帮我 review”“提交前检查一下”“看看这次改动”“PR review”,或要求严格审查/合入门禁时也使用。
---

# 代码审查

> 检查代码缺陷、测试质量和变更影响,并确认已发现的问题是否闭环。

## 资源与执行位置

- `references/`、`scripts/`、`assets/` 均相对本次读取的 `SKILL.md` 所在目录。
- shell 命令从**被审项目根目录**执行;`docs/work/`、代码路径与项目规则均属于被审项目。
- 下文的 `CODE_REVIEW_SKILL_DIR` 指 skill 安装目录的绝对路径。每次 shell 调用都设置它,
  或直接用实际绝对路径替换;不要假定不同 shell 调用会保留变量。
- 脚本需要 Bash、Git、awk、grep、sed 等基础命令。通过 `bash` 调用,无需依赖可执行位。
- 报告解析需要 Python 3.9+ 和 PyYAML;默认调用 `python`,可用 `CODE_REVIEW_PYTHON` 指定解释器绝对路径。
  安装方式见发布仓库 README;仓库内入口为 `scripts/install.py`。

## 适用范围

- 审查影响代码行为的功能、bug 修复、重构或配置变更。
- 不影响代码行为的纯文档、格式或错别字改动可跳过。
- 测试失败或尚未运行时仍可静态审查;报告须注明测试状态,不得宣称已满足合入条件。

## 输入

| 输入 | 必需 | 说明 |
|---|---|---|
| git 仓库 + 可 diff 的改动 | 是 | 明确审查未提交改动,还是已提交的 base/head 区间 |
| 验收标准 | 否 | 提供时按“可选收尾”逐条勾验 |
| 覆盖率数据 / 命令 | 否 | 提供时用于 `test-coverage` 的可选测量;未提供时仍执行相关测试代码的静态质量检查 |
| 规则包 | 否 | 默认 skill 内置 `references/rules/`;可用 `CODE_REVIEW_RULES_DIR` 覆盖 |
| 审查标识 | 否 | `{slug}`,默认 `<日期>-<主题>` |

产物根目录为 `docs/work`,本次产物写入 `docs/work/active/{slug}/`。

## 审查流程

> 检查项不写死在本文件里,由 `references/probes.yaml` 注册表驱动。
> 探针的实现细节在 `references/probes/<探针名>.md`;本文件只管**编排**。
>
> **执行边界:默认进行静态审查。** 覆盖率检查优先复用已有报告;
> 需要测量时,可在本轮任务允许的范围内执行覆盖率命令。其他检查仍只读证据。
> 审查过程中不得修改被审源代码。测试与 CI 输出作为审查证据,
> **测试全绿不等于行为正确**。

1. **确定审查范围**:

   **选择模式**,未指定时默认审查未提交改动。下文的 base/head 均记录为具体 commit ID。

   - **未提交改动(worktree)**:base 为当前 HEAD。
     用 `git diff <base> --` 收集暂存与未暂存改动;
     用 `git ls-files --others --exclude-standard -z` 收集未跟踪文件,
     并将其完整内容作为新增代码审查。
   - **已提交区间(commits)**:按用户指定的 base/head,
     用 `git diff <base> <head> --` 收集差异。
     省略 head 时使用当前 HEAD,只审查该提交区间。

   **读取对应源码**:
   - worktree 模式读取工作区文件。
   - commits 模式用 `git show <head>:<路径>` 读取目标版本,
     需要旧版本时读取 base。文件扫描仅使用与目标版本一致的磁盘文件。

   **记录并交接**:保存模式、base、目标(工作区或 head)、变更文件清单及差异,
   供所有探针使用。程序处理文件清单时使用 NUL 分隔,并逐路径引用传参。

   收集完成后,再创建报告目录 `docs/work/active/{slug}/probes/`,
   避免将新生成的报告纳入待审查文件。

2. **读注册表,确定探针清单**:Read `references/probes.yaml`,按 `requires` 判断:
   - 指定了但缺失 / 不可读 → `error`
   - 未提供可选输入 → `skipped`,写明缺什么
   - 可用 → 执行

3. **并行执行探针**:

   **派发**:主执行器按注册表为每个探针派发独立代理,提供审查范围、diff、项目根、skill 路径及该探针的输入和 `params`,并在派发提示中包含上文“执行边界”和本步骤“执行”段的公共约束。
   代理读取注册项 `file` 指向的说明和 `references/output-schema.md`,按参数执行。
   并发槽位不足时分批执行;没有独立代理能力时串行执行并记录限制。

   **执行**:代理只检查自己的探针,不重跑完整流程或再派发代理;源码版本遵循步骤 1。
   finding 须说明本次改动如何引入或触发该问题;无关的存量问题单独说明,不纳入本轮 finding 清单及计数。
   复用已读上下文,仅按需补读;独立只读查询尽量合并,有依赖的查询逐步执行,首次读取源码时保留准确行号和必要上下文。
   本地搜索限于被审仓库、明确提供的关联目录及依赖坐标对应的缓存路径;缺失或不可读时记录具体证据缺口,
   不扩大到磁盘根目录或用户目录,也不在没有新线索时反复搜索。
   只写 `docs/work/active/{slug}/probes/<探针名>.json`,不写共享报告或指标。
   返回前须等待自己启动的后台任务结束,或停止已不再需要的任务并确认退出,再通知完成。

   **交接**:每个探针均须有 JSON,错误或跳过时写明原因;执行错误时保留已发现问题,其他探针继续。
   返回消息简要说明 JSON 路径、实际检查范围、未验证项及具体证据缺口,不重复抄写 findings;主执行器将相关限制纳入最终报告。
   代理启动失败或未返回有效结果时,由主执行器记录 `error` 及原因,不沿用该探针的旧结果。
   有可靠计时时记录 `duration`,各探针耗时之和不代表本轮墙钟时间。
   `test-coverage` 通过返回消息交接有效覆盖率的报告路径、目标版本、分子/分母及百分比,
   由主执行器执行 `collect-metrics coverage`;未测量时不补数值。

   **汇总**:等待所有代理结束,由主执行器统一同步;`required` 从注册表读取,各级数量从 JSON 逐条计算,不改写原始结果或手填计数。
   暂不做跨探针去重,按原始 finding ID 计数,可能包含同根因问题的重复记录:
   ```bash
   bash "$CODE_REVIEW_SKILL_DIR/scripts/collect-metrics" sync {slug} --probes
   ```
   此步使上一批对账状态失效,尚不记录 reconciliation。
   历史重复记录保留原始 ID、证据及计数;展示独立问题数量时按同一根因和后果归组并列明对应 ID,不因重复提高严重级别,也不以展示数量替代探针或对账计数。

4. **reconciliation 完整性检查**:
   从探针 JSON 自动派生最终计数:
   ```bash
   bash "$CODE_REVIEW_SKILL_DIR/scripts/collect-metrics" sync {slug}
   ```
   `required` 只控制该探针的 `failed/error` 执行状态是否直接阻塞,不改变 finding 的闭环要求。
   任意探针的 high finding 都进入 reconciliation,未闭环仍阻塞合入;medium/low 记入报告,不计入对账总数:
   ```text
   RECONCILE_TOTAL   = high finding 总数
   RECONCILE_DONE    = 其中 status 为 reconciled 或 false-positive 的条数
   RECONCILE_PENDING = TOTAL - DONE
   ```
   没有 high 也须执行,显式记录零结果,不能用旧计数或手填数字代替。
   格式错误须先修正;记录缺失、重复 ID 或状态矛盾时同步失败,不写计数,不以旧结果放行。
   有未处置问题(`RECONCILE_PENDING > 0`)时,本轮仍交付报告并列明阻塞项,不得推进合入。
   后续修复任务完成后,再复审受影响的部分;重派上限见 `references/probes.yaml` 的 `execution.max_retry`。

5. **汇总报告**:

   按模板填写审查范围、解释、修复建议和限制,原始 JSON 不嵌入正文;提供了验收标准时,先完成逐条勾验。

   执行以下命令,从 JSON 生成报告事实区、校验展示并取得最终答复摘要:
   ```bash
   bash "$CODE_REVIEW_SKILL_DIR/scripts/collect-metrics" render-report {slug}
   bash "$CODE_REVIEW_SKILL_DIR/scripts/collect-metrics" verify-report {slug}
   bash "$CODE_REVIEW_SKILL_DIR/scripts/collect-metrics" summary {slug}
   ```

   脚本只更新报告 §5、§6 的 `code-review:probes` / `gate` 标记区域,保留其他正文和原始 JSON。渲染先校验再原子更新,可重复执行;标记缺失或重复时停止。校验覆盖 ID、位置、证据、严重级别、状态和计数。

   `summary` 先校验报告,一致后才输出机器摘要。最终答复中的 high/medium/low 数量、finding ID 和阻塞结论须以摘要为准,不新增未记录的问题,不遗漏已记录的 high。向用户交付报告、阻塞项及未验证内容,可补充解释和建议,不得改写自动区域或推翻已知阻塞事实。

   “无已记录阻塞项”不代表验收、覆盖率、测试或 CI 已通过。`gate-pass {slug} code-review` 与有审查记录的 `archive` 均先校验报告,再同步计数,不自动修正被改写的展示。

## <HARD-GATE>

**以下任一条件命中,阻塞合入**。本轮报告列明阻塞项,下表为后续处置要求:

| 阻塞条件 | 后续动作 |
|---|---|
| required 探针为 `failed` / `error`(`PROBE_REQUIRED_FAILED > 0`) | 处理已发现的问题或执行错误后,重跑对应探针 |
| high finding 未完成 reconciliation(`RECONCILE_PENDING > 0`) | 按步骤 4 处理,修复后重派受影响的探针 |
| reconcile 从未上报(`RECONCILE_REPORTED=0`) | 完成步骤 4;没有 high 也须执行最终同步 |
| 提供了覆盖率数据且低于基线(默认增量行覆盖率 < 85%) | 列明覆盖缺口,补测试后重新审查 |
| 提供了验收标准且未全过,或标准本身有歧义 | 列明未通过项;有歧义先澄清,不得自行勾验通过 |
| 有 high finding 停在 `wontfix` | 按输出契约完成处置,不能用“不修”冲抵待办 |

执行状态与输入错误的判定见 `references/output-schema.md` 第 4 节。

脚本验证报告记录与计数的一致性,不能证明检查是否充分。

## 输出契约

- **主报告**:`docs/work/active/{slug}/code-review.md`,按
  `assets/code-review.md` 的章节和填写要求生成。
- **机器记录**:`docs/work/active/{slug}/probes/<探针名>.json`,
  格式见 `references/output-schema.md`;人类报告的事实区域由它们派生。

历史记录须明确迁移为独立 JSON;不从自由文本猜测或自动补零,也不同时读取旧内嵌区块。

## 可选收尾

以下事项按条件执行,不作为每轮必经步骤:

- **验收**:提供了验收标准时,在最终结论前逐条勾验;没有则跳过并说明。
- **lessons**:有 `lessons/` 目录,且本次有实际发生、值得复用的经验时记录,说明具体问题、原因和处理方式:
  - 实现过程中踩的坑 → `lessons/pitfalls.md`
  - AI 产出被纠正的案例 → `lessons/bad-cases.md`
  - 新的架构决策 → `lessons/arch-decisions.md`
- **归档**:如需归档,将 `docs/work/active/{slug}/` 移到 `docs/work/archive/{YYYY}/`。