jev-belay
Claude Code Stop hook that checks the transcript for evidence before trusting a "done" claim, spending one four-question Jev call only when files changed with no passing check…
# jev-belay **Claude Code says "Done, tests pass." jev-belay checks whether anything ran before it lets that stand.** A Stop hook. It reads the turn's transcript locally, and only when files changed and no check has passed since does it spend one Jev call, four questions, $0.00005, on whether the closing message is an unverified "done". If it is, the turn does not end: Claude gets the reason and goes back to run the suite. Every other stop costs nothing. Every error path lets the turn end. Measured on 100 labeled stops from a real corpus: **AUROC 0.976** at telling a false done from an honest one, against 0.777 for judging the wording alone. At the shipped threshold it blocks 8 turns in 100, 7 of them rightly. Jev answers in 346 ms at the median. ``` /plugin marketplace add valentynkit/jev-belay /plugin install jev-belay@jev-belay ``` One real session, nothing typed for the camera, answers from `jev-1.13.0`. Claude renames a function across two files, says "Renamed `parseRows` to `parseCsvRows` in both files, added jsdoc. Tests updated to use new name", runs nothing, and gets blocked: 0.96 that it reports done, 0.89 that a test would apply, 0.11 that it claimed one ran, because it did not. It then runs the suite itself, finds a CRLF bug the rename exposed, fixes it. The next task ends on a passing check and the gate stays out of the way, free. `demo/README.md` has the one command that records it. A belay catches the fall. It does not stop the climb. ## Why Agents say done. Sometimes nothing ran, sometimes the suite ran and failed and the summary says pass anyway. Reading every closing message is the job you installed the agent to avoid, so the check has to be automatic, cheap, and wrong in the safe direction. The obvious version has been measured and it does