Skip to content

v0.2.0

Choose a tag to compare

@qkal qkal released this 21 Sep 01:20
· 15 commits to main since this release
1778c80

Canny 0.2.0 closes the ways an agent could pass the done-gate without a passing check, extends the secret and test-removal checks to shell commands, and makes the CLI report on itself honestly.

Install or update as before: git -C ~/.canny/src pull --ff-only, or the prompt in the README. There is nothing to build.

Before you update

  • Run canny trust once per project that has a .canny.json. verify, ignore, rules, and allow are ignored until the file is trusted, because it lives in the repository the agent is editing. strict is still read from any config.
  • A check piped into tail no longer counts. pnpm test 2>&1 | tail -20 reports tail's exit status, so it proves nothing. Agents that pipe their test runs get blocked once and have to rerun the check on its own, or with set -o pipefail.
  • Tighten old ledgers: chmod -R go= ~/.canny. New files are created owner-only; files from 0.1.0 keep their old mode.
  • canny init and canny remove now exit 1 when they refuse a settings file they cannot parse. They used to print the error and exit 0.
  • Ledgers written by 0.1.0 do not record their project, so canny status no longer picks them up on its own. They are still readable by file name.

The done-gate

  • A check whose exit status never reaches the agent does not count: piped without pipefail, backgrounded, followed by || true, or followed by ; echo done. Neither do commands that only print or inspect, such as echo tsc or tsc --version.
  • > inside a quoted string or a heredoc body is not a file write, so git commit -m "a > b" no longer blocks a session that edited nothing.
  • cp, mv, rm, git rm, git checkout -- file, and git restore count as code changes. node_modules, .venv, caches, logs, and temp files outside the project do not.
  • One very long line of digits in command output stalled the hook for 41 s and lost the ledger entry. It now takes milliseconds.

Secrets and tests

  • Shell commands that write a file go through the secret check: echo "key = 'sk-…'" > src/config.ts is denied like the same Write. A key that is only used, such as a curl header, is left alone.
  • Writing a key into a .env file that git ignores is allowed. An unignored .env, a symlinked one, and .env.example-style templates are still denied.
  • rm, git rm, and mv of a test file or directory get the same ask as deleting it through an edit (deny on Codex). Renaming a test, or moving it into a directory, is not removal.

The README lists what the shell reading does not cover. These checks are a speed bump for an honest agent, not a sandbox.

The CLI

  • canny trust and canny remove are new. canny init writes hooks only for the agents it finds installed.
  • canny status and canny replay show the latest session of the project you are in, not of any project. canny sessions lists each session's project.
  • canny status prints how often the hook crashed and the last error. The hook fails open, so a crash used to be silent.
  • Messages name node "<checkout>/dist/cli.js" … when there is no canny on PATH, which is the case after the documented install.
  • init and remove recognise Canny's hooks by the statusMessage: "Canny" marker, keep another tool's hook that shares a group with Canny's, refuse malformed settings files without touching them, and write atomically through symlinks.
  • Ledger files are owner-only, and escape sequences are stripped before anything enters the ledger, so command output cannot redraw what canny status prints.

Full changelog: https://github.com/qkal/canny/blob/v0.2.0/CHANGELOG.md · v0.1.0...v0.2.0