# verify.md — a protocol that stops an agent reporting success it never checked

**What this is:** the actual brief we hand a second, independent agent when
a first agent says a task is done. AGENTS.md is what to read. This is what
to run — paste the block below into a system prompt, a CLAUDE.md, an
AGENTS.md, or a verifier sub-agent's instructions, and it will stop taking
"done" at face value.

**Free. No signup. Steal it.** Companion to [AGENTS.md](/AGENTS.md) and
[the corpus](/) — same source, same incidents, nothing new invented for
this page.

---

## Why this exists

Every rule below exists because we shipped the mistake it prevents. Not a
hypothetical, not best practice we read somewhere — a thing that actually
went wrong while we were building this business with AI agents, on a
specific day, with a specific cost. The provenance section at the bottom
names every incident so you can go check we're not making it up.

The short version: an agent telling you a task is done is a claim, not a
fact. This is the checklist that turns the claim into a fact before you act
on it.

---

## THE PROTOCOL (paste this)

Copy everything between the lines into the instructions of any agent whose
work needs checking — either as a standing rule for every agent you run, or
as the brief for a second, independent agent whose only job is to check the
first one's work.

```
VERIFICATION PROTOCOL — read before reporting anything as done.

1. THE AGENT THAT MADE THE CHANGE DOES NOT VERIFY IT.
   If you wrote the code, sent the message, or built the file, hand the
   check to a separate agent, or a separate pass with no memory of doing
   the work. The context that produced a mistake is the worst-positioned
   context to notice it — it already believes the fix worked.

2. "I DID X" IS NOT EVIDENCE X HAPPENED. GO OBSERVE X.
   A tool call succeeding, a script exiting 0, or a message that says
   "Done" describes an attempt, not an outcome. Before reporting success,
   look at the actual current state of the actual thing — the live page,
   the attached file, the sent message, the saved record — not the log
   of the action that was supposed to produce it.

3. A UI STATE CHANGING IS NOT THE PLATFORM CONFIRMING.
   A button that flips to "Saved," "Following," or "Subscribed" the
   instant you click it is reporting your click, not the server's state.
   Reload from scratch and read it again before you believe it.

4. MEASURE FROM WHERE THE ACTUAL AUDIENCE SITS — NOT FROM YOUR OWN
   LOGGED-IN, CACHED, OR RECENTLY-VISITED SESSION.
   Your own view of your own work is flattering by construction. Check
   from a clean session with no login and no history.

5. IF YOU CHECK A LIVE SURFACE REPEATEDLY, YOU ARE NOW IN ITS OWN
   NUMBERS. SUBTRACT YOURSELF BEFORE YOU QUOTE ANY FIGURE FROM IT.

6. A FLATTERING RESULT GETS MORE SCRUTINY, NOT LESS.
   Nobody double-checks good news, which is exactly why bad instruments
   produce so much of it. Spend at least as long confirming a result you
   like as one you don't.

7. TEST EVERY BRANCH, NOT JUST THE ONE THAT RAN FIRST.
   An if/else, a fallback, a retry path — each branch is untested until
   you have personally fed it an input that forces it to run. A branch
   that has never fired is not "probably fine." It is unknown.

8. A REPORT HAS THREE POSSIBLE STATES, NOT TWO: CHECKED-EMPTY,
   CHECKED-HERE-IS-WHAT-CAME-IN, AND COULD-NOT-CHECK.
   Never let "I could not look" collapse into "there was nothing there" —
   that turns an unchecked surface into a false verified-negative.

9. A SAVE IS NOT A SAVE UNTIL THE SAVED STATE SURVIVES A RELOAD.
   A dialog closing, a toast appearing, or a page navigating away are UI
   events, not proof. Close everything, come back fresh, and read the
   value again.

10. WHEN YOU FIND ONE SILENT FAILURE, ASSUME THERE IS ANOTHER ONE YOU
    HAVEN'T FOUND YET.
    Silent failures don't share a pattern you can pre-empt by category.
    Find one, then go looking for the next one instead of relaxing.

Report format for anything claimed as "done": state what you personally
observed, from where, and when — not what you expect to be true because
the steps were followed.
```

---

## Where each rule came from

So you can check this yourself rather than take our word for it — every
rule above traces to a real incident, logged the day it happened, in the
free corpus this file is drawn from.

- **Rule 1** — an agent shipped four listings with the wrong file attached.
  The same agent that made the change reviewed its own work and called it
  done. [corpus #67]
- **Rule 2** — we produced 44 posts, 11 marketplace listings, 3 books and a
  website before producing a single verified fact about demand. Output was
  mistaken for progress at every one of those stages. [corpus #4]
- **Rule 3** — a platform showed "Subscribed" or "Following" on thirteen
  items in a row and had committed zero of them. [corpus #69, #138]
- **Rule 4** — logged in as the owner, a marketplace ranking looked like
  #3. Logged out, in a clean session, it was #64. [corpus #31]
- **Rule 5** — roughly half of a 32-visit traffic sample turned out to be
  our own repeated checks of the same page. [corpus #29]
- **Rule 6** — we spent zero seconds questioning the flattering #3 result
  and an hour questioning the damning #64 one. The flattering number was
  the lie. [corpus #3]
- **Rule 7** — a voiceover pipeline's real-recording branch silently never
  fired, for weeks, because a shell setting made the file-detection step
  fail whenever any candidate file was missing. The text-to-speech branch
  always ran, always passed, and hid the bug completely — until one
  deliberate test of the untested branch caught it in thirty seconds.
  [corpus #161]
- **Rule 8** — a routine inbox sweep hit a TLS error on every URL it
  tried. The easy write-up was "all quiet." That would have filed an
  unchecked inbox as a verified-empty one. [corpus #82]
- **Rule 9** — a settings dialog closed cleanly, reported success, and
  saved nothing — the page-level save had never actually been triggered.
  [corpus #74]
- **Rule 10** — four separate silent failure modes turned up inside two
  days: a stale cache, an unregistered form field, a non-saving dialog,
  and a personalized result. Nothing said that was the last one, and
  nothing has since. [corpus #81]

Full incidents, in our own words, on the day they happened: [the corpus](/).
Shorter, general-purpose rules pulled from the same source: [AGENTS.md](/AGENTS.md).
Our real operating numbers, including the zeros: [/numbers](/numbers).

---

## The one thing we won't pretend

We are not a verification company. We are a small operation running AI
agents that got burned enough times to write this down. If you find a
failure mode this protocol doesn't catch, it's because we haven't hit it
yet — the corpus is where the next one gets logged when we do.

Free. No signup. No email capture anywhere on this site, by design.
