✅ Review Early Link to heading
Coding agents changed where my time goes. Writing code isn’t the slow part anymore — reviewing it is.
That’s a management problem as much as a technical one. On a small team there’s no separate QA group and no architecture board. There’s you, a few people, and now a few agents that can produce a lot of plausible code very quickly.
In my CodeSpeak post I ended with open questions about reviewable diffs and how much automation a domain can take. This is the practical follow-up — not a new language or a spec format, just the method I use day to day with coding agents (tools like Claude Code or Codex; the specific tool matters less than the habits).
Most of it will feel familiar if you’ve ever led people. That’s no coincidence.
🧭 The Problem: Review at the End Collapses Link to heading
The default flow looks like this: describe the task, let the agent run, read the diff.
For small changes, that’s fine. For anything big, it falls apart. A 2,000-line generated diff is where review quality collapses. Every file looks reasonable. The tests pass. The decisions that matter were made somewhere in the middle, and now they’re spread across twenty files.
At that point you’ve got two bad options: skim and approve, or send it back and pay for the whole thing again.
Reviewing harder won’t fix that. Reviewing earlier will — while changes are still cheap.
🚦 1) Triage First Link to heading
Most work doesn’t need ceremony. Small, easy-to-undo changes — renames, docs, config, cosmetic work — get one agent session and a normal review, and they’re done.
I move up to a heavier flow when the change touches any of these:
- security, auth, or permissions
- persisted data: writes, migrations, retention
- a contract other people depend on: an API, an event, a shared schema
- several layers at once
- two or more decisions that belong to a human
If none apply, I keep it light. If one applies, I slow down on purpose. And if it’s borderline, I decide explicitly instead of drifting into whichever flow I happened to start with.
🧱 2) Review the Plan, Then the Stubs, Then the Tests Link to heading
For the heavier flow, I review in this order, before any implementation exists:
- The plan. What’s being built, what’s out of scope, which decisions are open. A wrong assumption costs one sentence to fix here.
- The interfaces and stubs. Signatures, data shapes, where things live. I can read the shape of a change in minutes; reading the same shape inside a finished implementation takes much longer.
- The tests. What “done” means, written down before the code. This is where I catch missing corner cases and expectations I disagree with.
Each review is small, and each one narrows the next step. By the time implementation starts, the interesting decisions are already made — and they’re visible.
📦 3) Delegate Inside a Box Link to heading
Once the plan, stubs and tests are reviewed, the implementation is mostly filling in. That’s where a cheaper, faster model earns its keep.
The catch is that it only works inside a complete box:
- reviewed stubs with fixed signatures and data shapes
- locked tests it isn’t allowed to change
- a clear instruction to make the tests pass and nothing else
When something doesn’t fit, I want a misfit report, not a workaround I never hear about. “This test looks wrong because…” or “this stub can’t return that without…” is useful. A silently edited test is the worst outcome in the whole process.
The same idea applies to a junior developer on risky work: give them a box with clear edges, and make it safe to say “this doesn’t fit.” Growing people is a different goal, and there I hand off outcomes rather than boxes, as I wrote in Leading Without Letting Go.
The line I don’t cross: never delegate the thinking. The cheap model implements. It doesn’t decide what to build.
🔍 4) Use an Independent Reviewer Link to heading
The reviewer — whether it’s another agent or a person — gets the plan and the code. It doesn’t get the author’s conclusion. Hand a reviewer “I think this is correct, please confirm,” and it’ll usually confirm.
I expect the reviewer to push back. Then every finding gets an answer:
- Fixed, with evidence (a test, a diff, an output)
- Disputed, with a reason the human can see
- Deferred, with a follow-up written down
What’s not allowed is arguing a finding away in a private loop between the author and the reviewer. If a finding is wrong, say why, somewhere I can read it.
🙋 5) Decisions Stay With the Human Link to heading
Agents are very good at finding a precedent in the codebase and following it. That’s exactly the problem when the precedent is a decision no one would make again.
So the agent stops and asks for decisions that are mine:
- scope
- data retention
- API shape that other people will consume
- security tradeoffs
This is commander’s intent applied to tools. Give enough context for good local decisions, and keep the decisions that carry real risk with the person who owns that risk.
🧪 6) Check It Like a Real User Link to heading
Tests prove the code does what the tests say. They don’t prove the feature works.
Late in the flow, someone runs the thing the way its user would. Call the endpoint. Click through the page. Run the job against realistic data. This catches the “all green, still wrong” class of problems that a test suite written alongside the code tends to miss.
🔀 7) I Open, You Merge Link to heading
Agents can open and update pull requests. A human does every merge.
That one rule keeps accountability where it belongs. It also means every change passes through at least one person who chose to ship it.
⚖️ What It Costs Link to heading
This is my own rough observation from working both ways — it’s not a study.
On low-risk work, a single agent session matched the heavier flow at roughly a third to half the cost. The ceremony bought nothing there.
On risky work, the early reviews caught problems that a single session would likely have shipped.
The heavier flow isn’t free. In its light form it costs roughly twice as much and takes about three times as long. A careful form costs more than that. So it’s a choice, not a default — and triage is what makes the whole thing affordable.
🔎 What I Look For in an AI-Generated PR Link to heading
Even with early reviews, the final PR still gets read. Here’s what I look for first:
- Tests that can’t fail. Assertions on mocks, assertions on the value just set, tests that pass with the implementation deleted. If I can’t imagine the test going red, it isn’t testing anything.
- Silent decisions. A new default, a changed error code, a retention window, a field that became nullable. If it’s a decision and no one asked me, it gets flagged.
- A precedent copied from bad code. “I followed the pattern in X” is only good news if X was good.
- Scope creep. Helpful refactors and “while I was here” changes make the diff bigger and the review worse. Split them out.
- Plausible but unverified claims. Comments, docs and PR descriptions that state behavior confidently — “thread-safe,” “idempotent,” “backwards compatible.” I check each one or ask for the evidence.
None of this is specific to AI. Agents just produce these problems faster — and with better grammar.
🏁 Wrap-Up Link to heading
The agents didn’t remove the need for engineering judgment. They moved it earlier.
Review the plan, the shape and the tests while they’re cheap. Put the implementer in a box. Let an independent reviewer push back, and answer every finding. Keep the real decisions — and the merge button — with a human.
Yes, it’s slower than letting the agent run. But on the work that matters, a few small reviews up front cost far less than one giant diff you can’t really read. And if it all sounds a lot like leading a good team — setting the intent, drawing clear edges, staying close enough to catch what matters — that’s because it is. The team just got a few new members.
✅ Checklist Link to heading
- Triage: does it touch security, persisted data, a shared contract, several layers, or two or more human decisions?
- If not: one session, normal review.
- If so: review the plan, then the stubs, then the tests, before implementation.
- Implementer works inside locked stubs and tests, and reports misfits.
- Reviewer gets the plan and the code, not the conclusion.
- Every finding: fixed, disputed, or deferred, in writing.
- Owner decisions are asked for, not inferred from precedent.
- Someone runs it like a real user.
- Agents open PRs. A human merges.
Related Posts