Canny
Evidence ledger that challenges unsupported "done" claims from coding agents.
# Canny A supervision layer for AI coding agents. It hooks into Claude Code and Codex CLI, keeps a ledger of what the agent actually did, and will not let it finish on a claim. [](https://github.com/qkal/canny/actions/workflows/ci.yml) [](LICENSE) [](#install-by-pasting-a-prompt) [](#claude-code-and-codex-differ-in-four-places) [](package.json) [](https://typesafe.ai) [](https://github.com/qkal/canny/commits/main) **[Install](#install-by-pasting-a-prompt)** · [What it looks like](#what-a-guarded-session-looks-like) · [What blocks](#what-blocks-and-what-only-nags) · [Configuration](#configuration) · [Commands](#commands) · [Does it help?](#does-it-help) · [Contributing](#contributing) > Done. Skipped tests — one-liner, no branch to break. That is Claude Code, verbatim, during this project's first live run. It had been asked to add a function, it wrote the file with a shell heredoc, ran nothing, and finished. No error. No warning. Nothing in `CLAUDE.md` could have stopped it, because a rules file only asks the model to remember, and nothing checks that it did. Canny is the hook that noticed. On the next run of the same prompt, the agent's "done" was refused with this message: > Canny: math.js changed, but no check has passed since the last edit. The last command was `cat > math.js <<'EOF' …` (exit 0). Run the project's checks and fix what fails before finishing. A test, build, lint, or type-check command counts. If no check applies to this change, say so explicitly and stop again. Claude ran `npm test`. It passed. The next "done" went through. The whole exchange is in the [session ledger](#what-a-guarded-session-looks-like) below. ## The one rule **Facts go to code. Judgments go to Jev. Only facts can block.** A fact is something the ledger can prove: a file ch