Rust · macOS & Linux · v0.10.1
AI coding agents that prove their work.
You say what “done” means. An agent — Claude Code, Codex, Copilot, Kiro — does the work. keel checks it, stops the line when a check fails or you haven't signed off, and keeps a tamper-evident record anyone can verify, even without your repo.
$cargo install keel-harness
Installs a binary called keel. Works with the agent you already use.
How it works
You decide. The agent works. keel keeps score.
Coding agents are brilliant at writing code and bad at knowing when to stop. keel is the part that knows: what “done” means, whether the work got there, and who said so.
1 · Define doneA short spec whose every criterion has a test that can say no. You approve it, and the plan.
2 · Let it workAny agent you like. keel hands it the task and nothing it doesn't need.
3 · Prove itBuild, tests, review, your sign-off — then one file of evidence anyone can check.
Use cases
What you can do with it
Start with one. Each works on its own.
For anyone using an agent
Keep an agent on a short leash
Nothing counts as done until the build and tests are green, a review pass has run, and you've signed off. A gate that fails sends the work back — it never quietly ships.
keel spec new rate-limit # what done means keel approve rate-limit --stage spec keel plan rate-limit # which files, how big keel run rate-limit # agent works, gates judge
For audit, risk and compliance
Show an auditor exactly what happened
Every approval and verdict is locked into a hash chain. One command packs the chain, the spec, the verdicts and the exact diff into a single file that anyone can verify offline, with no access to your code.
keel export keel bundle verify keel-<run>.tar.gz pass members · chain · approvals pass gate-verdicts · trajectory
For teams on GitHub
Block pull requests nobody gated
Add one step to a workflow. A PR passes only if it carries the evidence of
a passing run of exactly its content — or a maintainer labels it
keel:exempt, and the record says so.
# .github/workflows/keel-cover.yml on: pull_request jobs: keel-cover: runs-on: ubuntu-latest steps: - uses: daneb/keel@v0.10.1
For platform teams
Let CI do the gating
GitHub Actions gates each PR inside a locked-down container — gVisor, when the runner has it — keeps the record where that container can't reach it, and commits the evidence back to the PR.
# in a pull_request workflow - uses: daneb/keel/runtime@v0.10.1 with: spec: rate-limit image: rust:1-bookworm
For running agents locally
Put the agent in a sealed box
Pair keel with moor: a sandbox per project, no access to your disk, an allowlist for the internet — and keel's record written from outside, so the agent can't rewrite it.
moor new my-app
moor ask my-app "add rate limiting"
moor bundle -p my-app # ✓ bundle pass
Why trust it
Every claim here is checked, not asserted
keel is built with keel. Every change to it carried a spec, passed its gates, and ships its own evidence bundle.
VALUE
Less babysitting, more shipping
- Works with the agent you have — Claude Code, Codex, Copilot, Kiro — through one small adapter each.
- 14.6× less context fed to the agent, at 100% recall, by handing it outlines and symbols instead of whole files.
- One line in a workflow turns it into a PR check.
- Remembers across sessions: mistakes that recur become checks, not more instructions to ignore.
QUALITY
Nothing is done until it's proven
- Five gates, from “is this spec testable?” to “did a human sign off?” — each one a verdict with its evidence.
- A test that can say no on every acceptance criterion; a spec that can't fail can't pass either.
- Review built in: weakened tests and added mocks are caught, and serious security findings block.
- 541 tests, 0 warnings at
clippy -D warnings.
SECURITY
The agent can't mark its own homework
- Tamper-evident record: every approval and verdict is hash-linked; edit, delete or reorder one and keel names where.
- The pen stays outside the sandbox: under moor or CI, the record is written by the host, never by the agent.
- gVisor, proven: on GitHub runners the gate runs in a user-space kernel, and the record says so — or says it couldn't.
- Approvals bind to content: change the spec after sign-off and the approval stops counting.
RELIABILITY
It never guesses green
- Three verdicts, not two: a check that couldn't run is
blocked(exit 3) — never a silent pass. - Verifies offline: a bundle checks out with no repo, no network, no account — on a plane, or in an auditor's sandbox.
- Tested on real pull requests, not just in unit tests: covered, uncovered and exempted, on live GitHub runners.
- Frozen formats: the record and attestation formats change only additively, so evidence written today still verifies tomorrow.
Gates
Where the load is carried
Each gate answers one question and refuses to answer it vaguely.
G0
Is the spec answerable?
Every requirement falsifiable, every criterion carrying an oracle. A spec that cannot fail cannot pass either.
G1
Is the plan honest about its reach?
Blast radius computed from the import graph and compared with what the plan declared — not with what it hoped.
G2
Did the work stay inside its scope, and does it build?
Build, lint, tests, line budget, blast radius, store drift, baseline ratchet.
G2.5 adds test-invalidation review, and grades the diff for security defects —
a model, a scanner, or both — where high/critical
block the gate.
G3
Could a reviewer actually check this?
Evidence complete, change reviewable in size, earlier gates green, a human verdict where one was required.
G4
Did we learn anything that should become a rule?
Episodes classified, promotions proposed, decay reviewed. G4 forces the decision; it does not make it for you.
pass · exit 0
The checks ran and held.
fail · exit 1
A check ran and said no.
blocked · exit 3
A check could not run. It never silently passes, and it is never counted as an agentic failure.
Evidence
Numbers, and where they came from
All of these are measured by keel on real repositories. The provenance matters as much as the value.
14.6×
Less context
At 100% recall on keel's retrieval benchmark.
1.25 s
To index 5,705 files
Cold, across eight languages.
541
Tests · 0 warnings
Clippy clean at -D warnings.
11 → 54%
G2 pass rate
Inside keel vs. on a real project. The low number was the artefact.
The check to scrutinise first
keel's own metrics flag
G2/store-drift: it has never failed in 26 runs across two
repositories. That is either a check that is correctly always-true here, or
gate theatre. A harness that measures other people's work should be able to
say which — so it says so, on its own front page.
Get started
Ten minutes to your first gated change
Point keel at a repository and take one small change all the way through. The getting-started guide walks the same path with commentary.
# install cargo install keel-harness # binary is called `keel` # set up, then describe one change keel init keel spec new short-invocation keel approve short-invocation --stage spec # plan it, run it, prove it keel plan short-invocation keel run short-invocation keel bundle verify "$(keel export)" # where does it stand? what's next? keel next keel serve # read-only, in a browser
Before you trust it on real work
- macOS and Linux. Windows branches compile and are unexercised. That is a decision, not an oversight.
- Configure a reviewer. Without a model or scanner behind it, G2.5 reviews with heuristics.
- Pull requests from forks can't receive the CI runtime's bundle commit yet.
- The evidence is young — a handful of repositories, one operator. The roadmap keeps a full accounting of what is deferred and why.