A diff is the worst possible place to review a change. It shows you what moved. It hides everything the change depends on.

Senior engineers know this. They open the file, scroll up, find the caller, check the test. Most AI review setups give the model none of that, and then we're surprised its comments are about naming.

What a diff can't tell a reviewer

  • That the function it changed is also called from a background worker
  • That the screen has an offline state the change forgot
  • That the spec asked for the opposite behaviour
  • That the test it updated no longer asserts anything useful

All four are invisible in a diff, and obvious with the right three files open. The problem isn't the model. It's what we hand it.

What I give an AI reviewer

  1. 1The specWhat the change is supposed to do, including the states and the out-of-scope list. Without it, a reviewer can only check that the code agrees with itself.
  2. 2The touched files, wholeEvery file the diff touches, in full, plus the direct callers. The context around a change, not just the change.
  3. 3The testsThe tests that cover the change, and the diff of the tests. A reviewer that reads the test diff first catches the weakened assertion.
  4. 4The house rulesThe conventions file: architecture, naming, error handling, threading. So "this isn't how we do it here" becomes a finding, not a vibe.

I keep those instructions in the repo, as a file the reviewing agent reads first. It's short:

# Review instructions

Read first, in this order:
1. The spec linked in the PR description
2. The test diff
3. Every file the diff touches, in full, and their direct callers
4. CONVENTIONS.md

For each finding, give:
- the file and line
- what breaks, for which user, in which state
- the spec line or rule it goes against
- the test that would catch it

If there are no findings, say so. Don't invent nits to fill the space.

The last line matters more than it looks. A reviewer that feels obliged to say something will say something, and a page of filler trains everyone to skim the review.

Before

Diff-only review

  • Naming and formatting nits
  • "Consider adding a null check" on code that can't be null
  • Confident comments about code it can't see
  • Misses the caller, the spec and the test

After

Files, spec and tests

  • "A background worker calls this too"
  • "The spec's offline state isn't handled"
  • "This test no longer checks the cache"
  • Every finding points at a file and a line

What it catches

With that context, an AI reviewer is very good at the tedious, high-value checks: a missing loading or error state, an exception swallowed on a network call, a coroutine launched in a scope that outlives the screen, a field read as non-null that the API contract says can be missing, a hardcoded string that should be localized. On iOS, it catches a closure that captures self strongly, or UI work that slipped off the main thread.

It's also tireless. It reads the fortieth file with the same attention as the first, which is more than any of us can promise on a Friday afternoon.

What it misses

  • Whether the feature should exist. It reviews the change you made, not the one you should have made.
  • How it feels on a real device. Jank, a keyboard covering a button, an animation that's technically correct and still wrong.
  • Anything not in the files. The call where the requirement changed. The release freeze. The other team's API migration next week.
  • Risk in context. A small change to the checkout and a small change to a settings label look exactly the same in a diff.

That list is the job description of the human reviewer now. Not hunting for the missing null check, but asking whether the change is the right one and what it costs if it's wrong.

Reviewing like a senior

A senior reviewer asks three questions before reading a single line: what is this for, what could it break, and how would we know? Give the model the material to ask the same three, and its review moves a lot closer to theirs. Give it only the diff, and it can only answer a fourth question nobody asked: does this code look tidy?

A review comment worth reading
  • Agentrefresh() now clears the cache before the network call (OrdersRepository.kt). The spec says offline users keep seeing their last orders. On a failed request they'll now see an empty screen.
  • MeGood catch. Is there a test for the failure path?
  • AgentNo. OrdersRepositoryTest only covers success. I'd add one where the API throws and assert the cached list is still returned.

That's the bar: a file, a reason taken from the spec, and the test that would have caught it. Nothing in that comment was visible in the diff alone.

AI review doesn't replace the senior on your team. It gives them a first pass worth reading, so their attention goes where only they can add value. The cheapest upgrade to your AI review isn't a better model; it's three more files in its context.

Building with AI?Let's talk about your appBook a free intro call