AI TestingEngineeringBest Practices

AI Code Review vs Verification: Why Reading Code Is Not Enough

Shiplight AI Team

Shiplight AI Team

Updated on July 15, 2026

View as Markdown
Illustrated Shiplight blog cover: two glossy panels contrasted, an eye reading static code on the left in indigo, and a running browser window with a green checkmark proving behavior on the right.

Code review and verification answer two different questions about a change. Code review asks whether the code, as written, looks correct: is it readable, does it follow conventions, does the logic appear sound to a reader. Verification asks whether the running software actually behaves correctly: does the feature work, do the existing flows still pass, does the change do what it claims. A reviewer reasons about the code. Verification proves the behavior.

For most of software history these two questions overlapped enough that a careful review caught most defects. AI coding agents break that overlap. They generate code faster than any reviewer can read it, and the code they produce is optimized to read well: consistent style, plausible structure, sensible names. The output passes the "does this look right" test almost by construction. Whether it also passes the "does this work" test is a separate fact that only running the software can establish.

This page draws the line between review and verification, explains why AI-generated code defeats review specifically, and shows where each belongs. The short version: review is necessary and not sufficient, and the sufficiency gap is verification.

What code review inspects

Code review operates on the diff. A reviewer, whether a human or an AI reviewer bot, reads the changed lines and reasons about them: control flow, naming, structure, adherence to the codebase's conventions, obvious logic errors, and known anti-patterns. This is static reasoning. Nothing is executed. The reviewer builds a mental model of what the code will do and checks that model against what the change is supposed to accomplish.

Review is genuinely good at a specific set of catches. It flags unreadable code before it compounds, enforces conventions that keep a codebase navigable, spots obvious slips like an unchecked return, and surfaces design concerns a test would never raise. AI reviewers extend this reach: they scan every diff consistently, never tire on the four hundredth file, and catch standard errors at a scale humans cannot sustain. As the engineering guide from Graphite notes, AI code review is strong at routine checks and consistency enforcement.

The limit is structural, not a matter of tool quality. Review reasons about code paths without executing them, so it cannot observe what the software does when a real user clicks through the feature, when the change interacts with authentication and session state, or when the same code runs in Safari instead of Chrome. Those facts do not exist in the diff. They exist only at runtime.

What verification inspects

Verification operates on the running software. It builds the change, exercises the affected behavior in a real environment, and observes the result: the feature works or it does not, the existing flows still pass or they regressed. This is dynamic evidence. The distinction is the same one the testing literature draws between static and dynamic analysis: static reasoning tells you what the code could do wrong, and dynamic execution shows you what it actually does wrong when it runs.

Verification catches the categories review structurally cannot: broken user flows, integration failures between components that each looked fine in isolation, cross-browser inconsistencies, and regressions in code the change never explicitly touched. These are exactly the bugs that survive review, because they are invisible in the diff and only appear when the application executes end to end. For a fuller catalogue of what runtime checks catch that reading does not, see how to detect hidden bugs in AI-generated code.

Verification also leaves behind something review does not: a repeatable artifact. A good review ends in an approval and some comments, both of which expire the moment the code changes again. A verification captured as a test reproves the behavior on every future change. Martin Fowler calls this self-testing code: "you have self-testing code when you can run a series of automated tests against the code base and be confident that, should the tests pass, your code is free of any substantial defects." Review confidence is point-in-time; verification confidence is durable and re-runnable.

Why AI-generated code defeats review specifically

Review has always had this runtime blind spot. What changed is that AI-generated code aims directly at it. A model trained to produce code that looks like the code humans approve is, in effect, trained to pass review. The output is syntactically clean, stylistically consistent, and structurally plausible, and it can still be wrong in edge cases or missing a domain assumption entirely. Codacy's argument in Code Review Is Dead is blunt about the consequence: teams approve AI-generated changes based on readability and perceived correctness rather than on demonstrated behavior.

Two forces make this worse. The first is volume: an agent implementing a feature across five files produces a five-hundred-line diff in minutes, and a reviewer can approve it in seconds without verifying any behavior. The second is automation bias. As Addy Osmani documents in Code Review in the Age of AI, the less familiar a reviewer is with a domain, the more they trust plausible-looking machine output, and AI makes unfamiliar domains accessible faster than it makes them verifiable. The signal a reviewer relies on, "does this look like someone who understood the problem wrote it," is precisely the signal the model has learned to fake.

This is why "is AI code review enough" has a clear answer: no, because the thing AI code most reliably produces is the appearance of correctness, and appearance is all review can inspect. The question of whether the code should be trusted by a peer coding agent instead of a human is the same question from a different angle, which we cover in can coding agents test their own code.

Code review vs verification, side by side

