Perform a dual-axis review of the diff between the user-provided fixed point and
:
- Standards — Does the code comply with the coding standards documented in this repo?
- Spec — Does the code faithfully implement the source issue / PRD / spec?
Both axes run as parallel sub-agents to avoid context contamination; this skill then aggregates their findings.
The issue tracker should already be provided to you; if
docs/agents/issue-tracker.md
is missing, run
/setup-matt-pocock-skills
.
Process
1. Pin the fixed point
Any content specified by the user serves as the fixed point: commit SHA, branch name, tag,
,
, etc. If the user does not specify one, ask for it.
First capture a diff command:
git diff <fixed-point>...HEAD
(three-dot, so it compares against the merge-base). Also record the list of commits using
git log <fixed-point>..HEAD --oneline
.
Before proceeding, confirm that the fixed point can be resolved (
git rev-parse <fixed-point>
) and that the diff is non-empty. Invalid refs or empty diffs should fail here instead of after spawning the two parallel sub-agents.
2. Identify the spec source
Look for the source spec in the following order:
- Issue references in commit messages (, , GitLab , etc.) — retrieve according to the workflow in
docs/agents/issue-tracker.md
.
- Path passed as an argument by the user.
- PRD/spec files under , or that match the branch name or feature.
- If nothing is found, ask the user where the spec is. If the user says there is no spec, the Spec sub-agent skips and reports "no spec available".
3. Identify the standards sources
Any content in the repo that documents how code should be written, such as
or
.
In addition to the standards documented by the repo itself, the Standards axis always includes the following smell baseline: a fixed set of Fowler code smells (Chapter 3 of Refactoring), which applies even if the repo has no conventions. There are two rules:
- The repo overrides. Documented repo standards always take precedence; if it approves something that would be flagged by the baseline, suppress that smell.
- Always a judgement call. Each smell is a labeled heuristic (e.g., "possible Feature Envy"), not a hard violation; like other standards here, skip items that are already enforced by tooling.
Each smell is evaluated against the diff by following what it is -> how to fix:
- Mysterious Name — The name of a function, variable, or type does not explain what it does or holds. -> Rename it; if an honest name cannot be found, the design itself may be unclear.
- Duplicated Code — The same logic pattern appears in multiple hunks or files. -> Extract the shared pattern and have both sides call it.
- Feature Envy — A method accesses another object's data more than its own. -> Move the method to the object whose data it envies.
- Data Clumps — The same groups of fields or parameters always appear together. -> Package them into a single type for passing.
- Primitive Obsession — Primitives or strings are used instead of domain concepts that deserve their own type. -> Create a small type for that concept.
- Repeated Switches — The same / cascade for the same type is repeated in the changes. -> Replace with polymorphism or share a map.
- Shotgun Surgery — A single logical change requires scattered modifications across many files in the diff. -> Consolidate things that change together into one module.
- Divergent Change — A file or module is modified for multiple unrelated reasons. -> Split it so each module changes for only one reason.
- Speculative Generality — Abstractions, parameters, or hooks are added for requirements not specified. -> Remove it and inline it back until there is a real need.
- Message Chains — Long chained navigation that the caller should not depend on. -> Hide this navigation behind a method in the first object.
- Middle Man — A class or function basically just delegates further. -> Remove it and call the real target directly.
- Refused Bequest — A subclass or implementer ignores or overrides most of the inherited content. -> Remove inheritance and use composition.
4. Spawn both sub-agents in parallel
Send a message containing two
tool calls. Both use the
subagent.
Standards sub-agent prompt — Includes:
- The complete diff command and commit list.
- The list of standards-source files found in Step 3, as well as the full text of the smell baseline from Step 3; the sub-agent has no other way to access it.
- 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 — Includes:
- The diff command and commit list.
- The path to the spec or the retrieved content.
- 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.
5. Aggregate
Display the two reports under
and
headings, either as-is or with minor cleanup.
Do not merge or reorder findings; the two axes are intentionally kept separate (see
Why two axes).
End with a one-line summary: the total number of findings for each axis, and the most severe issue within each axis (if any). Do not select an overall top issue across axes; separation is intended to avoid such reranking.
Why two axes
A change may pass one axis but fail the other:
- The code complies with all standards but implements the wrong thing -> Standards pass, Spec fail.
- The code fully meets the issue requirements but violates project conventions -> Spec pass, Standards fail.
Reporting separately prevents one axis from overshadowing the other.