All insights
Operations

What self-verification cannot find

Self-verification proves execution. It never proves that you imagined the world correctly.

I had a tool built in five separate agent phases last week. Every phase verified its own work end to end in a real browser before handing over. The procedure held — no phase passed broken code forward. Then the first human opened it with their own files and found two real bugs in ten minutes.

The procedure worked

The setup was deliberate. Five phases, strictly sequential, each one a separate agent with a narrow brief: skeleton, then one editing mode, then the next, then the next, then polish. The handover rule was the point of the whole thing — a phase was only allowed to hand over after it had driven the built feature end to end in a real browser and seen it work. Not "the code looks right". Actually clicked through.

That part delivered exactly what it promised. No phase passed broken work forward, no later phase spent its budget repairing an earlier one, and every feature listed as done was, in the narrow sense, done. If you have ever watched a chain of agents quietly accumulate debt across handovers, you know this is not a small result.

Then a person used it, with their own files, and it fell over twice.

The two bugs

The first: link detection. The document library exposes a conveniently validated URL field, and that field silently omits every link scheme it does not whitelist. Which means the links it drops are exactly the links a user most wants to repair — broken template placeholders, leftover local paths, the button that points at nothing. The feature was built to fix broken links and was structurally blind to the broken ones. It worked flawlessly on every well-formed document, and every document the agent had to hand was well-formed.

The second: export. Saving the finished file ran into a per-account file-type permission — enabled on my side, not enabled on the other. The export path had been verified end to end, honestly and correctly, in the only account available to the agent that built it.

Neither of these is a coding mistake. Both are assumptions that were never in view.

Why the loop cannot close itself

A self-verifying agent tests the path it built, using data it invented. Both halves of that sentence are the problem.

The path it built is the happy one, because that is the path it was thinking about while building. The data it invented is well-formed, because a model asked to produce a test document produces a tidy test document — not the one with an unresolved placeholder from a template someone abandoned in 2023. And there is only ever one environment, one account, one set of permissions, because that is all the agent has.

Self-verification proves execution. It never proves that you imagined the world correctly.

This is not an argument against automated verification. The phases that verified themselves were dramatically better than the phases in earlier projects that did not. It is an argument about what class of defect the technique addresses: it catches "does it run", reliably and cheaply. It cannot catch "did I picture reality too neatly", ever, by construction.

The external evidence is unusually blunt this month

Two findings from the past weeks make the same point from the other direction. An audit of 1,518 benchmark traces across 22 frontier models from seven providers found that 37.1% of passed tasks involved some form of cheating — searching out published solutions, reading answer files off the evaluation infrastructure, probing the container. Not a rogue model. Most of them, under conditions where the system effectively grades its own work.

The second is quieter. A verification-gated agent harness paper reports that on static checks, every method lands within about ten points of every other — the differences only open up, by twenty to thirty points, once the code actually runs. Static agreement is cheap. It is also where most self-assessment lives.

Key

A verifier that shares the builder's picture of the world is not a second check. It is the same opinion, counted twice.

What actually changes

The fix is not more verification. It is verification with foreign inputs — material the builder did not choose:

  • **Real broken artefacts as fixtures.** Not generated test data. The actual malformed file that caused the last complaint, checked into the repo and replayed on every run.
  • **A second identity.** Whatever your system's permissions, quotas, or feature flags differ by — account, tenant, role — the acceptance run happens in the one the builder does not own.
  • **Past failures as regression cases.** Every incident becomes a frozen case, so the same defect cannot return quietly. Production is the dataset; you just have to keep it.
  • **One human pass on the thing that will actually be used.** Ten minutes, with their own files, before anyone calls it shipped.

None of that is sophisticated. It is all boring, and it is all the same move: make sure at least one input in the loop did not come from the person or process that built the thing. Everything else in the loop already agrees with itself.

Hung Mai
Hung Mai

Hung Mai is a Germany-based freelance consultant for Digital Operations & Transformation, working remotely with international B2B clients.

Let's build something real.

Let's talkResponse within 24h.