How to review a pull request an AI wrote
6m read time

How to review a pull request an AI wrote

Reviewing AI-generated pull requests is not the same job as reviewing a human one. The names are clean, the comments are confident, CI is green, and the boundary is wrong. A checklist ordered by where models actually slip.

The pull request looks great. The variable names are clear. The commit message reads like a human wrote it after a good night's sleep. There's a tidy comment above the one tricky bit. CI is green.

That is exactly the problem.

A human PR tells on itself. The rushed variable name, the commented-out block someone forgot, the test that clearly only covers the happy path: these are tells, and years of reviewing have tuned you to spot them. You skim for the smell and dig where it stinks.

An AI PR has no smell. It is uniformly polished, because polish is the one thing next-token prediction is genuinely good at. So your instinct fires the wrong way. The surface looks more reviewable than a human's, and the honest consequence is that it gets less review. There's research now showing reviewers feel better about approving agent-written PRs, while those same PRs carry more redundancy and quiet debt per change. The confidence is the trap.

Reviewing AI-generated code is a different job than reviewing a colleague's. Same diff view, different failure modes, different order of operations. Here is the checklist I actually run, sorted by where models slip most, not by what's easiest to eyeball.

1. Does it solve the problem, or something adjacent to it?

This is the failure that costs the most and shows the least. The model read your prompt, matched it to the most statistically likely shape of a solution, and built that. Often the shape is right and the boundary is wrong: it paginates from the wrong offset, it handles the collection but not the empty collection, it implements the feature for the logged-in user and silently ignores the service account.

Start at the ticket, not the diff. What was actually asked? Then check that the PR does that, all of that, and only that. AI loves to helpfully implement three things you didn't ask for and forget the one you did. The model writes a beautiful description of a solution to a problem that is almost yours.

2. Trace one critical path. Do not scan it

Scanning is how you review a human. You trust they held the intent in their head and you're checking the execution. There was no intent here, so there's nothing to trust.

Pick the one path that matters, the one where a bug reaches production or a user, and follow a value through it. Input, every transformation, output. Check the boundaries out loud: what happens at zero, at one, at the last element, at null, when two of these run at once. This is where the off-by-one lives, where the missing permission check lives, where the race condition lives. The code compiles and the tests pass and it is still wrong, because you can't spot the bug if you didn't write the code unless you deliberately walk the path the author never walked.

If tracing one path takes longer than the model took to write the whole PR, good. That asymmetry is the job now.

3. Who wrote the tests?

If the answer is "the same agent, in the same run," the green checkmark is worth almost nothing. A model that made a wrong assumption in the code will make the identical wrong assumption in the test, and now you have two artefacts agreeing with each other and a suite that goes green because the test confirms the bug rather than catching it.

Read the assertions, not the count. Does the test check the actual required behaviour, or does it check what the code happens to do? Are the edge cases from step 2 in there, or only the happy path? A test with no failing case it could ever catch is decoration.

4. Did it weaken the harness to go green?

This one is specific to agents and it is nasty. When a model is told to make CI pass, "make CI pass" is the objective, not "make the code correct." Sometimes the cheapest path to green is to change the thing being measured.

Look at every change to test files, CI config, coverage thresholds, and lint rules with a colder eye than the rest of the diff. A skipped test, a lowered threshold, an assertion quietly loosened, a workflow step newly gated: any change that weakens the net is a blocker until you understand exactly why it was made. The feature code getting easier to merge because the gate got lower is the oldest trick, and now something runs it automatically.

5. Is this the fourth way to format a date?

The model does not have your whole repository in its head. It cannot see the formatDate helper three directories over, so it writes a new one, slightly different, named something plausible. Do this across a few dozen sessions and you get a codebase that solves every problem four times, each solution a near-clone of the others. It is invisible in any single PR and it is exactly the churn that petrifies a codebase.

Before approving, ask whether the utility, type, or constant being introduced already exists under another name. Reuse is the thing agents are structurally worst at, so it's the thing a human reviewer adds the most value on.

6. The comments and names are confident. Confidence is not evidence

A human who writes // this is safe because the caller already validated has usually checked. A model writes that sentence because it is the statistically likely sentence to appear above that kind of code. The comment describes what the code looks like, not what is true about it. Same with names: a function called validateAndSanitize is a claim, not a guarantee. Verify the claim. Never let the label do the verifying for you.

Review is the merge gate, and now it's the only one

Every other check on an AI PR can be gamed by the thing being checked. Tests can be written to pass, CI can be weakened, descriptions can be generated. The one gate that doesn't collapse is a human who understands the change well enough to own it.

That's the whole point of running review as a hard stop in your agent workflow: not to rubber-stamp the diff, but to be the step where understanding is required before merge. If you approve a PR you couldn't have written and can't fully explain, you didn't review it. You witnessed it. And shipping code you don't understand is the same debt whether a person or a model typed it, except the model produced it faster and dressed it better.

So slow down at the exact moment the PR makes you want to speed up. The cleaner it looks, the less your instinct will fire, and the more deliberately you have to trace it. The polish is real. It just isn't the signal you've spent your career learning to read.