← 技能图谱
namecode-review
descriptionReview the changes since a fixed point (commit, branch, tag, or merge-base) along two axes — Standards (does the code follow this repo's documented coding standards?) and Spec (does the code match what the originating issue/PRD asked for?). Runs both reviews in parallel sub-agents and reports them side by side. Use when the user wants to review a branch, a PR, work-in-progress changes, or asks to "review since X".
触发词沿两条轴线审查自某个固定点(提交、分支、标签或合并基点)以来的变更——规范轴(代码是否遵循该仓库的已记录编码规范?)和规格轴(代码是否匹配原始 issue/PRD 的要求?)。在两个并行子代理中分别运行这两条审查,并排报告结果。当用户想要审查分支、PR、进行中的变更,或要求"审查自某点以来的变更"时使用。

code-review

Review the changes since a fixed point (commit, branch, tag, or merge-base) along two axes — Standards (does the code follow this repo's documented coding standards?) and Spec (does the code match what the originating issue/PRD asked for?). Runs both reviews in parallel sub-agents and reports them side by side. Use when the user wants to review a branch, a PR, work-in-progress changes, or asks to "review since X".

Two-axis review of the diff between HEAD and a fixed point the user supplies:

HEAD 与用户提供的固定点之间 diff 的双轴审查:

  • Standards — does the code conform to this repo's documented coding standards?
  • Spec — does the code faithfully implement the originating issue / PRD / spec?
  • 规范(Standards) — 代码是否遵循该仓库的已记录编码规范?
  • 规格(Spec) — 代码是否忠实地实现了原始 issue / PRD / 规格说明?

Both axes run as parallel sub-agents so they don't pollute each other's context, then this skill aggregates their findings.

两条轴线以并行的子代理运行,以免互相污染上下文,随后该技能汇总它们的发现。

The issue tracker should have been provided to you — run /setup-matt-pocock-skills if docs/agents/issue-tracker.md is missing.

Issue 跟踪器应已提供给你——如果 docs/agents/issue-tracker.md 缺失,请运行 /setup-matt-pocock-skills

Process

流程

1. Pin the fixed point

1. 固定参考点

Whatever the user said is the fixed point — a commit SHA, branch name, tag, main, HEAD~5, etc. If they didn't specify one, ask for it.

用户所说的任何内容即为固定点——一个提交 SHA、分支名、标签、mainHEAD~5 等。如果用户没有指定,请询问。

Capture the diff command once: git diff <fixed-point>...HEAD (three-dot, so the comparison is against the merge-base). Also note the list of commits via git log <fixed-point>..HEAD --oneline.

记录 diff 命令:git diff <fixed-point>...HEAD(三点,因此比较针对合并基点)。同时通过 git log <fixed-point>..HEAD --oneline 记下提交列表。

Before going further, confirm the fixed point resolves (git rev-parse <fixed-point>) and the diff is non-empty. A bad ref or empty diff should fail here — not inside two parallel sub-agents.

在继续之前,确认固定点可解析(git rev-parse <fixed-point>)且 diff 非空。无效引用或空 diff 应在此处失败——而不是在两个并行子代理内部。

2. Identify the spec source

2. 确定规格来源

Look for the originating spec, in this order:

按以下顺序查找原始规格说明:

  1. Issue references in the commit messages (#123, Closes #45, GitLab !67, etc.) — fetch via the workflow in docs/agents/issue-tracker.md.
  2. A path the user passed as an argument.
  3. A PRD/spec file under docs/, specs/, or .scratch/ matching the branch name or feature.
  4. If nothing is found, ask the user where the spec is. If they say there isn't one, the Spec sub-agent will skip and report "no spec available".
  1. 提交信息中的 Issue 引用(#123Closes #45、GitLab !67 等)——通过 docs/agents/issue-tracker.md 中的工作流获取。
  2. 用户通过参数传递的路径。
  3. docs/specs/.scratch/ 下匹配分支名或功能名的 PRD/规格文件。
  4. 若未找到,询问用户规格在哪里。若用户表示没有规格,则规格子代理将跳过并在报告中注明"无可用规格"。

3. Identify the standards sources

3. 确定规范来源

Anything in the repo that documents how code should be written, such as CODING_STANDARDS.md or CONTRIBUTING.md.

仓库中任何记录了代码应如何编写的文件,如 CODING_STANDARDS.mdCONTRIBUTING.md

On top of whatever the repo documents, the Standards axis always carries the smell baseline below — a fixed set of Fowler code smells (Refactoring, ch.3) that applies even when a repo documents nothing. Two rules bind it:

在仓库已记录的内容之上,规范轴始终附带以下坏味道基线——一组固定的 Fowler 代码坏味道(Refactoring 第 3 章),即使仓库没有任何文档也同样适用。两条规则约束它:

  • The repo overrides. A documented repo standard always wins; where it endorses something the baseline would flag, suppress the smell.
  • Always a judgement call. Each smell is a labelled heuristic ("possible Feature Envy"), never a hard violation — and, like any standard here, skip anything tooling already enforces.
  • 仓库优先。 已记录的仓库标准始终胜出;若其认可了基线会标记的内容,则压制该坏味道。
  • 始终是判断性调用。 每种坏味道是一个带有标签的启发式判断(如"可能的 Feature Envy"),而非硬性违规——与本处所有标准一样,跳过工具已强制检查的内容。

Each smell reads what it ishow to fix; match it against the diff:

每种坏味道按是什么如何修复的格式;将其与 diff 对照匹配:

Mysterious Name — a function, variable, or type whose name doesn't reveal what it does or holds. → rename it; if no honest name comes, the design's murky.

Mysterious Name — 函数、变量或类型的名称未能揭示其功能或含义。→ 重命名;若找不到诚实的名称,说明设计不清晰。

Duplicated Code — the same logic shape appears in more than one hunk or file in the change. → extract the shared shape, call it from both.

Duplicated Code — 同一段逻辑结构在变更中的多个代码块或文件中重复出现。→ 提取共享结构,从两处调用它。

Feature Envy — a method that reaches into another object's data more than its own. → move the method onto the data it envies.

Feature Envy — 方法访问另一个对象的数据比访问自己的还多。→ 将该方法移到它所"嫉妒"的数据上。

Data Clumps — the same few fields or params keep travelling together (a type wanting to be born). → bundle them into one type, pass that.

Data Clumps — 相同的几个字段或参数总是结伴出现(一个渴望诞生的类型)。→ 将它们打包成一个类型,传递该类型。

Primitive Obsession — a primitive or string standing in for a domain concept that deserves its own type. → give the concept its own small type.

Primitive Obsession — 使用基本类型或字符串来代表本应拥有专属类型的领域概念。→ 给该概念一个独立的小类型。

Repeated Switches — the same switch/if-cascade on the same type recurs across the change. → replace with polymorphism, or one map both sites share.

Repeated Switches — 变更中反复出现针对同一类型的相同 switch/if 级联。→ 用多态替换,或使用两处共享的同一映射表。

Shotgun Surgery — one logical change forces scattered edits across many files in the diff. → gather what changes together into one module.

Shotgun Surgery — 一个逻辑变更迫使 diff 中许多文件散落修改。→ 将一起变更的内容聚集到一个模块中。

Divergent Change — one file or module is edited for several unrelated reasons. → split so each module changes for one reason.

Divergent Change — 一个文件或模块因多种不相关的原因而被修改。→ 拆分,使每个模块只因一种原因而变更。

Speculative Generality — abstraction, parameters, or hooks added for needs the spec doesn't have. → delete it; inline back until a real need shows.

Speculative Generality — 为规格说明中不存在的需求而添加的抽象、参数或钩子。→ 删除它;内联回去,直到真实需求出现。

Message Chains — long a.b().c().d() navigation the caller shouldn't depend on. → hide the walk behind one method on the first object.

Message Chains — 调用方不应依赖的过长 a.b().c().d() 链条式导航。→ 将遍历隐藏到第一个对象的一个方法中。

Middle Man — a class or function that mostly just delegates onward. → cut it, call the real target direct.

Middle Man — 一个主要只是向下委托的类或函数。→ 去掉它,直接调用真正的目标。

Refused Bequest — a subclass or implementer that ignores or overrides most of what it inherits. → drop the inheritance, use composition.

Refused Bequest — 子类或实现者忽略或覆写了其继承的大部分内容。→ 放弃继承,改用组合。

4. Spawn both sub-agents in parallel

4. 并行启动两个子代理

Send a single message with two Agent tool calls. Use the general-purpose subagent for both.

发送一条包含两个 Agent 工具调用的消息。两个都使用 general-purpose 子代理。

Standards sub-agent prompt — include:

规范子代理提示 — 包含:

  • The full diff command and commit list.
  • The list of standards-source files you found in step 3, plus the smell baseline from step 3 pasted in full — the sub-agent has no other access to it.
  • The brief: "Report — per file/hunk where relevant — (a) every place the diff violates a documented standard: cite the standard (file + the rule); and (b) any baseline smell you spot: name it and quote the hunk. Distinguish hard violations from judgement calls — documented-standard breaches can be hard, but baseline smells are always judgement calls, and a documented repo standard overrides the baseline. Skip anything tooling enforces. Under 400 words."
  • 完整的 diff 命令和提交列表。
  • 你在步骤 3 中找到的规范来源文件列表,以及步骤 3 中的坏味道基线完整粘贴——子代理无法自行获取。
  • 指令:"报告——按相关文件/代码块——(a) diff 中每处违反已记录标准的地方:引用标准(文件 + 规则);(b) 你发现的任何基线坏味道:命名它并引用代码块。区分硬性违规与判断性调用——违反已记录标准可以是硬性的,但基线坏味道始终是判断性调用,且已记录的仓库标准优先于基线。跳过工具已强制检查的内容。不超过 400 字。"

Spec sub-agent prompt — include:

规格子代理提示 — 包含:

  • The diff command and commit list.
  • The path or fetched contents of the spec.
  • The brief: "Report: (a) requirements the spec asked for that are missing or partial; (b) behaviour in the diff that wasn't asked for (scope creep); (c) requirements that look implemented but where the implementation looks wrong. Quote the spec line for each finding. Under 400 words."
  • diff 命令和提交列表。
  • 规格说明的路径或获取到的内容。
  • 指令:"报告:(a) 规格说明要求但缺失或不完整的需求;(b) diff 中未经要求的行为(范围蔓延);(c) 看似已实现但实现看起来有问题的需求。对每条发现引用规格说明原文。不超过 400 字。"

If the spec is missing, skip the Spec sub-agent and note this in the final report.

如果规格说明缺失,跳过规格子代理并在最终报告中注明。

5. Aggregate

5. 汇总

Present the two reports under ## Standards and ## Spec headings, verbatim or lightly cleaned. Do not merge or rerank findings — the two axes are deliberately separate (see Why two axes).

## Standards## Spec 两个标题下呈现两份报告,逐字引用或稍加清理。不要合并或重新排序发现——两条轴线是有意分开的(参见为何分两条轴线)。

End with a one-line summary: total findings per axis, and the worst issue within each axis (if any). Don't pick a single winner across axes — that's the reranking the separation exists to prevent.

以一行摘要结束:每条轴线的发现总数,以及每条轴线的最严重问题(如有)。不要在轴线之间选出单一最严重问题——这正是分开所要防止的重新排序。

Why two axes

为何分两条轴线

A change can pass one axis and fail the other:

一项变更可能通过一条轴线而失败于另一条:

  • Code that follows every standard but implements the wrong thing → Standards pass, Spec fail.
  • Code that does exactly what the issue asked but breaks the project's conventions → Spec pass, Standards fail.
  • 遵循所有规范却实现了错误内容的代码 → 规范通过,规格失败。
  • 完全按 issue 要求实现却违反项目约定的代码 → 规格通过,规范失败。

Reporting them separately stops one axis from masking the other.

分开报告可防止一条轴线掩盖另一条。