qkal

Canny — AI skill for Claude Code

AI community

Stops AI coding agents from claiming work is done without evidence.

How to install Canny

This entry records only its repository, not the path inside it, so there is no exact command to give. Open qkal/Canny and copy the folder into ~/.claude/skills/, or the file into ~/.claude/agents/.

What Canny does

Stops AI coding agents from claiming work is done without evidence. Deterministic hooks decide, TypeSafe's Jev advises. Append-only ledger, zero runtime dependencies.

Alternatives in AI

  • Open Multi Agent — TypeScript multi-agent orchestration engine — one runTeam() call from goal to result 5.8k ★
  • Surface — Show ranked attack surface for a target from its recon manifest + hunt memory 3.8k ★
  • Cindy — Consider it done 2.3k ★

README

Canny

A warden 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.

[![ci](https://github.com/qkal/canny/actions/workflows/ci.yml/badge.svg)](https://github.com/qkal/canny/actions/workflows/ci.yml) [![license](https://img.shields.io/github/license/qkal/canny)](LICENSE) [![node](https://img.shields.io/badge/node-%E2%89%A5%2022-339933?logo=node.js&logoColor=white)](#install-by-pasting-a-prompt) [![agents](https://img.shields.io/badge/hooks%20into-Claude%20Code%20%C2%B7%20Codex%20CLI-7c3aed)](#claude-code-and-codex-differ-in-four-places) [![runtime dependencies](https://img.shields.io/badge/runtime%20dependencies-0-success)](package.json) [![judge](https://img.shields.io/badge/judge-Jev%20by%20TypeSafe%2C%20optional-0ea5e9)](https://typesafe.ai) [![last commit](https://img.shields.io/github/last-commit/qkal/canny)](https://github.com/qkal/canny/commits/main)

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