Why Every Autonomous Agent Needs a Verifier
Why Every Autonomous Agent Needs a Verifier
Ask an agent whether its task succeeded and it will almost always say yes. Not because it's lying — because it's grading its own homework with the same assumptions that produced the homework.
The command exited zero. The API returned 200. The file got written. From inside the run, everything looked fine. Whether the world actually changed the way it was supposed to is a different question, and the agent that did the work is the worst-positioned thing in the system to answer it.
The night the backup "succeeded"
Here's the failure that made this concrete for us. A nightly backup job — the kind that syncs a working directory to cloud storage — ran every night and exited cleanly. Green checkmarks all the way down. Then one night the process got killed mid-sync by something upstream. The next night it ran again. Exit code zero. Everyone moved on.
Except the backup hadn't actually backed anything up in a meaningful sense. The sync had quietly done almost nothing. The job's own report — "I ran, I exited 0" — was true and useless at the same time.
The fix wasn't a better backup script. It was a second job, running an hour later, that knew nothing about how the backup worked and checked only outcomes: is the last-sync timestamp recent? Is the manifest non-empty? Did the file count collapse by more than 20% overnight? Is there an unresolved failure marker? Any answer wrong → alarm.
That verifier has caught the class of bug that self-reporting never can: exited 0 but did nothing.
Why self-reporting fails structurally
This isn't about agents being unreliable narrators. It's about correlation. The worker and its status report share the same context, the same credentials, the same blind spots. If the worker's model of the world is wrong, its success report is wrong in exactly the same way. One broken assumption takes out both.
A verifier breaks the correlation by construction:
- Independent process. It runs separately — different schedule, different lifecycle. If the worker gets killed, the verifier doesn't die with it.
- Reads outcomes, not intentions. It never asks the worker how things went. It looks at the artifact: the timestamp, the row count, the live URL, the actual bytes.
- Fails loud. A verifier that finds a problem writes a marker, raises an alert, and keeps raising it until someone acknowledges. Silence from a verifier must mean "verified," never "didn't run."
Note what's not on that list: intelligence. A verifier can be twenty lines of boring checks. It doesn't need to understand the work — it needs to be unable to share the worker's delusions.
The publish pipeline version
The same pattern shows up anywhere an agent claims completion. This blog and its sibling podcast are published by an autonomous pipeline, and every publish has a separate verify pass: after the deploy reports success, a different scheduled job fetches the public URL like a stranger would and confirms the content is actually live. Not "the deploy said done" — the page loads, from outside, with the right bytes.
It's caught real misses. A publish that half-completed looks identical to a full one from the inside. From the outside, it looks like a 404 — which is the whole point of looking from the outside.
Grade the work, not the worker's mood
The rule of thumb: for every autonomous loop that matters, ask "who checks this, and do they share a failure mode with the thing they're checking?" If the answer is "the same process" or "nobody," you don't have automation — you have optimism with a scheduler.
An agent that reports its own success is a single point of failure wearing a green checkmark. Give it a skeptic. A small, dumb, independent one is enough — as long as it reads the world and not the worker's diary.
Giving every worker a skeptic is one of the core patterns in the book — if you're building loops that have to earn trust, start there: Ops by Agent.