Reviewing AI-generated code: a checklist for senior engineers
Short answer: review AI-generated code from the diff, not from the agent's summary, and look hardest where models fail most: swallowed errors, security, tests that were weakened, invented APIs and changes nobody asked for. If you can't explain a line, it doesn't get merged. The checklist below takes ten minutes per change and catches most of what matters.
A real example: a search endpoint that looked fine
I asked an agent for "a search endpoint for policies by holder name". It produced this, with a cheerful summary saying it handles errors gracefully:
app.MapGet("/policies/search", async (string q, AppDbContext db) =>
{
try
{
var sql = $"SELECT * FROM Policies WHERE HolderName LIKE '%{q}%'";
return Results.Ok(await db.Policies.FromSqlRaw(sql).ToListAsync());
}
catch (Exception)
{
return Results.Ok(new List<Policy>());
}
});
It compiles, and on the happy path it works. It also has a SQL injection, no authorization, returns every column (including the national ID and phone number), has no paging, and turns a database outage into "no results", which is the worst kind of failure: silent. The reviewed version:
app.MapGet("/policies/search",
async (string q, int page, AppDbContext db, CancellationToken ct) =>
{
if (q.Length < 3) return Results.BadRequest("Enter at least 3 characters.");
var items = await db.Policies
.AsNoTracking()
.Where(p => EF.Functions.Like(p.HolderName, $"%{q}%")) // parameterised
.OrderBy(p => p.Id)
.Skip(Math.Max(page, 0) * 20).Take(20)
.Select(p => new PolicySummary(p.Id, p.Number, p.HolderName, p.Status))
.ToListAsync(ct);
return Results.Ok(items);
})
.RequireAuthorization("PolicyReader");
None of the problems were exotic. They were just easy to miss because the code looked finished.
The checklist
- Scope. Does the diff do what was asked and only that? Unrequested refactors, renamed files and "while I was here" changes get reverted or split out.
- Read the diff, not the chat. The summary describes intent. The diff is what ships.
- Tests. Were any tests deleted, skipped or loosened to make the build green? Do new tests assert behaviour, or only that mocks were called?
- Error handling. Look for
catch (Exception)that returns a default, empty catches, and errors logged but not surfaced. - Security. String-built SQL, missing
[Authorize]orRequireAuthorization, secrets in code or config, sensitive data in logs or responses. - Data and concurrency. Multi-step writes without a transaction, read-then-write races on balances, retries without idempotency.
- APIs that exist. Methods, overloads and NuGet packages that look right but don't exist, or exist in another version.
- Performance. Queries inside loops, loading whole tables, missing
CancellationToken, no paging. - Conventions. Does it follow the project's rules (money type, time provider, error style)? Recurring misses belong in your AGENTS.md.
- Can you explain it? If a line is clever and you can't say why it's correct, ask the agent to simplify it or explain it, then decide.
Habits that make review cheaper
- Small steps. Ask for one change at a time; a 200-line diff gets a real review, a 2,000-line diff gets a skim.
- Tests first. When the tests describe the behaviour, the review becomes "are these the right tests?".
- A second pass by a fresh session. Ask a new agent session to review the diff against this checklist before you do. Then do your own.
Pros and cons of a strict review
Pros
- You keep the speed of AI-generated code without inheriting its blind spots.
- Problems are caught when they cost minutes, not after an incident.
- Over time the checklist feeds back into AGENTS.md and the agent makes fewer of the same mistakes.
Cons
- It takes discipline: the temptation to merge "obviously fine" code is strong.
- Reviewing is slower than generating, so it becomes the bottleneck. That's the right bottleneck.
Want a second pair of eyes on an AI-built codebase before it goes to production? See how I can help.
Frequently asked questions
Is reviewing AI code different from reviewing a colleague's code?
The checks are similar, the failure modes are not. A colleague rarely invents an API or silently weakens a test; an agent sometimes does, and writes it all in confident, tidy code. So read more of the diff and trust the summary less.
Can I ask the AI to review its own code?
Yes, as a first pass: ask a fresh session to review the diff against a checklist like this one. It catches a fair amount. It doesn't replace your review, because it shares the same blind spots as the model that wrote the code.
How big should an AI-generated change be?
Small enough that you can read every line in one sitting, ideally a few hundred lines at most. Ask the agent for one step at a time; ten small reviewed commits beat one large unreadable one.