Who Verifies the Agents?
How agents can verify AI-generated code through layered checks, deployment, end-to-end testing, and exploratory use.
A couple of weeks ago I published a post about how nothing stops the train — how, when execution gets cheap, the process we built to protect expensive code becomes the most expensive thing in the system. The reaction was about what I expected. A fair amount of "yes, finally," and a steady stream of "good luck with that."
The good-luck crowd all pointed at the same thing. Sure, it sounds nice in theory. But in practice you'll hit the bugs. You'll hit the production incidents. Your customers will complain, and the first thing you'll do is quietly reinstate all the gates you tore down. And underneath every version of that objection is one core claim: you cannot let agents verify their own quality. It won't be good enough. It can't be.
First, the uncomfortable math
Before I defend agentic verification on its merits, I want to name the thing that makes this whole debate feel different from a normal engineering argument: we don't actually have a choice.
In the world we're now in, there is no version of events where a human reviews every line of code. The math doesn't work. In a single night, while I sleep, my agents can produce more code than I would have written in a month. If I then spend the next several days reading all of it, sure, I'm technically still ahead of my old self — but barely. And I'm nowhere near the pace I could be moving at.
Worse, I'm nowhere near the pace of the competitor who decided not to read it.
That's the uncomfortable part. Somewhere out there — probably at a company much smaller than yours — people are already shipping without line-by-line review. They are not doing it by abandoning quality; that would be suicide and it wouldn't last a week. They're doing it some other way. The question isn't whether to give up manual review. That's happening with or without your permission. The question is what you replace it with.
The answer is verification flows.
Verification was never the human part
Here's the reframe that makes the rest of this obvious. Ask what a human actually does to convince themselves that code is good.
They run the linter — usually without even noticing, right there in the editor. They compile it. They run the unit tests. They run the integration tests. They do a code review. They deploy it somewhere and click around. Maybe QA clicks around too.
Notice how little of that is really the human. It's the human invoking tools and running procedures. Verification was never only the act of a person staring at code and blessing it with their judgment. Verification is a stack of assessments, checks, and tests. The person was just the one pressing the buttons.
So the entire move is this: take everything you were already doing to verify, and hand the button-pressing to the agent. Nothing about the standard of quality changes. What changes is who runs the loop.
The layers, from cheapest to most convincing
The reason this works is that verification isn't one gate — it's a gradient, and each layer is a stronger signal than the last. An agent can climb the whole thing.
Start at the bottom, where it's nearly free. Linting. Basic structure and style. An agent runs it and fixes what it finds. First layer of protection, essentially for nothing.
Next, compilation — in any language that compiles. This one is underrated. A failed compile is an unambiguous "this is broken," and a clean compile is a real, if partial, signal that things are heading the right way. The agent reads that signal exactly the way you would.
Then tests, and this is where it stops being a chore and starts being an advantage. Unit tests. Component tests. Integration tests. Acceptance tests. But go further than that. Because the agent is doing the work, you can enforce things you would never have had the patience to enforce as a human — coverage targets, edge-case matrices, whole testing strategies you'd have written off as too tedious to maintain. Write any kind of test the project calls for, and write a lot of them.
And here's the catch. The agent is writing the tests because you can't review all the code — which means you can't review all the tests either. So where does the human fit? In the one place with the highest leverage: the test plan. Have the agent lay out what it intends to verify before it starts, or document what it verified after it finishes, and review that. It's the smallest possible artifact that still tells you whether the agent understood the job.
And even the test plan review fades over time. Early on, in sensitive areas, you read it. But as the codebase matures — as it accumulates its own rules and coverage expectations and the agents that maintain them — the system starts holding its own standard. New code gets coverage because the static analysis demands it, not because you asked. Before long you're only reviewing test plans for genuinely big moves: major features, real architectural shifts. The everyday features verify themselves.
Deployment is where it gets real
Everything above still lives in the comfortable, offline world of "does it build and do the tests pass." The thing that turns verification from reassuring into convincing is deployment.
Actually deploying the code is one of the strongest quality signals there is, because it exercises everything the offline checks can't — migrations, configuration, the way the pieces behave when they're wired together for real. And if you can afford it, don't deploy once. Deploy clean, to prove it stands up on a fresh system. Then deploy as an upgrade over the previous version, to prove you didn't break the path your existing customers will actually take. Two deployments, two very different classes of bug caught.
Then, on that live environment, you run the real thing: full end-to-end tests that drive the actual interface — the browser, the API, whatever surface the product exposes. This is the level of testing you were ultimately paying humans to do by hand, and now a single developer's agent can trigger a deploy and, inside that deploy, run the entire pyramid — unit, integration, end-to-end — against a real environment, in a loop, fixing and redeploying until it all passes.
Then you let the agent try to break it
Passing your predetermined tests is table stakes. The interesting part is what an agent can do that a fixed test suite never could: behave like a person.
Once everything deterministic is green, you turn a fresh agent loose on the running system with a much looser brief. The first and most important instruction is almost embarrassingly simple: read the spec for what we just built, then go use it and confirm it actually does that. The agent opens the app, exercises the feature, calls the endpoints — and it catches the gaps. The things that were specified but not really built. The rough edges. The UI that technically works but doesn't feel finished.
And you don't have to stop at the spec. Layer on more of these non-deterministic passes. Tell the agent to hunt for edge cases. Tell it to hold the UI to a high bar of polish. Tell it, plainly, to try to break the thing. Run all of it in a loop, so every time it finds something, it fixes, redeploys, and rechecks. This is the piece a static suite fundamentally cannot give you: simulated human interaction, at a scale and patience no human tester could sustain.
What the finished loop looks like
Put it all together and here's what you end up with. The agent wrote the code. The agent wrote the tests. A human may or may not have glanced at the test plan. Then the agent ran layer after layer of verification — lint, compile, unit, integration — actually deployed the result, ran deterministic end-to-end tests against the interface, and finally ran non-deterministic user-simulation passes to find whatever the scripted tests missed. Every failure fed straight back into the loop. Code, verify, fix. Code, verify, fix. Until it holds.
Where I personally land, in my own projects, is this: for anything that isn't a major new feature, I trust that loop and go straight to production. For a major feature or a significant shift in the experience, I add exactly one human step at the very end — and it is not reading the code. The code is already deployed to an integration environment; the latest version is sitting right there, running. So I go there and I use it. I don't try to enumerate every scenario. I run a handful of real manual tests until I'm satisfied it does what it was meant to do and feels the way it should. Then I merge the PR.
"But is the quality actually lower?"
This is the question the whole objection rests on, so let me answer it as directly as I can: no. In my own experience, the quality coming out of this loop is not lower than what I was shipping under the old manual regime.
And that shouldn't be surprising, because the old way was never as pristine as nostalgia makes it. Manual testing requires testing. Automation requires testing. Human review misses things constantly. None of the old gates were free of error; they were just ours, so we trusted them. All this loop does is take the things you were already doing and give the agent the authority to run them, over and over, without getting tired or bored or sloppy on the fortieth pass.
The concrete rhythm, for me, looks like this. I take a reasonably large feature, set it up before bed, and go to sleep. In the morning I open the browser and use it. If there are gaps, I have them fixed — usually within a couple of hours. And then that entire feature is merged to production at a quality I'm genuinely comfortable with. Not degraded. Comfortable. And I'm free to move on to the next one.
One caveat, this is all very new. I don't have the long-run data to prove it holds up over years, across teams, at scale — nobody does yet. All I have is my own experience so far, and so far it works. If anything I'm optimistic about where it goes, not nervous, because the whole thing rides on how good the models are, and they keep getting better. A loop that works well enough today should only get better as the agents underneath it do.
That's the whole answer to "you can't let agents verify their own quality." You're right that an agent blessing its own code with a shrug would be worthless. But that was never the proposal. The proposal is to take the entire apparatus of verification you already believe in — the linting, the compiling, the tests, the deployments, the end-to-end runs, the exploratory poking — and let the agent operate it in a loop you designed. The human doesn't leave the system. The human moves to the top of it: setting the standard, reviewing the plan for the things that matter, and taking one last real look before the biggest changes ship.
Verification is always worth it. It just doesn't have to be you pressing the buttons anymore.