When the code is written, review it on two separate axes:
Standards: does the code follow this repo's written coding standards?
Spec: does the code do what the Spec or Ticket asked for?
Why two
A change can pass one axis and fail the other.
Code that follows every standard but builds the wrong thing: Standards pass, Spec fail.
Code that does exactly what the Ticket asked but breaks the project's conventions: Spec pass, Standards fail.
builds the wrong thing
breaks the project's conventions
Standards pass
yes
no
Spec pass
no
yes
A change can pass one axis and fail the other.
If you review only one way, the other kind of problem slips through. So the two reports stay separate. Their findings aren't merged or ranked against each other, because that would let one axis hide the other.
How the review runs
code-review runs each axis in its own subagent (a helper agent with its own context window), at the same time, so neither muddles the other's thinking.
The Standards axis reads every file in the repo that says how code should be written. On top of that it carries a fixed baseline of code smells, signs that the design may have a problem, such as duplicated code or a name that doesn't say what it holds. Two things keep the baseline in its place. A written repo standard always wins over it. And each smell is a judgement call, never a hard failure.
Who enforces the standards
The agent that writes the code is under the most pressure on its context window: it explores, writes code and debugs. The reviewing agent just gets the diff. So the reviewer, not the writer, is the one who enforces the coding standards.
Where it shows up
implement calls the review once a Ticket's code is done. implement-spec runs one review over the whole integration branch (the single branch where all the Tickets land) once every Ticket is complete.
Going deeper
5 min read · Going deeper not read
Why it exists
Matt explains the design on his code-review page, last updated on 24 August 2026. It "exists to avoid a generic review skill that does not know your standards." Such a reviewer "flags what is deliberate in your codebase and misses the invariants your codebase depends on." So the repo's own written rules lead, and "the repo always overrides".
His page adds how the report ends: with a worst issue for each axis, and never one winner across them.
How it works underneath
Code smells. The baseline comes from Martin Fowler's book Refactoring. In a 2006 post, Fowler defined a code smell as "a surface indication that usually corresponds to a deeper problem in the system", and said Kent Beck coined the term. He also wrote that "smells don't always indicate a problem". That fits code-review's rule: each smell is "a labelled heuristic", never a hard violation.
A reviewer that didn't write the code. Anthropic's docs give the same reason for a separate reviewer. They say it of Claude Code's own built-in /code-review, a different command with the same name: it reviews "in a fresh subagent that never saw your conversation" and "isn't swayed by the reasoning that produced the code." The page is careful about what a subagent buys you. It doesn't give a smarter answer by itself, but "A fresh reviewer does help, because it hasn't seen your reasoning". Since 29 October 2026, the code-review SKILL.md says it outright: "Start every sub-agent with a fresh context window."
Citations (64)
From snapshot/skills/code-review/SKILL.md, lines 8–9: “- Standards: does the code conform to this repo's documented coding standards? - Spec: does the code faithfully implement the originating issue / spec?”
From snapshot/skills/code-review/SKILL.md, lines 86–89: “- 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.”
Findings you can check. Every finding must point at something: a standards file and its rule, a named smell plus the hunk (the changed lines it's about), or a line of the Spec. Matt's page calls a subagent's output "a hypothesis, not evidence". The required citation "is what makes the findings checkable."
A real example
Anthropic's best-practices page includes a real reviewer, the file .claude/agents/reviewer.md. Its instructions read:
You're reviewing code you didn't write. Compare the changed files against the spec you're given,
check that every requirement is implemented and the listed edge cases have tests,
and report only the gaps that affect correctness. Skip style.
So Anthropic's reviewer is a Spec axis on its own. The same page's review-against-spec prompt also ends "skip style", and it says why: "A reviewer that's asked to find problems will always find something." Fix every finding, the page warns, and "you end up with extra abstraction layers and tests for cases that can't happen."
code-review keeps a Standards axis but fences it in. It reads only the repo's written standards plus a fixed baseline.
Anthropic's reviewer
code-review
a Spec axis
yes
yes
a Standards axis
no
yes
each smell is a judgement call
yes
Anthropic's reviewer is a Spec axis on its own
code-review keeps a Standards axis but fences it in.
Where it goes wrong
Reviewing in the same session. Matt's page quotes a reader: "Same context reviewing itself isn't review, it's confirmation bias with a slash command." His page is dated 24 August 2026. Since 29 October 2026, which is newer, the SKILL.md starts every sub-agent with a fresh context window. But implement still calls code-review from the session that wrote the code, and Matt's page hasn't withdrawn its advice: "The independent version is to invoke /code-review yourself from a clean session."
It never comes back clean. Each fix adds new code to review, and the judgement calls change from run to run. "There is no convergence guarantee." Act on the findings with a cited rule behind them, then stop.
It can't see uncommitted work. It compares your last commit (HEAD) with the point you name, such as main. That diff "excludes staged and working-tree changes". Issue #511, opened on 10 July 2026 and still open on 30 October 2026, reports that implement and code-review disagree here. Commit first, then review.
Reviewers that start the review again. Issue #573, opened on 14 July 2026, reports that the two subagents "regularly invoke /code-review themselves", so each spawns two more. Matt's page, updated in August, calls it "a known open bug". The newer word is a scope note in Matt's repo that lists #573 as a prior request: "The harness should be responsible for stopping infinite subagent loops, not skills." The issue was closed as not planned on 6 October 2026, and the SKILL.md as of 29 October 2026 adds no guard. So if you run it unattended, "watch the agent count."
Try it
In your practice project (set it up first with keeping-track's Try it step if you haven't), give the Standards axis something of yours to read. Add a CODING_STANDARDS.md with one judgement-call rule for the FastAPI backend, such as "route handlers stay thin; booking logic lives in a service module". Commit your booking endpoint work on a feature branch, with Closes #<ticket> in a commit message, so the Spec axis can find its Ticket. Then open a fresh session and run code-review against main. Check that the report comes back as two blocks, ## Standards and ## Spec, and that each Standards finding names your rule or a smell.
From snapshot/skills/code-review/SKILL.md, lines 40–41: “- 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.”
From snapshot/skills/retro/SKILL.md, lines 31–35: “The implementation agent has the most context pressure. They are responsible for exploration, writing code, and debugging failures. The review agent has the least context pressure - it receives a diff, so no exploration needed.”
From snapshot/skills/retro/SKILL.md, line 35: “This means that the review agent should be responsible for imposing coding standards, not the implementation agent.”
From snapshot/skills/code-review/SKILL.md, lines 45–46: “- 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:”
From snapshot/web/aihero.dev/skills-code-review.md, line 135: “This design exists to avoid a generic review skill that does not know your standards. Such a skill flags what is deliberate in your codebase and misses the invariants your codebase depends on.”
From snapshot/web/code.claude.com/docs-en-best-practices.md, line 223: “By someone who didn’t write the code: in the terminal, /code-review reviews the diff in a fresh subagent that never saw your conversation. It isn’t swayed by the reasoning that produced the code.”
From snapshot/web/aihero.dev/skills-code-review.md, line 164: “The skill requires every finding to carry a citation (a standards rule, a smell plus its hunk, or a spec line), and that is what makes the findings checkable.”
From snapshot/web/code.claude.com/docs-en-best-practices.md, lines 422–434: “That reviewer is one short file, .claude/agents/reviewer.md: .claude/agents/reviewer.md ``` --- name: reviewer description: Reviews changed files against the spec they were built from. Use after implementing a feature, before opening the PR. tools: Read, Grep, Glob --- You're reviewing code you didn't write. Compare the changed files against the spec you're given, check that every requirement is implemented and the listed edge cases have tests, and report only the gaps that affect correctness. Skip style.”
From snapshot/web/code.claude.com/docs-en-best-practices.md, line 234: “use a subagent to review the rate limiter diff against SPEC.md, check every requirement is implemented and the listed edge cases have tests, report gaps that affect correctness and skip style”
From snapshot/web/code.claude.com/docs-en-best-practices.md, line 237: “Don’t drop the skip style part of that prompt. A reviewer that’s asked to find problems will always find something. If you fix every finding, you end up with extra abstraction layers and tests for cases that can’t happen.”