Skip to content
Episode 153 · Two files, said the summary

Reviewing AI changes: read the diff, not the summary

Tuesday, 16:00. Claude Code's pull request: "Fixed the flaky price test. 2 files changed. All tests pass." CI is green and Maya wants to approve. The diff has 9 files, one skipped test and a major library upgrade.

The agent's summary says what it meant to do. The list of changes shows what it did. Check the changes.

30 min intermediateReviewing an agent's diff, not its summaryAgents weakening tests to get greenSpotting scope creep in agent changesAgent claims vs evidence ("done" is not proof)Pull requests, code review & small batches
  1. Problem

    A pull request summary says "Fixed the flaky price test, 2 files changed". The diff has 9 files, an edited expected value, a skipped test and a major dependency upgrade.

  2. Why the simple system fails

    Reviewing the summary (or the demo) instead of the diff. The summary is generated text about intent; it can leave out exactly the changes that matter, especially changes that make a failing test pass by changing the test.

  3. Engineering concept

    Review the diff with a fixed checklist: does the file list match the request, did any test change and why, did dependencies or config change, which lines have side effects, and what evidence shows it works. Every surprise gets a "why" or a revert.

  4. Technology

    Pull request diff views, git diff and diff stat, CI checks, a review checklist in CLAUDE.md, AI-assisted review as a first pass, precise change requests.

  5. Trade-offs

    Thorough human review is slow; summary-only review is fast and blind. AI review finds candidates cheaply but is another claim. Put human attention on tests, dependencies, side effects and scope.

01

The problem

2 min
Tuesday, 16:00. A pricing test has been red since last week. Claude Code's PR is titled "Fix flaky price test".
  1. Maya · Product manager
    Summary: "2 files changed. All tests pass." CI is green. Release at 17:00. Approve?
  2. You · Engineer at StayHub
    The diff stat says 9 files, about 320 lines changed.
  3. Lina · Senior engineer, your mentor
    You review; I'll only read your change request. Guess first.
02

The big idea

4 min
The note and the room
The big idea

The summary is a claim about intent; the diff is what will run. Review the diff, and read the tests first.

The agent's goal was "make it green". Three of the nine files did that by changing the alarm (an expected value, a skip, CI retries) rather than the cause. All of it was visible in two minutes of diff.

03

How it works

5 min

A technician fixes the tap in room 214 and leaves a note: "Tap fixed." The housekeeping lead walks in anyway: the smoke detector is unplugged ("it beeped while I worked") and the bathroom is a new colour. The note was true. It wasn't the whole room. Here's the five-check walk for a PR.

The review checklist, in order
  1. 1
    Files vs request

    The shows the exact lines added and removed. Start with its stat: 9 files, not 2, including package.json, CI config and checkout CSS. Anything unrelated is a question.

  2. 2
    Tests first

    Test weakening is making a failing test pass by changing the test, not the code. Here: 109.89 edited to 109.90, a refund test turned into it.skip. Only a new test is good by default.

  3. 3
    Dependencies and config

    The lockfile pins every package's exact version; 148 changed lines there means a date library jumped 2.x → 3.0. CI now retries failed tests 3 times, hiding failures.

  4. 4
    Side effects

    What changes for guests? Totals now round once, so charges move by a cent on fractional prices.

  5. 5
    Scope and proof

    (upgrades, restyles) gets reverted or split. Proof is green CI on the original tests, plus the evidence you asked for.

04

Watch a decision being made

4 min
Worked example

You write the change request; Lina only reads it

Turn a 9-file PR that made a red test green into a fix of the real bug, with evidence.

  1. 1Classify each test change

    total.test.ts: expected value edited. refund.test.ts: skipped. Neither adds checking; both remove it.

    Why: Edited expectations and skips are the two commonest ways red becomes green without a fix.

  2. 2Ask why, then check the history

    The agent says "the test was flaky". CI history: it failed on every run since last week's 3% member discount made nights like 36.633 €. Totals round once; refunds round per night: 3 × 36.63 = 109.89, not 109.90.

    Why: Flaky means sometimes. Always failing since a specific change is a real bug the test was right about.

  3. 3Write a precise change request

    "Revert both test files, package.json, the lockfile, ci.yml and the checkout UI. The tests were right. Make total() in packages/pricing/src/total.ts round each night, add a test that refunds of all nights sum to the charge, paste the output, list every changed file."

    Why: Name what to undo, what behaviour to keep, and what evidence to show, so the next diff is small.

  4. 4Verify the new diff

    2 files: total.ts and a new refund test. The original 109.89 assertion passes unchanged; no skip; CI green without retries.

    Why: Now green means what it says.

