council
Multi-expert CLI committee. Fan out one question to N expert CLI-instances, run a two-round debate (blind R1 + peer-aware R2), then distribute the final decision across all experts via a vote. Every run is archived on disk as file artifacts for audit.
Status: v2 — debate engine with anonymized multi-round rounds and distributed voting.
📖 Plain-language overview (Russian): Council — лучший ответ на любой вопрос — what Council does, why voting instead of a judge, and the research backing each design decision.
Why
A single opinion from a single LLM is noisy. Running the same question through multiple expert personas, letting them critique each other's drafts in a second round, and then voting among them removes single-model bias without reintroducing a judge. Inspired by:
What's new in v2
- Two-round debate (
rounds: 2): R1 is blind (each expert answers independently), R2 is peer-aware (each expert sees every other expert's R1 output, anonymized).
- Anonymization: experts are relabeled
A, B, C, … derived from the session ID so the cohort is rotated per run.
- Per-session nonce + forgery detection on LLM outputs — every structural fence the orchestrator emits carries a
[nonce-<16hex>] === suffix, and any matching line in a subprocess's stdout is rejected (ADR-0008 as amended by ADR-0011). Benign markdown dividers like === Section === pass the scan.
- Voting stage: every active expert casts a ballot on the R2 aggregate; the winner's published answer is printed to stdout (clean JSON-tail extraction by default — see below — with fail-closed fallback to the raw R2 body). A tie surfaces
output-A.md, output-B.md, … and exits 2 (no_consensus).
council resume subcommand: finish an interrupted session without re-running completed stages.
verdict.json.version bumps to 2; shape documented in docs/design/v2.md.
- Published answer is a clean extraction from the winner's R2 JSON tail: every R2 ends with a fenced JSON block containing a peer-free
answer, and that string lands in output.md and verdict.answer. Raw R2 with full peer-engaged reasoning stays in rounds/2/experts/<label>/output.md unchanged. Extraction is fail-closed — missing or malformed JSON falls back to writing the raw R2 (today's pre-extraction behavior). The outcome is recorded in verdict.json.answer_extraction. See ADR-0014.
Web tools
Experts always spawn with WebSearch and WebFetch available in both R1 and R2. Ballot subprocesses always run tools-off. There is no profile knob, no CLI flag, and no environment variable — the behaviour is hardcoded in the debate layer and translated to --allowedTools / --permission-mode bypassPermissions by the claude-code executor.
- Token cost: expect 8–15× the v1 token spend on research-heavy questions. General-knowledge questions with no fetch stay close to v1 cost.
- Latency: plan for 3–5 min per session wall-clock on research-heavy runs (per-expert
timeout: 300s in the shipped profile).
- Audit: the R1/R2 prompts instruct experts to cite URLs inline. Query with
grep -oE 'https?://[^ ]+' .council/sessions/<id>/rounds/*/experts/*/output.md. verdict.json is unchanged — there is no structured per-fetch trail.
See ADR-0010, ADR-0011, and docs/design/v2-web-tools.md for the full rationale.
Install
Requires Go 1.25+ (as declared in go.mod).
v3 fans the debate across three vendor CLIs (Anthropic / OpenAI / Google) so the cohort has true cross-model heterogeneity instead of three samples of one distribution. You only need one of them on $PATH to run, but the shipped default profile and quorum (2-of-3) assume all three. See ADR-0012 and docs/design/v3-multi-cli.md.
Install council itself:
go install github.com/fitz123/council/cmd/council@latest
Or build from a clone:
git clone https://github.com/fitz123/council.git
cd council
go build -o council ./cmd/council
Install the CLI vendors (each is subscription-based — no API keys):