Skip to content

Getting started

Terminal window
go install github.com/pdbethke/corralai/cmd/corral@latest

Or clone and build from source:

Terminal window
git clone https://github.com/pdbethke/corralai
cd corralai
go build ./...

The fastest way to see corral do the thing it’s for — certify a change by execution, not opinion — is one command, off your own key, no daemon:

Terminal window
export ANTHROPIC_API_KEY=sk-ant-... # your own key
corral certify --local \
--code path/to/your/file.go \
--goal "what this code must guarantee" \
-- go test ./...

That runs the full adversarial testing pool in-process: mutant-generators seed goal-violating bugs into your code, your own test is scored against them by executing it in a jail (never a self-report), a test-writer proves any gap is real by writing and killing the test you were missing, and a decorrelated test-critic reads your suite cold. You get a signed verdict — certified or needs-review — and can re-check it offline any time:

Terminal window
corral certify verify <record>

On a file with several functions the generation fans out — one seat per group of functions, so every function gets probed, not just whichever one a single generator happened to pick (--max-shards N bounds the width; the default auto-sizes to your machine). Alongside each region a cheaper challenger model attacks the same code in parallel, purely to measure one model against another on identical ground — it’s recorded for comparison and never part of the verdict (--shadow-model off disables it). And a mutant that makes your suite hang is killed fast and counted as caught, so a runaway loop can’t stall the audit (--test-timeout overrides the auto-derived cap).

By default the audit runs two distinct Claude models off that single ANTHROPIC_API_KEY (Sonnet writes/mutates, Haiku critiques); on that same default path, --critic-model gemini-3.5-flash plus a Google key (GEMINI_API_KEY or GOOGLE_API_KEY) routes the critic to Gemini via the OpenAI-compatible Google endpoint — a real cross-vendor critic, writer and mutant-generator unchanged on Claude. A missing key fails the run closed instead of silently falling back. It supports Go, Python (pytest), Ruby (minitest/RSpec), JavaScript (node:test), and TypeScript (tsc + node:test) — the language is inferred from --code’s extension.

It always runs sandboxed. bwrap is the Linux default; --jail container falls back to docker/podman; macOS uses sandbox-exec. There’s no unsandboxed option. On Ubuntu 24.04+, apparmor disables unprivileged user namespaces by default and bwrap won’t start — the error message spells out the exact one-line fix (or pass --jail container). And the language toolchain has to be jail-visible: installed system-wide under /usr (your distro’s golang/python3 package), not a --user/snap/pyenv install — a snap go or a pip install --user pytest is invisible inside the sandboxed mount namespace and the run will fail closed looking for it.

Walk through a real verdict end to end in Your first audit, in detail.

--local runs the audit standalone. The brain is the coordination substrate the repo/control gates run inside of — worth running if you want the gate poller, shared memory, or the swarm UI, not required for --local.

Against a brain you’re running yourself (dev mode — no CORRALAI_OIDC_ISSUER set, so auth is off):

Terminal window
go run ./cmd/corral

Open http://127.0.0.1:9019/ for the live corral view and the Progress tab. From another terminal, drive it with corral-admin — see the CLI reference for every verb.

  • CORRALAI_OIDC_ISSUER / CORRALAI_OIDC_AUDIENCE — cross-machine auth
  • CORRALAI_GIT_TOKEN + CORRALAI_FORGES — repo-work / multi-forge missions
  • CORRALAI_EMBED_URL — reference RAG + vector search
  • CORRALAI_MOTHERDUCK — fleet analytics + oracle
  • MODEL_BACKEND / OPENAI_BASE_URL — bring your own model

See Running it for the full rundown, and the CLI reference for every corral-admin verb.