Multi-model herds
Multi-model isn’t a comparison feature bolted onto certify — it’s the mechanism that makes the verdict trustworthy. Nemo iudex in causa sua: the model that critiques a test suite is forced to differ from the model that wrote the exposing test — the run refuses to start where the roles collapse onto one model. A swarm that runs one LLM in every role gets parallelism with correlated blind spots, because the “reviewer” shares the “author’s” failure modes when it’s the same model underneath.
Decorrelation across the audit roles
Section titled “Decorrelation across the audit roles”corral certify --local runs distinct roles — mutant-generator, test-writer,
test-critic — each with its own model assignment, and the critic role is
decorrelation-enforced: it must differ from the model that authored the
exposing test, checked at run start, not advised after the fact. There are no
default models — you name every seat — but a single ANTHROPIC_API_KEY can
satisfy the rule on its own (Sonnet writing and mutating, Haiku critiquing) —
the weakest form of it, since two models from one lab share the most lineage;
--critic-model plus a second vendor’s key crosses a vendor boundary entirely. Bring Claude, Gemini, GPT, anything OpenAI-compatible, or a
local model — no lock-in.
What is enforced, what is advised, and what isn’t checked. Read the
sentence above precisely: CheckDecorrelation (internal/advpool/driver.go)
compares exactly one pair — test-critic against test-writer — by model
name, and refuses the run if they match. That is the entire rule.
Cross-vendor separation (Sonnet writing, Gemini critiquing) is advised,
not enforced: two models from the same lab satisfy the check just as well,
which is why it’s called the weakest form above rather than a loophole. And
the mutant-generator is not part of the check at all — it may share a
model with the test-writer, and often does (naming one model for both
--writer-model and --mutant-model is a common, supported configuration).
None of that is a defect in the verdict: the kill-rate that gates
certification is decided by running your real suite against each mutant in a
sandbox and reading the exit code, not by any model’s opinion, so a
correlated generator/writer pair cannot move the number it certifies on. It
is a real gap between “decorrelated by construction” and what the code
checks, and it’s disclosed here rather than left for a reader to find in
driver.go.
A role-model policy for the hosted brain
Section titled “A role-model policy for the hosted brain”The same idea, generalized: CORRALAI_ROLE_MODELS maps role=backend:model
pairs so different roles in a running brain carry different models — e.g. a
generator and a critic on two distinct models so model_comparison has
something real to compare. When a role’s spawn happens and its assigned model
is already live in the pool, the spawn call resolves the new subagent onto it
(apply-on-spawn); when it isn’t yet connected, the child inherits the
default instead and the gap shows up as drift on swarm_topology rather
than a blocked spawn. See corral’s env reference for the
rest of the brain’s environment variables.
Bring your own model, bring your own auth
Section titled “Bring your own model, bring your own auth”corral-harness workers bring their own model and their own auth — e.g. a
Claude Code agent running on a Claude Pro/Max subscription instead of
per-call API billing. The herd “contract” is nothing but MCP tool calls
against the brain (bootstrap → claim_task → work → complete_task);
corral-agent is merely the reference implementation of that same contract,
wired to a local Ollama model by default (MODEL_BACKEND=ollama,
AGENT_MODEL=qwen2.5-coder:7b) or any OpenAI-compatible endpoint
(MODEL_BACKEND=openai, e.g. Gemini or OpenRouter). Neither binary is
special-cased brain-side — both are ordinary MCP clients.
Comparing models on the same work
Section titled “Comparing models on the same work”corral-admin analyze can report on model_comparison across a mission’s
agents once more than one model has done work in it — findings raised (by
severity) and how they were resolved (addressed vs. dismissed vs. still
open — the open count is derived as raised minus resolved, floored at zero),
broken out per model, so an A-vs-B run isn’t just a vibe.
The fleet view
Section titled “The fleet view”Beyond a single mission, CORRALAI_MOTHERDUCK turns on a DuckDB bridge that
incrementally rolls the coordination audit/action stream from many brains
into one MotherDuck database, tagged by brain — federation-ready across
machines. ask_fleet is a natural-language oracle over that same rolled-up
history (“what did agent X do across every mission? who ingested that
document?”), running its own locked-down DuckDB connection with the local
filesystem disabled — it can read the MotherDuck-attached fleet tables and
nothing else on disk. This is real today, not a roadmap slide, though it’s
optional: unset CORRALAI_MOTHERDUCK and a brain runs standalone with no
loss of single-brain function.
This fleet-oracle surface is product-side and credentialed: it is never
wired into the public site. The site’s own recordings page
computes its per-model and per-severity numbers at build time with plain
DuckDB over committed recording streams instead — the public, uncredentialed
face of the same model_comparison idea above.