Repository navigation
Bench v2.1.0
v2 proved that AI code governance can be adversarial, binding, and auditable. v2.1 makes it cheap enough, installable enough, and honest enough that a developer who opens the repo stays. Every change in this release landed through Bench's own pipeline and carries a receipt in its ledger.
Cost
Figures come from Bench's operational chain, the same numbers python -m cli stats prints and the viewer's dashboard plots. They are a fixed snapshot of the chain as it stood at 2026-09-07T06:37:19Z (2,767 entries, 2,743 with usage recorded), not a live weekly value. Nothing here is an estimate.
| Week | Entries with usage | Median tokens per edit | At cached rates | Median seconds per edit |
|---|---|---|---|---|
| 2026-W36 (the roadmap week) | 1,777 | 34,747 | 33,451 | 63.5 |
| 2026-W37 (release week, at the snapshot) | 118 | 20,383 | 19,085 | 26.6 |
The release-week row is a small sample of light edits, most of them docstring and test changes the Challenger clears in seconds, and it is not a settled reduction: on the day of the snapshot that median moved from under 20,000 to just over it as heavier edits landed. It is the first week under every 2.1 cost change together; the roadmap week is the number to plan on until a full week of ordinary edits is in. Across the snapshot: 2,764 adjudicated changes, 97.1% passed, 2.9% vetoed; median 34,917 tokens per edit (33,899 at cached rates) over the 2,743 entries with usage; median 61.1 seconds over 1,673 timed entries; chain VALID.
What changed to get there: each stage receives every constraint's rule without its rationale and commentary (constitution v7), the constitution and repository context are cached on the anthropic provider and folded into the cached system prompt file on the claude_code provider, and cosmetic drift in judge output is repaired and recorded instead of turning an examined edit into a fail-closed pipeline error.
Install
pip install .
bench install --project /path/to/your/project
bench install writes the hook settings with an absolute path, appends /.bench/ to the project's gitignore, and installs the ledger commit guard as the pre-commit hook when the project has none. bench uninstall reverses exactly what install wrote, from the receipt it keeps at .bench/install.json. The CLI is argparse now: bench --help lists every command and its flags.
The bound bypass
The judge subprocess used to be let through on a bare BENCH_SUBPROCESS=1. It is now let through only on a per-call nonce the provider records on disk for the duration of the call; a bare 1, a guessed token, or a stale one is governed like any other process.
Also in this release
- A derived tip cache and an append lock in the ledger: an append reads only the entries it links to, and two sessions on one machine cannot fork the chain. Retirement holds the lock across its whole mutation window.
- Per-stage wall time in every entry, and a recorded model override per stage.
- Tests that run the hook as a real subprocess and pin its host contract, and tests that a prompt-injected diff cannot move the verdict, offline and, opt-in, live.
- Strict mypy and ruff in CI; a timeout on every subprocess; the viewer file created owner-only on Windows as well as POSIX.
CHANGELOG.md, and docstrings that describe the code as it is.
Full details in CHANGELOG.md.