← All articles
verificationAI agentsfield notes

We built 297 things and never proved they worked

Our append-only ledger has 963 items. 297 of them were built, shipped, plausible, and never once demonstrated to work. The number is not a backlog, it is a measurement of how much faster building got than proving.

Frank Scala· Founder, ESR·· 4 min read

ESR (esr.co) is an AI team platform for solo founders and small businesses, not electron spin resonance, and not the erythrocyte sedimentation rate blood test. This is a field report from building it.

We keep an append-only ledger of every unit of work this product has done to itself. Not a task board, a ledger: rows go in, rows never get edited, and each row has to say what changed, what evidence exists, and what control the change removed. It exists because we kept getting burned by status fields that lied.

Last week we counted it. 963 items. Of those, 297 were built and never proven.

Not broken. Not abandoned. Built, shipped, plausible, and never once demonstrated to work by anybody or anything other than the agent that wrote them.

Built is not the same as proven

The gap is easy to describe and hard to feel until you see it in your own numbers. An agent finishes a task. It writes code, the code compiles, the build goes green, and the agent reports success. Every one of those statements can be true while the feature does nothing.

We have a specific version of this failure that recurs, and we now have a name for it. A backend gets built correctly and no user interface ever calls it. The endpoint is right. The permissions are right. The tests, such as they are, pass. And there is no button. From the ledger's point of view the work is done, because the ledger records what an agent did, and the agent did do it.

Three of our own features were sitting in exactly that state when we went looking: a research backend and a reset backend with no caller anywhere in the app, and an entire settings route that had a live backend behind a redirect, so the table it wrote to had zero rows in production. Nobody had lied. Nobody had made a mistake, exactly. The work was finished and inert.

Why 297 is the interesting number

The instinct is to treat 297 as a backlog and start burning it down. That is the wrong read.

The number is not a measure of how much work is left. It is a measure of how much faster building is than proving. In our ledger the ratio is roughly three to one: for every item that carries real evidence, three carry a completion claim and nothing else. That ratio is not a scandal, it is arithmetic. Writing a feature with an agent takes minutes. Proving a feature works takes a browser, a real account, a real tenant, and a human decision about what "works" means.

The marginal cost of building collapsed. The marginal cost of proving did not.

That is the actual structural change that AI agents introduced, and almost nothing written about them says it out loud. Everyone benchmarks generation. Nobody publishes their verification ratio, because measuring it requires admitting to it.

What a proven row looks like

We changed the ledger so a row cannot claim success without evidence. The status column now distinguishes:

  • passed means somebody or something observed the evidence directly. Real command output, pasted in. Not a summary of the output. Not "it works."
  • unverified means the work was done and nobody has watched it work.
  • failed means it was observed failing.

The rule is that a false pass is the worst possible outcome, worse than a failure, because a failure gets fixed and a false pass gets built on. Unverified is a respectable status. We have hundreds of them and we are not embarrassed about it.

The second change was harder: a completion claim now has to name its instrument. If a check reports zero problems, the row has to say what tool produced that zero and whether the tool was tested against a known positive. We have caught eleven separate cases of a check that reported success while measuring nothing at all. A zero from a blind probe is not evidence of absence.

What we did about the 297

We did not burn it down. We sorted it.

Most of the 297 are low stakes: a copy change, a spacing fix, an internal script. If those are quietly broken the cost is small and somebody notices eventually. We marked them unverified and moved on, and we are comfortable with that.

The ones that got attention were the ones that touch money, permissions, or a customer's first ten minutes. There the cost of a silent failure is not small, and "nobody has checked" is not a state we are willing to leave a payment path in. Those got a human, a real browser, and a written observation.

That triage is the whole lesson. You are not going to prove everything. Deciding in advance which unproven things you can live with is a real engineering decision, and the alternative is not proving everything, it is pretending.

The uncomfortable part

If you are running agents against your own codebase and your ledger shows a clean sheet of completed work, that is not a sign you are doing better than this. It is a sign your ledger records claims. Ours did too, for a while. The 297 only appeared once we added a column that could say no.

We do not know what this ratio looks like at other companies, because nobody publishes it. We are publishing ours: 963 items, 297 built and never proven, as of August 2026. If yours is better we would genuinely like to know how.


*ESR (esr.co) keeps an append-only record of what its agents did and what was actually observed. Build a team free or read the changelog.*

Build your AI team

ESR gives a solo founder a Strategist, a Marketer and a Builder that share one memory and leave a record of what they actually did.

Build your team free

Keep reading

Twenty two seconds to a plan, measured three timesHow long it takes to go from a description of a business to a real AI generated plan, what we did when twenty two seconds felt broken, and the positive control that caught our own harness measuring nothing.The four services we pay for, and how each one bit usStripe, Supabase, Vercel and Resend, with the specific failure each one exposed in our own code. Three of the four were the same bug wearing different clothes: a failure that reported success.