code-review
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTwo-axis review of the diff between and a fixed point the user supplies:
HEAD- Standards — does the code conform to this repo's documented coding standards?
- Spec — does the code faithfully implement the originating issue / spec?
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 if is missing.
/setup-matt-pocock-skillsdocs/agents/issue-tracker.md对与用户指定的固定节点之间的代码差异进行双维度审查:
HEAD- 标准维度——代码是否符合本仓库已文档化的编码标准?
- 需求维度——代码是否忠实地实现了原始需求/规格说明书的内容?
两个维度的审查由并行子Agent运行,避免互相干扰上下文,之后由本Skill汇总审查结果。
系统应已为你提供issue tracker——如果缺少,请运行。
docs/agents/issue-tracker.md/setup-matt-pocock-skillsProcess
流程
1. Pin the fixed point
1. 确定固定节点
Whatever the user said is the fixed point — a commit SHA, branch name, tag, , , etc. If they didn't specify one, ask for it.
mainHEAD~5Capture the diff command once: (three-dot, so the comparison is against the merge-base). Also note the list of commits via .
git diff <fixed-point>...HEADgit log <fixed-point>..HEAD --onelineBefore going further, confirm the fixed point resolves () 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>用户提及的任何内容都可作为固定节点——commit SHA、分支名称、tag、、等。如果用户未指定,需向其询问。
mainHEAD~5记录一次差异命令:(三个点,表示基于merge-base进行对比)。同时通过记录提交列表。
git diff <fixed-point>...HEADgit log <fixed-point>..HEAD --oneline在继续下一步前,确认固定节点可解析(运行)且差异内容非空。无效引用或空差异应在此处终止流程——不要进入并行子Agent的运行环节。
git rev-parse <fixed-point>2. Identify the spec source
2. 确定需求来源
Look for the originating spec, in this order:
- Issue references in the commit messages (,
#123, GitLabCloses #45, etc.) — fetch via the workflow in!67.docs/agents/issue-tracker.md - A path the user passed as an argument.
- A spec file under ,
docs/, orspecs/matching the branch name or feature..scratch/ - 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".
按以下顺序查找原始需求:
- 提交信息中的issue引用(如、
#123、GitLab的Closes #45等)——通过!67中的工作流获取。docs/agents/issue-tracker.md - 用户作为参数传入的路径。
- 、
docs/或specs/目录下与分支名称或功能匹配的需求文件。.scratch/ - 如果未找到任何内容,询问用户需求所在位置。若用户表示没有需求,需求维度的子Agent将跳过审查,并报告“无可用需求”。
3. Identify the standards sources
3. 确定标准来源
Anything in the repo that documents how code should be written, such as or .
CODING_STANDARDS.mdCONTRIBUTING.mdOn 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:
- 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.
Each smell reads what it is → how to fix; match it against the 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.
- 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.
- Feature Envy — a method that reaches into another object's data more than its own. → move the method onto the data it envies.
- Data Clumps — the same few fields or params keep travelling together (a type wanting to be born). → bundle them into one type, pass that.
- Primitive Obsession — a primitive or string standing in for a domain concept that deserves its own type. → give the concept its own small type.
- Repeated Switches — the same /
switch-cascade on the same type recurs across the change. → replace with polymorphism, or one map both sites share.if - Shotgun Surgery — one logical change forces scattered edits across many files in the diff. → gather what changes together into one module.
- Divergent Change — one file or module is edited for several unrelated reasons. → split so each module changes for one reason.
- Speculative Generality — abstraction, parameters, or hooks added for needs the spec doesn't have. → delete it; inline back until a real need shows.
- Message Chains — long navigation the caller shouldn't depend on. → hide the walk behind one method on the first object.
a.b().c().d() - Middle Man — a class or function that mostly just delegates onward. → cut it, call the real target direct.
- Refused Bequest — a subclass or implementer that ignores or overrides most of what it inherits. → drop the inheritance, use composition.
仓库中所有记录代码编写规范的文件,例如或。
CODING_STANDARDS.mdCONTRIBUTING.md除了仓库中已文档化的标准外,标准维度始终遵循以下代码异味基准——这是一组固定的Fowler代码异味(来自《Refactoring》第3章),即使仓库没有任何文档化标准也适用。该基准遵循两条规则:
- 仓库标准优先:仓库中已文档化的标准始终优先;如果仓库标准认可某一内容,而基准将其标记为异味,则忽略该异味。
- 始终需主观判断:每个异味都是带标签的启发式判断(如“可能存在Feature Envy”),而非硬性违规——并且,与这里的任何标准一样,跳过已由工具强制执行的内容。
每个异味都包含“是什么”→“如何修复”的说明,需与代码差异进行匹配:
- Mysterious Name(晦涩命名)——函数、变量或类型的名称无法体现其功能或用途。→ 重命名;如果找不到合适的名称,说明设计存在模糊性。
- Duplicated Code(重复代码)——相同的逻辑结构出现在变更中的多个代码块或文件中。→ 提取共享逻辑,在两处调用该逻辑。
- Feature Envy(特性羡慕)——某个方法更多地访问其他对象的数据,而非自身数据。→ 将该方法移至它所访问的数据所属的对象中。
- Data Clumps(数据泥团)——相同的几个字段或参数总是一起出现(意味着需要创建一个新类型)。→ 将它们打包成一个类型,传递该类型。
- Primitive Obsession(原始类型痴迷)——使用原始类型或字符串来代表本应拥有独立类型的领域概念。→ 为该概念创建一个独立的小型类型。
- Repeated Switches(重复分支)——针对同一类型的相同/
switch分支结构在变更中多次出现。→ 用多态替换,或使用一个两处共享的映射。if - Shotgun Surgery(霰弹式修改)——一项逻辑变更需要对差异中的多个文件进行零散修改。→ 将相关变更整合到一个模块中。
- Divergent Change(发散式修改)——一个文件或模块因多个不相关的原因被修改。→ 拆分该模块,使每个模块仅因一个原因变更。
- Speculative Generality(过度抽象)——为需求中不存在的场景添加了抽象、参数或钩子。→ 删除这些内容;直到有实际需求时再重新添加。
- Message Chains(消息链)——过长的链式调用,调用者不应依赖这种导航方式。→ 在第一个对象上添加一个方法,隐藏链式调用过程。
a.b().c().d() - Middle Man(中间人)——某个类或函数主要仅负责转发调用。→ 删除它,直接调用实际目标。
- Refused Bequest(拒绝继承)——子类或实现类忽略或覆盖了大部分继承的内容。→ 放弃继承,使用组合。
4. Spawn both sub-agents in parallel
4. 并行启动两个子Agent
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."
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."
If the spec is missing, skip the Spec sub-agent and note this in the final report.
标准维度子Agent提示词——需包含:
- 完整的差异命令和提交列表。
- 步骤3中找到的标准源文件列表,加上步骤3中的代码异味基准完整内容——子Agent无法访问其他外部内容。
- 任务说明:“报告——针对相关的文件/代码块——(a) 差异中所有违反已文档化标准的位置:引用标准(文件+规则);(b) 你发现的任何基准异味:命名异味并引用代码块。区分硬性违规与主观判断——违反已文档化标准属于硬性违规,但基准异味始终是主观判断,且仓库已文档化的标准优先于基准。跳过已由工具强制执行的内容。报告字数不超过400字。”
需求维度子Agent提示词——需包含:
- 差异命令和提交列表。
- 需求文件的路径或获取到的内容。
- 任务说明:“报告:(a) 需求中要求但未实现或部分实现的内容;(b) 差异中存在但未在需求中提及的行为(范围蔓延);(c) 看似已实现但存在错误的需求。每个发现需引用需求中的对应行。报告字数不超过400字。”
如果缺少需求文件,跳过需求维度子Agent,并在最终报告中注明这一点。
5. Aggregate
5. 汇总结果
Present the two reports under and headings, verbatim or lightly cleaned. Do not merge or rerank findings — the two axes are deliberately separate (see Why two axes).
## Standards## SpecEnd 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.
Reporting them separately stops one axis from masking the other.
一项代码变更可能通过其中一个维度的审查,但未通过另一个:
- 代码遵循所有标准,但实现了错误的功能 → 标准维度通过,需求维度未通过。
- 代码完全符合需求,但违反了项目约定 → 需求维度通过,标准维度未通过。
分开报告两个维度的结果,可以避免一个维度的结果掩盖另一个维度的问题。