Packs / Evidence Gate
Evidence Gate
Hookv1.0.0Refuses to let a task be marked complete while checklist criteria are unchecked or lack an evidence line.
Install
# once per machine curl -fsSL https://hookcrate.com/install | bash # then hookcrate install evidence-gate
Get access
One license covers all packs.
What it does
A Stop + PostToolUse hook that reads your task checklist (an ISA.md / CHECKLIST.md style file with - [ ] / - [x] criteria) and blocks completion when any criterion is unchecked or checked without an evidence: line underneath it. Claude gets a precise list of what is missing instead of a vague "not done". Works on any project: the gate only engages once the checklist declares status: complete (or phase: complete), so it stays silent while work is in progress.
Usage: Keep an ISA.md (or CHECKLIST.md) with `## Criteria` bullets. Add `evidence: <what you observed>` under each checked item. Set `status: complete` when done — the gate verifies before Claude can stop.
When to use this
Use Evidence Gate when the cost of a false "done" is high: deploys, migrations, billing code, anything a colleague will build on tomorrow. Coding agents are optimistic by default — they describe the change they intended, not the behaviour they observed — and a long session makes it easy for "tests should pass" to become "tests pass". The gate turns that habit into a mechanical check: nothing is complete until each criterion is ticked and carries an evidence: line that names what was actually seen (a command's exit code, a test count, a URL that returned 200, a file read back). It is most valuable in three situations. First, multi-step tasks tracked in a checklist file, where the agent edits the checklist as it goes. Second, unattended or long-running sessions, where nobody is watching the transcript in real time. Third, teams that review agent output asynchronously and want the evidence captured at the moment of work rather than reconstructed afterwards. Skip it for throwaway scripts and one-line fixes — the overhead of writing evidence lines is only worth it when someone will rely on the result.
When it triggers
- Stop — every time Claude tries to end its turn
- PostToolUse on Edit|Write — whenever the checklist file itself is modified
Preview — a sample session
Illustrative transcript showing the pack in use.
User: Finish the rate limiter and mark the task done.
Claude: Implemented limiter.ts with a sliding window and wired it into the router. Updating the checklist.
● Edit(ISA.md)
⎿ status: in-progress → status: complete
- [x] Sliding window limiter implemented
- [x] Unit tests cover burst + steady state
- [x] Router returns 429 with Retry-After
⚠ PostToolUse hook (evidence-gate) exited with code 2
evidence-gate: ISA.md declares completion but 3 criteria are unproven.
- line 7: NO EVIDENCE — Sliding window limiter implemented
- line 8: NO EVIDENCE — Unit tests cover burst + steady state
- line 9: NO EVIDENCE — Router returns 429 with Retry-After
Each criterion needs `- [x]` AND an `evidence:` line describing the observed
proof (command output, test count, URL fetched, file read).
Claude: The gate is right — I checked items off without proving them. Running the tests first.
● Bash(bun test src/limiter.test.ts)
⎿ 6 pass, 0 fail [48ms]
● Bash(curl -s -o /dev/null -w "%{http_code} %header{retry-after}" localhost:8787/v1/packs ×61)
⎿ 429 12
● Edit(ISA.md)
⎿ - [x] Sliding window limiter implemented
evidence: src/limiter.ts read back, 61 lines, exported `allow()`
- [x] Unit tests cover burst + steady state
evidence: `bun test src/limiter.test.ts` → 6 pass, 0 fail
- [x] Router returns 429 with Retry-After
evidence: 61st request returned `429` with `retry-after: 12`
✓ PostToolUse hook (evidence-gate)
evidence-gate: ISA.md — 3/3 criteria proven.
Claude: Done. All three criteria are checked with observed evidence; the gate passed and I can stop.
settings.json registration
The CLI prints this after install; --apply merges it for you.
{
"hooks": {
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "bun \"${CLAUDE_PROJECT_DIR}/.claude/hooks/evidence-gate.ts\"",
"timeout": 20
}
]
}
],
"PostToolUse": [
{
"matcher": "Edit|Write|MultiEdit",
"hooks": [
{
"type": "command",
"command": "bun \"${CLAUDE_PROJECT_DIR}/.claude/hooks/evidence-gate.ts\"",
"timeout": 20
}
]
}
]
}
}
FAQ
Will it nag me while the task is still in progress?
No. The gate only engages once the checklist declares status: complete (or phase: complete). While the status is anything else it stays silent, so you can leave items unchecked during the work.
What counts as evidence?
Any evidence: line under a checked item. The hook does not judge the text — it checks that you wrote down what you observed. Good evidence names a command and its output, a test count, an HTTP status, or a file you read back. The discipline is the point.
Can it block forever and lock the session?
No. Claude Code caps consecutive Stop-hook continuations (eight by default), and the hook keeps its message short on repeats. Fixing the checklist or removing status: complete clears the block immediately.