When Coding with AI, You Get What You Inspect, Not What You Expect
AI coding assistants have changed the economics of writing software.
A developer can describe a feature, accept a proposed implementation, ask for tests, refactor the result, and have a working pull request in minutes.
There is a catch.
The code still has to be correct.
And correctness does not increase at the same rate as code generation.
This creates a new engineering problem, and the sharpest phrasing of it isn't new. It's Admiral Hyman Rickover's:
"You get what you inspect, not what you expect."
Rickover built the U.S. Navy's nuclear submarine program from scratch and ran it for over three decades.
He had zero tolerance for "probably fine." He personally interviewed tens of thousands of officer candidates, demanded that problems get reported straight to him instead of getting smoothed over on the way up, and insisted that one well-chosen detail, traced to its source, tells you more than any status report.
The payoff: over 179 million miles on nuclear power, and never a single reactor accident — not because everyone involved was flawless, but because nothing shipped on the assumption that they were.
That's the same shift AI coding forces on us. A model can be genuinely good and still hand you a plausible-looking bug. The question was never whether it's competent — it's whether anyone actually checked the thing it built.
The difference matters because AI-generated code has exactly the property that makes review difficult: it usually looks finished.
The syntax is valid. The abstractions are plausible. The tests may pass. The explanation sounds reasonable.
The question is whether the resulting system behaves correctly under conditions the prompt did not describe.
That is an inspection problem.
AI can increase the rate of code creation faster than the rate of code understanding
Consider a simple team.
Before AI, suppose four developers collectively produce 8 meaningful changes per day.
Each change takes roughly 15 minutes of senior engineering attention to inspect.
That is:
8 changes/day * 15 min
= 120 min/day of inspection
Now suppose AI-assisted development doubles production:
16 changes/day * 15 min
= 240 min/day of inspection
Nothing about the reviewers changed.
The amount of code requiring judgment did.
This is easy to miss because software development has two different rates:
generation rate
inspection rate
AI primarily attacks the first one.
Humans are still constrained by the second.
You can express the resulting queue very simply:
inspection backlog(t+1)
=
inspection backlog(t)
+
new changes
-
inspected changes
When:
new changes > inspected changes
the backlog grows.
That backlog is not necessarily a list of pull requests sitting in GitHub.
It can be invisible.
An engineer can approve code without deeply understanding it. A developer can run the tests and assume the remaining risk is small. A team can merge changes faster than it can develop confidence in those changes.
That is how expectation becomes a substitute for inspection.
There is evidence that our intuition about AI-assisted development can already diverge from measured outcomes.
In a 2025 randomized controlled trial, METR gave 16 experienced open-source developers 246 real tasks and randomly allowed or disallowed AI tools. The AI-assisted group took 19% longer.
Before the tasks, developers had expected a 24% speedup. After completing them, they still estimated that AI had sped them up by 20%.
The researchers caution that the result does not generalize to all developers or current AI systems, and their 2026 follow-up found strong selection effects that made its newer productivity estimate unreliable.
The important lesson is larger than the number 19%.
What people expect AI to accomplish can differ materially from what the complete system actually accomplishes.
That is precisely why inspection exists.
This problem is older than AI: automation creates new inspection work
In 1983, cognitive psychologist Lisanne Bainbridge published a paper called the irony of automation.
Her observation was that automation does not simply remove human work — it changes it.
When normal operation becomes automated, humans are often left responsible for the unusual cases: failures, degraded states, unexpected interactions, and situations the automation does not handle correctly.
That produces an uncomfortable asymmetry.
The human may spend less time actively controlling the system while becoming more responsible for catching failures in a system whose normal behavior they interact with less often.
The same pattern appears in AI-assisted programming.
A traditional programmer continuously constructs a mental model while writing, moving through each stage in turn.
An AI coding workflow can compress most of that into a single step.
That compression is useful.
But the omitted cognitive work does not disappear. Someone still needs to establish:
Does this implement the intended behavior?
Does it preserve existing invariants?
What assumptions does it introduce?
What happens on failure?
What existing code does it affect?
What happens outside the happy path?
Automation research has repeatedly found that people can also develop inappropriate reliance on automated recommendations.
In controlled experiments, researchers studying automation bias found that people sometimes omitted information they were not explicitly prompted about, or followed automated recommendations despite contradictory information that was available to them.
The mechanism is familiar: once an automated aid is present, it can become a shortcut for active information seeking.
AI-generated code has a particularly strong interface for this problem.
It does not arrive looking broken — it arrives looking like code written by someone who understood the task.
A three-line change can have a million-dollar blast radius
On August 1, 2012, Knight Capital deployed software that interacted badly with an existing defective function in its automated equity router.
The resulting system behavior was catastrophic.
According to the SEC, in the first 45 minutes after the market opened, the system sent more than 4 million erroneous orders while attempting to fill only 212 customer orders.
Knight traded more than 397 million shares and ultimately suffered losses exceeding $460 million. The SEC also found inadequate controls and procedures around code deployment and testing.
The interesting engineering lesson isn't that production software can have bugs — we already know that. It's that the size of a code change tells you very little about the size of its consequences.
Imagine these two changes:
Change A:
300 lines of UI code in an isolated settings page
Change B:
4 lines inside an authorization function
Change A may affect one screen.
Change B could affect every API request in the system.
The relevant quantity is therefore not simply:
lines changed
It is something closer to:
potential impact
*
probability of failure
*
difficulty of detection
This is the idea behind a blast-radius calculation.
A small change at the center of a dependency graph can deserve more scrutiny than a large isolated change.
That becomes especially important when AI increases the number of changes being proposed.
The economics of inspection change when code becomes cheap
Suppose an AI assistant makes implementation 4x faster.
That sounds like an enormous productivity gain.
Now suppose the additional generated code also increases the amount of review work by 2x.
Your economics have changed like this:
The exact numbers are arbitrary, but the structural point is not.
As generation becomes cheaper, inspection becomes a larger fraction of the total cost of software.
This is a standard queueing problem.
If:
lambda = rate at which changes arrive
mu = rate at which changes can be inspected
then a review system is stable only when:
lambda < mu
As lambda approaches mu, waiting time grows rapidly.
So "AI writes 10x more code" is not automatically equivalent to "engineers produce 10x more useful software."
The additional code has to pass through the rest of the system.
The slowest stage increasingly determines throughput.
This is why the next bottleneck in AI-assisted development may not be typing.
It may be verification.
Passing tests is evidence. It is not the same thing as being mergeable.
This distinction shows up clearly in recent AI coding evaluations.
SWE-bench is useful because it gives coding agents concrete repository issues and evaluates whether their proposed changes satisfy automated tests.
But passing the benchmark is only one definition of success.
In March 2026, METR took this question directly to maintainers.
Researchers collected AI-generated pull requests that passed the SWE-bench automated grader and asked active maintainers from scikit-learn, Sphinx, and pytest whether they would merge them.
They examined 296 AI-generated PRs.
The automated grader's success rate was, on average, about 24 percentage points higher than the maintainer merge decision.
METR's conclusion: interpreting a benchmark score as equivalent to "this would pass real code review" overstates what the benchmark establishes.
This is a subtle but important distinction.
Consider a generated patch that does this:
def get_user(user_id, tenant_id):
key = f"user:{user_id}"
if key in cache:
return cache[key]
user = database.load_user(user_id, tenant_id)
cache[key] = user
return user
The tests may all pass.
The function may work perfectly in a single-tenant test environment.
But the cache key has omitted tenant_id.
A multi-tenant production system could now return one tenant's object to another tenant.
The code is syntactically valid.
The local tests can pass.
The implementation can be internally coherent.
And the system can still be wrong.
Testing asks:
Does the system satisfy these tested properties?
Inspection asks a broader question:
What important property might we have failed to test?
Those are different questions.
METR's result makes the distinction concrete: an automated correctness signal and a maintainer's judgment are correlated, but they are not interchangeable.
The writer should not be the only person judging the writing
This is where the architecture of AI-assisted development becomes important.
A coding model has a local objective:
produce a useful solution to the request
An inspection system has a different objective:
find reasons this solution might be wrong
Those objectives are related but not identical.
A useful inspection system should therefore ask questions such as:
What assumptions did this change introduce?
Which existing callers can now behave differently?
What state does it persist?
What happens under retries?
What happens under concurrency?
Which error paths changed?
Which security boundaries changed?
Which tests are missing?
Which repository-specific rules does it violate?
The independence matters because a single generation-and-review loop can share assumptions.
Imagine asking the same model:
"Write this authentication change."
Then:
"Review the authentication change you just wrote."
The second prompt may produce a useful review.
But it is still a review generated from the same context, assumptions, and representation that produced the original solution.
That does not make it useless — it means that independent inspection is a separate engineering control, just as testing, static analysis, observability, and deployment controls are separate controls.
The goal is not to distrust AI — it is to avoid making the generator the final authority on its own output.
AI-native engineering needs an inspection layer
This leads to a simple architecture.
The inspection layer does not need to review every line with equal intensity.
That would recreate the bottleneck.
It should concentrate attention where the expected cost of being wrong is high.
A useful mental model is:
review priority
~ potential impact * likelihood of failure * difficulty of detection
We usually cannot calculate those quantities precisely.
That is fine.
Engineering already uses imperfect proxies everywhere.
A change touching a shared authorization function, persistent state, concurrency-sensitive code, or widely reused APIs deserves more scrutiny than an isolated UI change.
This is the reasoning behind an independent inspection layer such as LiveReview.
LiveReview sits outside the tool generating the code. It can inspect changes at the commit, push, pull-request, CI/CD, and scheduled-review stages, rather than assuming that review happens only when a human happens to open a pull request. The CLI mode is the cheapest of those points: run one command locally, get a review in about 30 seconds, before anything is even pushed.
More importantly, it treats risk as something to prioritize, not just flags.
Its blast-radius model considers how far a change can reach through the call graph, whether it touches persistent state, and how well-tested it is. Its review-priority model considers complexity, nesting, dependencies, and test coverage. In practice that reach is something you can actually see, traced hop by hop from the changed function outward through every caller it touches:
That means a three-line change in a widely shared function can receive more scrutiny than a 300-line isolated UI change.
That is the broader design pattern.
AI makes code generation abundant.
Abundance changes the economics of engineering.
Once code becomes cheap, confidence becomes scarce.
The engineering system therefore needs to make inspection abundant too.
Not because AI cannot write good code, but because no generator should be treated as the final inspector of its own output.
The future workflow may therefore look less like today's default:
And more like this:
The code generator gives you speed.
The inspection layer determines where that speed is safe to use.
And that brings us back to the title:
When coding with AI, you get what you inspect, not what you expect.
How is your team handling the growing gap between the amount of code AI can generate and the amount of code humans can realistically inspect?