用途
该技能用于对代码变更做双轴审查。审查对象是 HEAD 与用户提供的固定点(commit SHA、分支名、标签、main、HEAD~5 等)之间的 diff。两个审查轴分别是:
- 标准(Standards):代码是否符合本仓库文档化的编码标准。
- 规格(Spec):代码是否忠实实现了来源 issue / 规格。
两个轴作为并行子智能体运行,避免互相污染上下文,随后由本技能汇总它们的发现。
前置条件
issue 跟踪器应已提供。如果缺少 docs/agents/issue-tracker.md,需告知用户运行 /setup-matt-pocock-skills。
使用方式
1. 固定固定点
用户所说的固定点即为固定点(commit SHA、分支名、标签、main、HEAD~5 等)。如果用户未指定,需要询问。
一次性捕获 diff 命令:git diff <fixed-point>...HEAD(三点,因此是与 merge-base 比较)。同时通过 git log <fixed-point>..HEAD --oneline 记录提交列表。
继续之前,确认固定点可解析(git rev-parse <fixed-point>)且 diff 非空。错误的 ref 或空 diff 应在此处失败,而不是在两个并行子智能体内部失败。
2. 识别规格来源
按以下顺序查找来源规格:
- 提交消息中的 issue 引用(#123、Closes #45、GitLab !67 等),通过 docs/agents/issue-tracker.md 中的工作流获取。
- 用户作为参数传入的路径。
- docs/、specs/ 或 .scratch/ 下与分支名或功能匹配的规格文件。
如果找不到,询问用户规格在哪里。如果用户说没有,Spec 子智能体将跳过并报告“no spec available”。
3. 识别标准来源
仓库中任何记录代码应如何编写的文件,例如 CODING_STANDARDS.md 或 CONTRIBUTING.md。
在仓库文档化的内容之上,标准轴始终携带以下坏味道基线:一组固定的 Fowler 代码坏味道(《重构》第 3 章),即使仓库没有记录任何内容也适用。两条规则约束它:
- 仓库优先。文档化的仓库标准始终胜出;当它认可基线会标记的内容时,抑制该坏味道。
- 始终是判断性判断。每个坏味道都是带标签的启发式(“possible Feature Envy”),绝不是硬性违规。与这里的任何标准一样,跳过工具已强制执行的任何内容。
每个坏味道的读法为“它是什么 → 如何修复”;将其与 diff 匹配:
- Mysterious Name:函数、变量或类型的名称没有揭示其作用或持有内容。→ 重命名;如果找不到诚实的名字,说明设计模糊。
- Duplicated Code:相同的逻辑形态出现在变更中的多个 hunk 或文件中。→ 提取共享形态,从两处调用。
- Feature Envy:方法访问另一个对象的数据多于自身数据。→ 将方法移到它所羡慕的数据上。
- Data Clumps:相同的几个字段或参数总是结伴出现(一个想要诞生的类型)。→ 将它们打包成一个类型并传递该类型。
- Primitive Obsession:用原始类型或字符串代替值得拥有自己类型的领域概念。→ 给该概念一个小类型。
- Repeated Switches:对同一类型的相同 switch/if 级联在变更中反复出现。→ 用多态替换,或两处共享一个映射。
- Shotgun Surgery:一个逻辑变更迫使 diff 中许多文件分散编辑。→ 将一起变化的内容聚集到一个模块。
- Divergent Change:一个文件或模块因多个不相关原因被编辑。→ 拆分,使每个模块只因一个原因变化。
- Speculative Generality:为规格没有的需求添加抽象、参数或钩子。→ 删除它;内联回去,直到出现真实需求。
- Message Chains:调用方不应依赖的长 a.b().c().d() 导航。→ 将遍历隐藏在第一个对象的一个方法后面。
- Middle Man:一个类或函数主要只是向下委托。→ 删掉它,直接调用真实目标。
- Refused Bequest:子类或实现者忽略或覆盖了它继承的大部分内容。→ 放弃继承,使用组合。
4. 并行生成两个子智能体
Standards 子智能体提示应包含:
- 完整的 diff 命令和提交列表。
- 第 3 步找到的标准来源文件列表,以及第 3 步的坏味道基线全文粘贴(子智能体没有其他途径访问它)。
- 简报:“按文件/hunk 报告相关处:(a) diff 违反文档化标准的每一处:引用标准(文件 + 规则);(b) 你发现的任何基线坏味道:命名并引用该 hunk。区分硬性违规与判断性判断:文档化标准的违反可以是硬性的,但基线坏味道始终是判断性判断,且文档化的仓库标准优先于基线。跳过工具已强制执行的任何内容。400 字以内。”
Spec 子智能体提示应包含:
- diff 命令和提交列表。
- 规格的路径或获取到的内容。
- 简报:“报告:(a) 规格要求但缺失或不完整的需求;(b) diff 中未被要求的行为(范围蔓延);(c) 看起来已实现但实现有误的需求。为每项发现引用规格行。400 字以内。”
如果规格缺失,跳过 Spec 子智能体并在最终报告中注明。
5. 汇总
在 ## Standards 和 ## Spec 标题下呈现两份报告,逐字或轻度清理。不要合并或重新排序发现,因为两个轴是刻意分开的(见“为什么是两个轴”)。
最后以一行摘要结束:每个轴的发现总数,以及每个轴内最严重的问题(如有)。不要跨轴选出一个赢家:那正是分离所要防止的重新排序。
为什么是两个轴
一个变更可能通过一个轴而失败于另一个轴:
- 遵循所有标准但实现了错误内容的代码 → 标准通过,规格失败。
- 完全按 issue 要求做但破坏项目约定的代码 → 规格通过,标准失败。
分开报告可防止一个轴掩盖另一个轴。