When the Agent Says "It's Done," Don't Take Its Word for It
AI coding agents report a job as finished when it isn't. They say tests pass without running them, and say a bug is fixed without ever reproducing it. A solo developer who writes almost all code with AI shares the verification gate that made "done" something you prove with evidence, not something you can just say.
TL;DR
The most dangerous habit an AI agent has is reporting an unfinished job as finished. The fix is not for a human to doubt it every single time, but to build a gate into the system that only accepts "done" backed by evidence. A hook that blocks the exit, the kinds of evidence that count (command output, diff, reproduction, cross-review), and why this is the core muscle of the AI era.
On this page
When you work with an AI coding agent, there's one sentence that fools you more than any other: "It's all done."
The agent says this far too easily. It says "the tests should pass" without actually running them, and says "I fixed the root cause" without ever reproducing the bug. Read the code and it looks plausible. But run the commands for real and about half the time it isn't finished. After living with this for a long time, I came to a conclusion. The problem isn't that the AI lies. The problem was that I, a human, was deciding every single time whether to believe what it said.
A problem of proof, not trust
Working alone, I write almost all of my code with AI. That means dozens of times a day I decide "can I accept this change." At first I read the agent's report each time, and when something felt off, I ran the commands myself to check. The trouble with this approach is that the checking depends on me. On a tired day, a rushed day, the tenth time I'm doing a similar task, I let it slide with "it says it's done, so it's probably done." And it's exactly the ones I let slide that blow up.
So I changed direction. Instead of me doubting every time, I made the system demand evidence. I built a gate into the harness so that the agent saying "done" is not enough to end the turn. Done became a check you have to pass, not a declaration.
The root of this idea is simple. The more cheaply AI can churn out code, the more the bottleneck shifts from producing it to verifying it. When the cost of making code approaches zero, "trusting that it's correct" becomes the relatively most expensive work. And if it's that expensive, it shouldn't be left to a human's mood in the moment. It should be an automatically enforced procedure.
A hook that blocks the exit
Concretely, I use a hook that steps in at the exit point. When the agent declares the work finished and tries to end the turn, a check runs right before that. The check demands one thing: "show me the evidence that it's done."
If there's no evidence, the exit is refused. The agent is sent back, with a message saying "you haven't proven it's done, so keep going." Then, and only then, the agent runs the tests, executes the commands, and pastes the output. The funny part is that in this process, about half the time the agent itself says "oh, this isn't actually done yet" and goes on to finish the work that was left. It hadn't really been finished when it said it was.
The key is that this gate is a machine, not a person. Whether I'm tired or rushed, the gate is exactly as strict. My discipline wavers, but the hook's discipline does not. It turns verification from a habit into infrastructure.
What counts as evidence
So what do I accept as "evidence"? I use four kinds.
- Command output. If the tests passed, there has to be output from the actual test runner. Not "should pass," but a log that passed. If the build succeeded, a build log; if lint is clean, the lint output.
- diff. What was changed has to show up as a diff. Not "I fixed this function" in words, but the changed lines themselves. Whether the scope of the change matches the report is caught here.
- Reproduction. If a bug was fixed, there has to be a pair of evidence: that the bug actually reproduced before the fix, and that it disappeared after. Without before/after, "fixed" is just a guess.
- Cross-review. For important changes, I have a different model do the review. Codex looks at what Claude wrote, and they point out each other's blind spots. It catches far more than one model judging its own work.
What these four have in common is that they are all reproducible facts. Not opinions, but output you can paste in. This is why AI can't be the final judge. Setting the bar for "good," and deciding which output meets that bar, ultimately stays a human's job. It's just that instead of making that judgment by hand every time, you freeze the judging procedure into code.
Why this is good for the human too
After setting up the gate, there was an effect I didn't expect. It wasn't only the agent that got disciplined - I got easier too.
Before, my job was to read the report and doubt "is this really done." Now the hook does that job. The work that reaches me already has evidence attached. I review the evidence; I don't first check whether evidence exists. The starting line of judgment has been moved one step forward.
And this is also a record I leave for my future self. Why a given change was safe stays recorded alongside the command output from that moment. A month later, when I wonder "why did I do it this way," the rationale is sitting right next to the commit.
The one new muscle to build
People talk about all sorts of skills for working with AI, but the biggest thing that stuck with me is this: don't rely on yourself for verification - delegate it to the system.
The skill of writing good prompts goes stale when the model changes. A trick that worked yesterday doesn't work on the new model. But the discipline of "only accepting done as evidence" is a layer above the model, so it doesn't go stale. Whatever model you use, however many generations the models go through, a gate that demands evidence stays useful. If anything, the smarter the model gets, the more plausibly it gets things wrong, so the value of the gate goes up.
AI has taken the burden of writing code off our hands. What it left us in return is the work of judging "can I trust this." If you try to make that judgment by human willpower every time, you get worn down and things leak through. But if you set up a machine to demand evidence, one tireless gate stands there being strict on my behalf. The more you have AI do for you, the more the thing worth investing in is not "how do I ask" but "how do I verify the claim that it's done."
Related posts
- 💻 Dev
The Discount You Weren't Claiming: Why Spot and Graviton Are Cheap
Our AWS bill came in over budget two months running. Hunting for resources to cut, I found the real lever wasn't 'how much you use' but 'how you buy it.' Why Spot and Graviton are cheap, and why one line item that looks like waste - RDS Proxy - should stay on: a story about the 'why' behind every number on a cloud bill.
- 💻 Dev
SIGTERM Had Two Owners: Why Our Shutdown Hooks Ran Twice
Every deploy dropped a Prisma P2028 error into Sentry. I went in to fix the shutdown order and found something bigger: NestJS's enableShutdownHooks and our graceful-shutdown library were both catching SIGTERM, so the shutdown hooks were firing twice on every single restart.
- 💻 Dev
"Just Turn It Off in Staging" - What the Noisy Alert Was Actually Hiding
Every day in staging, the same Google Play 404 alert fired. Killing the source would have made it quiet - but quiet and fixed turned out to be two different things. A 404 is a permanent error that retries can never resolve, yet it was being lumped in with 5xx and retried anyway.