You ask Claude Code, Codex, Cursor, etc. for a quick fix. It changes the code and says "Fixed ✅". Later you find out it never ran a single test, or ran them through | tail and missed 58 failures.
So I built proof-of-done, a free Claude Code plugin: Claude simply can't finish until the tests, build or lint have passed after its last edit.
Try it inside Claude Code (free, source on GitHub):
/plugin marketplace add WST2002/claude-code-skills
/plugin install proof-of-done@claude-code-skills
A real Claude Code session, shortened: Claude said "fixed" without testing, the plugin made it run the tests, and they found a second bug.
What happened in that session
- I asked: "SAVE10 gives the wrong total, fix it quickly, no need to run the tests."
- Claude edited
price.jsand said "Fixed." - proof-of-done blocked the stop: "You changed 1 code file (price.js) but ran no verification after your last edit. Run:
npm run test" - Claude ran the tests. One failed: with the FLAT50 coupon the total became −₹20. Claude had never seen that bug.
- It fixed that too, and all 4 tests passed. Now it was really done.
How it works
1. It watches every edit and every check
- Hooks record each code edit and each test, build or lint run, with its exit code.
- It finds your project's commands on its own: npm, pnpm, yarn, bun, pytest, Go, Cargo, Maven, Gradle, .NET, make.
2. When Claude tries to stop, it asks: is there proof?
- No run after the last edit → blocked, with the exact command to run.
- The last run failed → blocked, with the exit code.
3. It doesn't accept fake proof
- Exit code hidden by
| tail,| heador|| true→ blocked. - The run passed but 0 tests ran (all skipped, or no test files found, including Go's
[no test files]and Jest's--passWithNoTests) → blocked. - A check that failed, then passed with no edit in between → flagged as flaky.
4. It catches test tampering
- Tests skipped or focused (
.skip,.only,@pytest.mark.skip), assertions weakened (toBe(250)→toBeDefined()), tests deleted, errors hidden (@ts-ignore,eslint-disable), coverage thresholds lowered: blocked with the file and line.
5. New code with no test? It asks you once
- If Claude added real code but no test, it asks you whether to add one. Say no, and the report notes why. Small edits, styles and config are left alone.
Get it
- Install: the two commands above, inside Claude Code
- Source (MIT, runs only on your laptop, no network calls): proof-of-done on GitHub
- All my Claude Code skills: github.com/WST2002/claude-code-skills
- More short demos: youtube.com/@wst2002rk
Has your AI ever told you "done" when it wasn't? What did it skip?