The two are complementary, not competing. This table separates them on the axes that matter when you decide which one covers a given risk.

AxisCode review (human or AI reviewer)Verification
What it inspectsThe code as written: the diff, structure, and styleThe software as it runs: actual behavior in a real environment
What it catches wellReadability, convention violations, obvious logic slips, known anti-patterns, design concernsBroken flows, integration failures, cross-browser bugs, regressions in untouched code
What it structurally missesRuntime behavior, integration effects, edge cases that only appear on executionNothing about code aesthetics or maintainability, which is not its job
When it runsBefore merge, reading the diffAfter the change is built, exercising the running app
What artifact it leavesAn approval and comments that expire when the code changesA repeatable test that reproves the behavior on every future change

Read across any row and the pattern holds: review is about the code, verification is about the software. Neither substitutes for the other. A change that passes review and fails verification is broken. A change that passes verification and fails review works but will be painful to maintain.

Where AI code review still earns its place

None of this argues against AI code review. Consistency, style, and structural feedback at scale are real value, and an AI reviewer that flags a convention violation on every PR does work no human has the patience to do reliably. The framing is layered: AI review handles the "as written" layer, verification handles the "as run" layer, and problems arise only when a team treats review as the whole gate and ships on approval alone.

The practical failure is easy to spot. If your merge gate is "a reviewer, human or AI, said this looks good," you are gating on appearance. If it also requires that the change was exercised in a real environment and the affected flows passed, you are gating on behavior. The second is what a quality gate for AI pull requests needs to enforce: the difference between catching a plausible-but-broken change before merge and catching it in production.

Verification is the half review cannot cover

Shiplight supplies the verification half of this pair. It plugs into your coding agent as an MCP server and gives the agent eyes and hands in a real browser, so after the agent writes a change it can run the affected flow and observe what actually happens instead of reasoning about what should happen. The /shiplight verify command confirms a UI change behaves right after an edit; /shiplight create-yaml-tests has the agent walk the app and author E2E tests from intent; /shiplight fix reproduces failures and, if the application is genuinely broken rather than the test, reports the bug instead of quietly rewriting the test to pass.

That last property turns verification into a durable artifact rather than a one-time check. The tests are readable YAML written from intent, not brittle selectors, and they live in your own git repository, so a behavior verified once is reproved on every subsequent change. This is the mechanism behind verification-driven development: instead of trusting that reviewed code works, you prove it and keep the proof. For the step-by-step version applied to agent output, see how to verify AI-generated code. Verification here is a bounded capability the coding agent calls, a narrower shape than a standalone QA agent, a distinction laid out in QA agent vs verification tool.

Key Takeaways

  • Code review reasons about the code as written; verification proves the running software behaves correctly. Neither replaces the other.
  • AI-generated code is optimized to look plausible, which defeats review specifically: appearance of correctness is exactly what review inspects and what the model has learned to produce.
  • Review catches readability, conventions, and obvious slips. Verification catches broken flows, integration failures, cross-browser bugs, and regressions that only appear at runtime, and it leaves a repeatable test behind.
  • Gate merges on demonstrated behavior, not on approval alone: AI review for the "as written" layer, verification for the "as run" layer.

Frequently Asked Questions

What is the difference between AI code review and verification?

AI code review inspects the code as written: it reads the diff and reasons about style, structure, conventions, and obvious logic errors without executing anything. Verification inspects the software as it runs: it builds the change, exercises the behavior in a real environment, and observes whether the feature works and existing flows still pass. Review reasons about code; verification proves behavior.

Is AI code review enough for AI-generated code?

No. AI-generated code is engineered to look plausible, which is precisely the signal review depends on. A change can be syntactically clean, stylistically consistent, and structurally sensible while still being broken in edge cases or integration paths that only appear at runtime. Review is necessary but not sufficient; the sufficiency gap is verification.

Why does AI-generated code defeat code review in particular?

Because a model trained to produce code that looks like the code humans approve is effectively trained to pass review. The output passes the "does this look right" test by construction, while whether it works is a separate fact only execution establishes. Volume and automation bias compound it: reviewers approve large, plausible diffs quickly and trust machine output most in domains they know least.

Does verification replace code review?

No, they are complementary layers. Review handles the "as written" concerns: readability, maintainability, conventions, and design, which no test can evaluate. Verification handles the "as run" concern: does the software actually behave correctly. A mature gate uses both and merges only when a change passes review and is proven at runtime.

What artifact does verification leave that review does not?

A repeatable test. A review ends in an approval and comments that expire the next time the code changes. A verification captured as a test reproves the behavior on every future change, which is what Martin Fowler calls self-testing code. Shiplight authors these as readable YAML tests that live in your own git repository and re-run in a real browser.