← Skills

diff-review

diff-review

When an agent or user needs a diff, pull request, or set of changes read for correctness against what it claims to do. Also use when the user says "review this," "review my PR," "check this change," "did I break anything," "is this safe to merge," "look over this diff," or "what did I miss." Use this whenever code already written needs judging. For deciding the shape before code exists, see architecture-review. For applying a change once it is decided, see code-edit. For probing a live surface, see security-audit.

Diff Review

You read a diff against the claim it makes — not against your taste. A review
that lists preferences and misses a broken invariant is worse than no review,
because it reads as coverage.

The loop, in order

  1. Read the claim. The plan, the promise clause, or the commit message
    states an outcome. Every finding is measured against that outcome. A diff
    that does something other than what it claims is itself the finding.

  2. Bound the diff before judging any of it. List the changed files first —
    one cheap command, and it decides how much proof the review needs. A rename, a
    delete, or a change under schema/, packages/sdk/, or auth code needs the
    FULL lane before any approval: verify:fast selects by import graph, and the
    config, parity, and boundary gates import nothing from what they guard. Name
    the lane you actually saw, not the one that should have run.

  3. Hunt the four shapes that recur here. In this order — they are ranked by
    how often they have actually shipped:

    • Auth on the payload, not the receiver. A resolver reading actorId
      from the request body trusts the caller to name itself. The attested
      caller is the only identity. This is the single most-repeated defect in
      the estate.
    • The silent return. A swallowed catch, a fallback that hides a failure,
      a gate whose exit code is not the gate's result. Every signal closes with
      mark or warn.
    • Presence mistaken for proof. A check that greps a string, asserts a
      file exists, or counts matches proves the checker ran. Ask: can this
      check go RED?
      If not, it is decoration.
    • The unenforced label. A field naming an authority level that is never
      compared against one.
  4. Then walk the branches, mechanically. The four shapes are history, and
    history is blind to what has not bitten yet — a novel defect matching none of
    them has no owner in step 3. So make a second pass that is method-driven
    rather than intuition-driven: from the changed lines outward, walk every path
    they reach — conditionals, early returns, loop bounds, the empty input and the
    oversized one, the error handler, the missing else — and report only the
    paths with no guard. Discard the handled ones silently: a list of what is fine
    is not a review, it is padding. Each unguarded path carries the same four
    facts or it is not a finding — where it is, what triggers it, which guard is
    absent, and what happens without it.

  5. Label severity honestly.

    Severity Means
    blocker Ships a defect or opens a hole. Merge is wrong
    major Breaks an invariant; no user-visible symptom yet
    minor Correct, but will mislead the next reader

    Do not inflate to look thorough. Do not soften a blocker to be agreeable.

  6. Give each finding a failure scenario. Concrete inputs or state → the
    wrong output. "Given X, this returns Y and should return Z." A finding that
    cannot be reduced to that shape is a suspicion — label it one or drop it.

Hard rules

  • No diff, no review. Handed nothing, ask for the range or the file list and
    stop. Reviewing whatever happens to be in context produces findings about code
    the author never changed — the most expensive kind of noise, because it reads
    as coverage.
  • Default REFUTED. A finding is not real until you can name the line and a
    path that reaches it. Plausible-but-wrong findings cost more than silence.
  • A fix on main is not a fix in prod. If the diff closes a live defect,
    the review is not complete until someone names the deployment carrying it.
  • Rank most-severe first, and return an empty list rather than padding a
    clean diff with minors.

Out of scope

  • Applying the fixes — review reports, the author edits; see code-edit.
  • Style preferences the codebase does not already enforce.
  • Re-reviewing unchanged code outside the diff, unless the diff breaks it.