Skip to content

corral

Generated by scripts/gen-cli-docs.sh from corral’s own -h output and its main.go doc comment. Do not hand-edit — run scripts/gen-cli-docs.sh and commit the result.

corral — the CorralAI brain: an OIDC-authenticated, MCP-native coordination server
Usage:
corral serve /mcp/ + /healthz on $CORRALAI_ADDR
corral secret set|get|list|rm manage provider keys + tokens in the secure keystore
(env → OS keyring → age-encrypted file; set reads stdin, never argv)
corral control seed [flags] seed one vetted control test into the control-gate store
(--spec-db --owner --goal --target --code-path --test-path --test-file)
corral certify [<ref>] [--out <file>] [--net=false] [--produced-by a,b] -- <check-cmd>...
certify a change by execution: check out <ref> (default
HEAD) into a jail, run <check-cmd> there, and write a
signed, offline-verifiable record; exits with
<check-cmd>'s own exit code
signs locally (no server) unless --brain is given
flags: --produced-by a,b --out <file> --net=false
--repo/--commit/--branch (default: read via git)
corral certify --brain <url> [flags] -- <check-cmd>...
same as above, and also post the signed record to a
brain (report_build) as a tamper-evident build attestation
corral certify --adversarial --code <path> --goal "<text>" [--test <path>] -- <test cmd>
grade a change's own tests: fire the adversarial pool on the
brain, poll to a signed verdict
corral certify --repo <dir> [--top n|--all] [--goals <file>] [--dry-run] [--swarm n] [-- <test cmd>]
fan the --local audit out over a WHOLE repository: enumerate
every source file with a paired test, rank them by churn x size,
audit the top --top (default 25, --all for every one) through a
bounded swarm, and print a repo report whose kill rate is over
the AUDITED surface only, with every excluded file accounted for
by reason — including the ones the bound left out
each file's goal is DERIVED from its source by --derive-model;
--goals <file> instead takes goals from a JSON map and makes no
model call
--dry-run stops after enumeration (no jail, no LLM calls)
an explicit -- <test cmd> grades EVERY file, so it is refused
when the scan spans more than one language (omit it and each
file is graded with its own language's stock command)
the report is NOT signed yet — that lands with the sealed
repo statement
corral certify verify <record-file> [--pubkey <hex>|--brain <url>] [--allow-unanchored]
independently verify a --out (or report_build) record: the
Ed25519 signature, the ledger's hash chain, and that the
statement is bound to that exact ledger head — requires a
trusted key via --pubkey or --brain (a record's own
embedded public_key is never a trust anchor); prints
"verified" and exits 0, or names the failing check on
stderr and exits non-zero
corral certify pubkey print the local signing pubkey (for --pubkey trust anchors)
corral scorecard [--json] show the bug-catching scorecard (recall/precision per model×role,
plus a C-PREC column: the test-critic role's execution-checked
precision from criticscore adjudications);
table by default, or the raw cells as indented JSON with --json
corral criticscore list list execution-checked test-critic findings still awaiting human
adjudication (requires CORRAL_BRAIN — no offline mode)
corral criticscore show <id> print one finding in full (model, target test, evidence)
corral criticscore confirm <id> record a human "confirmed" verdict — the finding was real
corral criticscore refute <id> record a human "refuted" verdict — the finding was wrong
(confirm/refute permanently override the pool's own auto-adjudication;
this IS the human gate the critic-precision column measures)
corral matrix list [--json] show the tests×mutants matrix (swarm slice 5): per-test
execution-proven adequacy against a run's own mutant set, plus a
safe-to-delete candidate list — populated only by runs opted in via
certify --local --matrix (requires CORRAL_BRAIN — no offline mode)
corral scans list|show [flags] read the scan ledger certify --repo --record writes: list
shows recent scans, show <id> their per-file dispositions —
including WHY a proven-gap count of 0 is 0 (writer failed / test
unsound / tried and missed), which the bare number cannot say.
show <id> --evidence prints the pool's own authored test, kept
even when it proved nothing — that is the case worth reading.
Local DuckDB file, no brain required:
--db <path> (default $CORRALAI_SCANS_DB, else
~/.claude/corralai_scans.duckdb), --limit n, --json
corral eval [flags] run the adversarial pool across the versioned eval corpus and
print a soundness report (does the recall metric catch known gaps?)
flags: --corpus <path> (default eval/corpus/manifest.json)
--iterations <n> (default 1) --only <id,id,...>
--brain <url> (or $CORRAL_BRAIN)
--progress <path> (default eval/.eval-progress.json)
corral --version print the build version and exit
corral -h print this help and exit
Configuration is entirely environment variables — see CORRALAI_ADDR,
CORRALAI_DB, and the rest of the // Env: block at the top of this binary's
main.go (also reproduced in the generated CLI reference).
CORRALAI_ADDR listen address (default 127.0.0.1:9019)
CORRALAI_DB coordination SQLite path (default ~/.claude/corralai_coord.sqlite3)
CORRALAI_MEMORY_DB memory DuckDB path (default ~/.claude/corralai_memory.duckdb)
CORRALAI_RECORDINGS_DB recordings DuckDB path for scrubbed replay exports (default ~/.claude/corralai_recordings.duckdb)
CORRALAI_MEMORY_DIR where new memory entries are written (default ~/.claude/projects/default/memory)
CORRALAI_PROJECT_TIERS optional path->tier rules "substr=tier,substr=tier"; front-matter project: wins, else "default"
CORRALAI_OIDC_ISSUER OIDC issuer URL (any OIDC provider: Keycloak, Auth0, Okta, Dex, Authentik, …); empty => AUTH DISABLED (dev)
CORRALAI_ALLOW_INSECURE set "1" to allow auth-disabled startup on a non-loopback CORRALAI_ADDR (refused otherwise, H-3)
CORRALAI_OIDC_AUDIENCE expected token aud (the client_id)
CORRALAI_OIDC_CLIENTS extra trusted clients "issuer|aud,issuer|aud"
CORRALAI_ALLOWED_PRINCIPALS day-0 SEED of member emails (DB is canonical after; empty => any authenticated)
CORRALAI_PRINCIPALS_DB role/allowlist SQLite path (default ~/.claude/corralai_principals.sqlite3)
CORRALAI_MEMORY_OWNERS comma list of emails allowed to read/write memory (empty => any authorized)
CORRALAI_ALLOWED_HOSTS comma list of accepted Host headers (default: the brain's domains + localhost)
CORRALAI_CLIENT_IP_HEADER trusted real-client-IP header for rate limiting (e.g. CF-Connecting-IP); empty => RemoteAddr
CORRALAI_RATELIMIT_IP_PER_MIN / _IP_BURST per-IP rate limit (default 300/min, burst 100)
CORRALAI_RATELIMIT_USER_PER_MIN / _USER_BURST per-principal rate limit (default 600/min, burst 200)
CORRALAI_MAX_BODY_BYTES max request body size (default 1 MiB)
CORRALAI_TLS_CERT / _KEY serve HTTPS with these PEM files (built-in TLS, no proxy needed)
CORRALAI_TLS_AUTOCERT_DOMAINS comma list => auto Let's Encrypt certs (needs public reachability)
CORRALAI_TLS_AUTOCERT_CACHE cert cache dir (default ~/.cache/corralai-autocert)
CORRALAI_ADMIN_PRINCIPALS day-0 SEED of superuser emails (DB is canonical after; `corral createsuperuser` adds more)
CORRALAI_GATEWAY_DB MCP-gateway registry SQLite path (default ~/.claude/corralai_gateway.sqlite3)
CORRALAI_ARTIFACTS_DB fleet skill/hook sync SQLite path (default ~/.claude/corralai_artifacts.sqlite3)
CORRALAI_GATEWAY_ALLOWED_HOSTS hosts the gateway may dial despite the SSRF block (private/internal targets); empty => block all private/loopback
CORRALAI_MOTHERDUCK fleet-sync target: "md:<db>" or a .duckdb path; empty => sync off
CORRALAI_MOTHERDUCK_TOKEN MotherDuck token (exported as motherduck_token for md: attach)
CORRALAI_BRAIN_ID tag for this brain's rows (default hostname)
CORRALAI_SYNC_INTERVAL fleet sync interval, seconds (default 30)
CORRALAI_FLEET_RETENTION_DISABLE set "1" to disable the retention/compaction cycle entirely
CORRALAI_FLEET_RETENTION_DAYS TTL window in days (default 90; 0 = TTL off, compaction still runs)
CORRALAI_FLEET_RETENTION_INTERVAL_SEC how often (seconds) to run the retention cycle (default 3600)
CORRALAI_GIT_TOKEN GitHub PAT for repo-work missions (clone + PR); empty => repo engine disabled unless CORRALAI_REPO_ENABLE=1
CORRALAI_GITHUB_API GitHub API base URL (default https://api.github.com)
CORRALAI_REPO_WORKSPACE root dir for per-mission working copies (default $TMPDIR/corral-repos)
CORRALAI_REPO_ENABLE set "1" to enable the repo engine even without a token (anonymous / GitHub Apps token flow)
CORRALAI_REVIEW_POLL_SEC how often (seconds) the brain polls open PRs for CHANGES_REQUESTED reviews (default 60)
CORRALAI_BRAIN_KEY base64-encoded Ed25519 seed (32 bytes) for cross-swarm brain identity; takes priority over key file
CORRALAI_BRAIN_KEY_FILE path to persist the brain key seed (default ~/.claude/corralai_brain_key); created 0600 on first run
CORRALAI_BRAIN_PEERS optional allowlist "brain_id:pubB64" entries (comma or newline separated); empty => TOFU mode
CORRALAI_LEARN_DB learning-loop proposals SQLite path (default ~/.claude/corralai_learn.sqlite3)
CORRALAI_LEARN_SWEEP_SECONDS how often (seconds) the learn sweep clusters findings/lessons into proposals (default 60)
CORRALAI_BUILD_DB `corral certify` signed build-record ledger DuckDB path (default ~/.claude/corralai_build.duckdb)
CORRALAI_CERTIFY_KEY hex-encoded Ed25519 seed (32 bytes) `corral certify` build attestations are signed with; takes priority over key file
CORRALAI_CERTIFY_KEY_FILE path to persist the certify signing key seed (default ~/.claude/corralai_certify_key); created 0600 on first run
CORRALAI_BRAIN_TOKEN `corral certify`'s bearer token to authenticate to a brain (via `corral secret set`); distinct
from CORRALAI_BRAIN_KEY above (that's an Ed25519 IDENTITY SEED, not a bearer token — do not reuse it)
CORRALAI_REKOR_URL Sigstore Rekor instance report_build anchors signed build attestations to (default https://rekor.sigstore.dev);
`corral certify verify` checks the same default unless --rekor-url overrides it
CORRALAI_GATE_POLICIES repo merge gate: ";"-separated policies "repo=owner/name,base=main,net=false,timeout=600,cmd=go test ./...";
cmd= MUST be the last field — everything after it is the command verbatim (commas
allowed, never split) so "cmd=go test -run A,B ./..." isn't silently truncated;
timeout= is seconds, defaults to gate.DefaultGateTimeout (600s) when omitted;
empty => the repo gate is OFF (no poller starts); GitHub-only for v1
CORRALAI_GATE_DB repo gate dedupe/index store DuckDB path (default ~/.claude/corralai_gate.duckdb)
CORRALAI_GATE_POLL_SECONDS how often (seconds) the repo gate polls covered repos for new PR heads (default 120)
CORRALAI_GATE_EXEC_BACKEND / _EXEC_UNSAFE_HOST same jail backend used by the independent verify-gate (see below);
the repo gate reuses it — a missing backend disables the repo gate too, loudly, never unsandboxed
CORRALAI_CONTROL_GATE control gate: ";"-separated "repo=owner/name,owner=<principal>,lang=go,base=main"
— owner= MUST equal the control owner's authenticated principal (the identity they
author controls under), else the gate finds no vetted controls
— runs the owner's VETTED tests against PR heads, posts corral/control-gate
CORRALAI_CONTROL_GATE_SPEC_DB control-gate vetted-tests store (default ~/.claude/corralai_control_spec.duckdb)
CORRALAI_CONTROL_GATE_DB control-gate dedupe/index store (default ~/.claude/corralai_control_gate.duckdb)
CORRALAI_CONTROL_GATE_POLL_SECONDS how often the control gate polls for new PR heads (default 120)
CORRALAI_BUGCATCH_DB adversarial pool's bug-catching scorecard store DuckDB path
(default ~/.claude/corralai_bugcatch.duckdb); also read by `corral scorecard`
CORRALAI_CRITICSCORE_DB adversarial pool's critic-accuracy store DuckDB path (default
~/.claude/corralai_criticscore.duckdb); the scorecard's C-PREC column and
`corral criticscore` read it over the API — see CORRAL_BRAIN below