# Your coding agent has never once told you it failed
Ask it if it's finished and it says yes. It has said yes every time, on every task, since the day you started using it — and if you think back, you cannot name the occasion it stopped and told you the work was not done.
That is not because the work was always done. It is because nobody in that session has any reason to say otherwise. The run that wrote the code is the run that reports on it, and "tests pass, all criteria met" costs an agent nothing to say. There is no cheaper sentence in the language.
oh-my-agent (first-fluke/oh-my-agent, MIT, 1,268 stars and 146 forks as of 2026-09-05, last pushed 2026-09-04) is a free harness that stops reading the claim and goes and looks at the files. Its own line for this is worth stealing: *agents narrate success; it checks the artifacts.*
Install is one line:
bunx oh-my-agent@latest
## The four checks, and what each one mechanically does
Every one of these is a command exiting 0 or a file being on disk. No model is asked whether the work "looks correct" at any point.
1. A stop hook holds the session open while your tests are red. The hook runs your project's own gate script before it will let the session end. Only three keywords are executable — typecheck, test and lint — and anything else an agent writes into the state file is ignored and never run. It is capped at five reinforcements so a permanently red gate cannot trap you in a loop.
2. `oma ralph:verify --json` hunts four artifacts a shortcut cannot fake. A prose instruction like "run the full workflow" is advisory and can be rationalised away; artifacts cannot. The command looks for a phase-completion record, a plan JSON, a result file from a distinct QA agent, and a result file from a distinct refactor agent. Two of those are absent the moment a single agent shortcuts the work, no matter what the narration says. The repo is blunt about the precedence: the JSON verdict is the gate result, and you do not proceed on a non-zero exit.
3. A judge spawns with the checklist and nothing else. It is a separate agent that starts with an empty context window. It receives the criteria table and the verification protocol — never the implementer's account of what it fixed. Independence here is structural rather than a role instruction in a prompt.
4. It re-checks every box every round. Including the ones that already passed, because fixing C4 is how C1 silently breaks. That case has its own status in the protocol: a criterion that passed at iteration 1 and fails at iteration 2 comes back REGRESSED rather than plain FAIL, emitted exactly once on the transition. Three consecutive failures and a criterion is marked BLOCKED and retried no further.
The catch, stated plainly
The stop gate can only run those three scripts. Whatever else your agent decides its gate should be, the hook will ignore it. And nothing in this loop can judge whether the thing you built is any *good* — mechanical verification tells you a command exited 0, not that the design was right. That judgement is still yours, and always will be.
It also brings no model. You need an agent CLI you already pay for; the harness projects one portable .agents/ directory into whichever runtime you use.
The free thing
checker.py — one file, zero dependencies, Python 3.8+ — audits a repo for exactly the traces above and exits non-zero when they are missing. Read-only: it opens files and prints a verdict, it never writes, installs or runs anything of yours. Drop it in a pre-push hook and your own repo starts disagreeing with your agent.
Comment CHECKER and it's yours.
