cancho-code builds software one small piece at a time, and the compiler — not the model — decides when each piece is done.
One real run (Claude Haiku 5.5 building the tokenbucket library from a hand-written plan: 4 units, 17 seconds, $0.0023, 46 of 46 hidden checks). The left is its log, the right is the board the dashboard makes from the same files; the board is replayed in step with the log here. The refusal line comes from the run's trail file. Not a live session. Open this run in the full board.
Most assistants say “done” and leave you to read the diff. Here, “done” has to be earned.
Every piece is type-checked by the real compiler and run against its own examples. A model's confidence counts for nothing.
A brief becomes a plan of small units. A failing unit is fixed alone, and everything already verified is re-checked after each step.
Attempt ceilings and a “same refusal twice” rule end a stuck run, named, instead of burning your money.
Claude with an API key, or a local model through Ollama. You pick the provider and the model every time.
Plan, build, check, repeat. Each lap ends in a verdict you can read.
Give it a brief. It writes the plan, checks it, builds every unit with the compiler as judge, and ends with a verdict.
build/cancho-build "$CANCHO" brief.txt work "$AGENT" \
--provider anthropic --model claude-haiku-5-5 --guide docs/plan-guide.md --review on
[BUILD_VERDICT] done
The functions your brief names are the ones built. A plan that renames one is refused before anything is built.
A read-only page shows every unit as waiting, building, verified or stuck. Click a unit to read its whole story: each prompt, the model's reply, the compiler's full refusal, the diff between attempts, tokens and cost. Open it and load a run's board.json.
Killed halfway? The next run keeps the verified units and does not ask for the plan again.
The board above is docs/board.html showing two real runs of Claude Haiku 5.5. The first is the tokenbucket run from the top of the page. The second is a sortedmap run that failed, and it has a full journal: click the stuck get unit to read both attempts, the compiler's refusal and the diff, and open Story for the plan stage. What the journal shows is not the model's fault: the unit's own tests file imports std.option itself, so the model could not fix the "already bound" error; the plan's test generation is what needs fixing. Only the run machine's folder names were replaced in the data (by /work); nothing else was edited.
Example, one run: Claude Haiku 5.5 built the roman library from its brief alone, 6 units, 88 seconds, $0.013, and passed the hidden audit 439/439. One run on one task; the numbers below are the larger measurement. Details: docs/build.md, docs/dashboard.md.
Thirteen small library tasks (parsers, encoders, a rate limiter…) and four small web services, built by Claude Haiku 5.5.
Hidden tests the model never sees score the results. One model (Claude Haiku 5.5), two or three runs per task. The first four figures: 13 small libraries; the brief-only rows come from 2 runs per task and a model-written plan with a review pass (with the required function signatures given too, 20 of 26 finish and 19 of 26 are fully right). Services: the four services (webhooks, jobs, invoices, kvstore) were built from hand-written plans; with the instructions as first written the application unit got no answer in 7 of 8 runs, and the final scores (webhooks 129/129, jobs 188/188, invoices 163/165, kvstore up to 225/225 on the hidden attack) came after the guide was changed to fix the failures it showed, so treat them as what is reachable, not as a blind result. See the dated reports in eval/results for conditions and failures.
Paste this into Claude Code, Codex or any coding agent that can run commands. It installs cancho-code, proves the install with a test that needs no key, and only then asks you which model to use.
Install cancho-code and try it on one small task. Work in a new empty directory, keep every path free of spaces, and never use sudo. Run steps 2 to 4 in one shell session (or repeat the two `export` lines in every command): `export` and `cd` do not survive a fresh shell.
1. Check that `git`, `cargo` (Rust, stable, via rustup), a C compiler (`cc`) and `sh` exist. If one is missing, stop and tell me which; do not install system packages on your own.
2. Get the two repositories side by side, both cloned into the new empty directory (call it the parent):
git clone https://github.com/alpibrusl/cancho-code.git
git clone https://github.com/alpibrusl/cancho.git
git -C cancho checkout "$(cat cancho-code/.cancho-rev)"
3. Build the compiler (a few minutes) and point at it:
(cd cancho && cargo build --release -p cancho)
export CANCHO="$PWD/cancho/target/release/cancho"
export CANCHO_PACKAGES="$PWD/cancho/packages"
4. Build the two tools and prove the install works. This needs no network, no key and no model. Start from the parent directory:
cd cancho-code
sh scripts/build-agent.sh && sh scripts/build-cancho-build.sh
sh scripts/test-build.sh # must end with: build gate: ok
"$CANCHO" agent-guidelines > guidelines.md
Lines such as `ld: warning: no platform load command ...` and `Killed: 9` during these commands are expected (the gate kills a run on purpose to test resuming); only the final `build gate: ok` line matters.
5. A real build needs a model. Ask me which one I want to use, and wait:
- Claude: ask me for the PATH of a file that holds my Anthropic API key (mode 600). Never read, print, copy or log that file, and never put the key in a command line or an environment variable; the tool takes the path.
- Ollama (local): ask me for the model name; it must already be pulled and the server running on localhost:11434.
If I do not want a real run, stop after step 4 and report.
6. Build the example "roman" library from its brief alone (about 2 minutes, a few cents on Claude), with the model I chose (for Claude use claude-haiku-5-5):
mkdir -p runs/roman
build/cancho-build "$CANCHO" "$PWD/eval/roman/brief.txt" "$PWD/runs/roman" \
"$PWD/scripts/cancho-agent.sh --key-file <KEY_FILE> --primer $PWD/guidelines.md --max-tokens 16000 --output patch" \
--provider anthropic --model claude-haiku-5-5 --guide "$PWD/docs/plan-guide.md" \
--review on --review-guide "$PWD/docs/review-guide.md" --attempts 6 --agent-seconds 300
(For Ollama: drop --key-file and --output patch, use --provider ollama and my model name.)
7. Look at the result and tell me, honestly and briefly:
- the last line it printed ([BUILD_VERDICT] done, stuck, plan_failed, provider_error), and the exit code;
- runs/roman/build.json (units verified of total, seconds) and, if usage.jsonl is there, the total output tokens;
- whether runs/roman/project.cho exists, and what the hidden checks said if you can run them (python3 eval/audit_roman.py runs/roman/project.cho);
- anything that failed, with the exact error. Do not retry in a loop and do not edit the repositories to make it pass.
To see the run as a board: sh scripts/cancho-board.sh runs/roman, then serve docs/ (python3 -m http.server -d docs 8000) and open /board.html.
Docs: docs/build.md (the command), docs/dashboard.md (the board), docs/reference.md (every flag).
It never asks the agent to read your API key: you give the path of a key file and the tool reads it itself. A run on Claude costs a few cents; the install and the test cost nothing. The same text is in docs/agent-prompt.md.
You need the cancho compiler and either an Anthropic key or a local Ollama model.
git clone https://github.com/alpibrusl/cancho-code.git
cd cancho-code
export CANCHO=<path-to-the-cancho-binary> # the commit named in .cancho-rev
export CANCHO_PACKAGES=<compiler-checkout>/packages
"$CANCHO" build tests/programs/fix.cho \
src/driver.cho src/checker.cho src/signature.cho \
src/loop_check.cho src/snapshot.cho src/trail.cho src/acceptance.cho \
--std --backend cranelift -o ./fix
Then fix a broken program with a local model, or build a whole plan with Claude: the step-by-step guide has both.