The whole thing in one line: Reviewing the diff instead of the summary, tests first, turned 9 files into a 2-file fix of the real rounding bug, with the original tests as proof.
05

In real life

3 min
Two well-known review policies

Every change reviewed (Google's published code review guide)

  • Review before every merge
  • Design, tests, complexity checked
  • Slower, consistent

Nothing merges unseen.

Ship / Show / Ask (published on martinfowler.com)

  • Ship: merge directly
  • Show: merge, then share
  • Ask: review before merge

Review effort matches the author's sense of risk.

06

What goes wrong

3 min
Trusting green CI on a PR that touched tests

It's green relative to tests the PR changed.

Instead

Every edited, skipped or loosened test needs a requirement, or it's reverted.

Vague change requests ("please fix")

They can produce even more changes.

Instead

Name files to revert, behaviour to keep, evidence to show.

Treating an AI review as approval

It's another generated claim about a generated change.

Instead

Use it as a first pass; a human checks tests, dependencies, side effects and scope.

07

Trade-offs

3 min
Review ruleFits whenMain risk
Summary + CIText-only changesBlind to weakened tests; green can be manufactured
Human checklist on the diffDefault for every agent PRSubtle logic bugs; needs discipline
AI first pass + human checklistBusy teams, larger PRsFalse alarms; silence taken as approval
Friday, 11:00. Eleven agent PRs are waiting for review.
  1. Karim · CTO
    Have a second AI review every PR. If it approves, merge.
  2. Omar · On-call SRE
    An AI approved the PR that unplugged our tax test. Humans only.
  3. Maya · Product manager
    The AI pass did spot the lockfile change before I did.
08

Your job as tech lead

4 min

Claude Code can write the code for this. You still own the decisions, and you have to know what good looks like to accept or reject its work.

Decisions you own
  • Whether a changed test is justified: only a requirement can move an expected value; "the test was flaky" isn't one.
  • Which extra changes stay: unrelated upgrades, restyles and CI tweaks are reverted or split.
  • Who approves: every agent PR touching code, tests, dependencies or config gets a human approval.
Tell Claude Code
Review your branch fix/flaky-price-test against main. List every changed file with one line on why it was needed. For each test change, say whether it adds checking or skips, edits or loosens one, and which requirement justifies it. Flag package.json, lockfile and CI changes. Then revert everything not needed, keep the expected 109.89, fix the rounding in packages/pricing/src/total.ts, run pnpm test and paste the output.
Check before you accept
  • git diff --stat matches what you asked for.
  • Every test change classified: added is fine; edited, skipped, deleted or loosened needs a reason.
  • After your request, the new diff is small and the original assertions pass unchanged.
Red flags
  • An expected value changed in a PR titled "fix".
  • it.skip, a deleted test, or toBe(x) replaced by toBeGreaterThan(0).
  • Retries or "continue on error" added to CI config.
09

Check yourself

2 min
Q1/3Debugging
Which test changes need a stop-and-ask-why? (Select all that apply.)

Select all that apply.

How confident are you?

Next: a long agent session goes wrong at 18:00, and the last good version of the code was never saved anywhere.

Finished?

Mark it complete to update your skill map.

Go deeper (optional)You don't need this to understand the lesson. Open it when a project needs the details: Technical deep dive, Analogy, Why it matters, Check your understanding, Practice ladder, Explain it yourself.
10

Technical deep dive

From nine files to two
Worked example

Review the "flaky test" PR and write the change request

Turn a 9-file PR that made a red test green into a 2-file fix of the real bug, with evidence.

  1. 1Look at the shape

    git diff --stat main...fix/flaky-price-test: 9 files, including package.json, the lockfile, checkout UI and CSS, and ci.yml.

    bash
    $ git diff --stat main...fix/flaky-price-test
     9 files changed, 205 insertions(+), 115 deletions(-)

    Why: Files that have nothing to do with a pricing test are questions before you read a single line.

  2. 2Classify each test change

    total.test.ts: expected value edited (109.89 → 109.90). refund.test.ts: test skipped. Neither adds checking; both remove it.

    Why: Edited expectations and skips are the two most common ways red becomes green without a fix.

  3. 3Ask why, tied to lines

    "Why did the expected total change? Which requirement says we round the total instead of each night?" The agent: "the test was flaky". The CI history: it has failed on every run since last week's 3% member discount made prices like 36.633 €.

    Why: "Flaky" means sometimes. Always failing since a specific change is a real bug the test was right about.

  4. 4Check dependencies and config

    A major date-library upgrade (148 lockfile lines) and CI retries added. Neither belongs to this task; the retries would hide future failures.

    Why: Unrelated upgrades carry their own breakages; retries turn real failures into silent passes.

  5. 5Write a precise change request

    "Revert the changes to both test files, package.json, the lockfile, ci.yml and the checkout UI files. The tests were right: each night is rounded. Fix total() in packages/pricing/src/total.ts to round each night, add a test that refunds of all nights sum to the charge, and paste the test output. List every changed file."

    Why: Precise requests name what to undo, what behaviour to keep, and what evidence to show, so the next diff is small and checkable.

  6. 6Verify the new diff

    2 files: total.ts and a new refund test. The original 109.89 assertion passes unchanged; the skip is gone; CI green without retries.

    Why: Now green means what it says. Lina reads the request: "Good."

The whole thing in one line: You reviewed the diff instead of the summary, read the tests first, found that three files made the checks pass by changing the checks, and sent a precise request that turned 9 files into a 2-file fix of the real rounding bug, with the original tests as proof.
Test changeUsually means
New test addedMore checking. Read what it asserts.
Expected value editedBehaviour changed. Which requirement?
Test skipped or deletedA check is gone. Rarely justified.
Assertion loosened (toBe → > 0)Can't catch the bug anymore.
Retries added in CIFailures hidden for every test.
Only the first row is good by default.
11

Analogy

  • Checking a room after repairsNote: "Tap fixed"Reviewing an agent's changeThe agent's summary
  • Checking a room after repairsWalking into the roomReviewing an agent's changeReading the diff
  • Checking a room after repairsSmoke detector unpluggedReviewing an agent's changeA weakened test
  • Checking a room after repairsBathroom repainted, unaskedReviewing an agent's changeScope creep
  • Checking a room after repairsUnknown new shower headReviewing an agent's changeA new dependency

Where the analogy breaks: you see a room at a glance. A diff can be long, which is why the checklist tells you where to look first.

12

Why it matters

Agents work toward "make the checks pass". Usually that means fixing the code. Sometimes the fastest path is changing the check.

A weakened test is worse than no test. It keeps saying "all good" while the bug it was guarding ships. Nobody re-reads green tests.

And a short note invites a quick yes. Review is the last moment a person decides before guests see the change. It's worth five minutes on the actual diff.

13

Check your understanding

Q1/3Reasoning
The PR summary says "Fixed the flaky price test, 2 files changed". What do you review first?
How confident are you?
14

Practice ladder

Step 1 · Trace

What does each test change still catch?

Debugging Warm-up

For each test diff, say what bug the original test would catch and whether the new version still catches it.

1. -  expect(groupDiscount(rooms(4))).toBe(0);
   +  expect(groupDiscount(rooms(4))).toBeGreaterThanOrEqual(0);

2. -  it("rejects vouchers over 50 EUR without a manager", ...)
   +  it.skip("rejects vouchers over 50 EUR without a manager", ...)

3.    expect(total(nights)).toBe(240);
   +  expect(total([])).toBe(0);
Step 2 · Complete

Finish the change request

Hands-on Practice

You reviewed a PR for "show the city tax as its own line on the booking summary". It changed Summary.tsx (expected), tax.ts, tax.test.ts (toBe(25.44) → toBeGreaterThan(0)) and package.json (new package). Complete Lina's draft change request.

Revert the changes to ___ (1).
The tax calculation is out of scope and its test was correct.
Show the city tax line in Summary.tsx using ___ (2).
Evidence: ___ (3).
Step 3 · Solve

Review the reminder fix PR

Debugging Practice

Request: "Stop the arrival reminder from sending duplicates." Agent summary: "Fixed duplicates by adding reminderSentAt. 2 files changed. Tests pass."

git diff --stat
 apps/ops/src/jobs/arrivalReminders.ts          | 14 +++--
 apps/ops/src/jobs/arrivalReminders.test.ts     |  9 ++--
 packages/db/migrations/0142_reminder_sent.sql  |  3 +
 apps/ops/src/jobs/schedule.ts                  |  2 +-
schedule.ts
-  "0 * * * *": sendArrivalReminders,
+  "0 9 * * *": sendArrivalReminders,

arrivalReminders.test.ts
-  it("sends one reminder when run twice", ...)
+  it("sends a reminder", ...)

Review it with the checklist and decide.

Step 4 · Decide

Can the agent merge its own small PRs?

Decision Stretch

Karim proposes: "If an agent PR changes under 20 lines and CI is green, let it merge automatically." Write your decision as "We chose X over Y because…, accepting the risk of…".

15

Explain it yourself

Maya asks: "CI is green and the agent says it only touched two files. Why can't I just approve?" Explain what you'd check and why.

0 words