From eins78-skills
Convene a council of ~4 frontier models via the OpenRouter API for independent parallel reviews of a PR, plan doc, or files, then synthesize agreements and dissents in-session. Use for high-stakes or contested changes, before irreversible decisions, or when one extra model's opinion is not enough — costs real money per run. Triggers on /ai-council-review, "council review", "panel review", "multi-model review", "review with multiple models", "ask several models", "get a third opinion", "high-stakes review", "openrouter review". For a quick single-model second opinion, use ai-review instead.
How this skill is triggered — by the user, by Claude, or both
Slash command
/eins78-skills:ai-council-reviewThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Several frontier models review the same material in parallel — blind to each
README.mdjsconfig.jsonreferences/presets.jsonreferences/prompts/code-review.mdreferences/prompts/document-review.mdreferences/prompts/plan-review.mdreferences/report-template.mdreferences/synthesis.mdscripts/council.mjsscripts/lib/budget.mjsscripts/lib/cluster.mjsscripts/lib/config.mjsscripts/lib/input.mjsscripts/lib/openrouter.mjsscripts/lib/outcomes.mjsscripts/lib/prompts.mjsscripts/lib/schema.mjstests/budget.test.mjstests/cluster.test.mjstests/dispatch.test.mjsSeveral frontier models review the same material in parallel — blind to each other — via one API (OpenRouter). A dispatch script handles fan-out, cost gating, and clustering; you synthesize, because you can do the one thing the council cannot: verify findings against the actual repository.
This is the heavyweight sibling of ai-review (single model, $0.03). A
council run costs real money ($0.30–0.90 with default presets). Use it for
high-stakes decisions, not routine diffs.
Everything submitted (diffs, plan docs, file contents) is sent to the OpenRouter API and forwarded to multiple third-party model providers (different companies, different data-retention policies). For private or proprietary code this means unreleased source leaves the machine.
.env
files, credentials, or customer data in the input.node --version)OPENROUTER_API_KEY exported (get one: https://openrouter.ai/keys).
The script reads it from the environment only and never prints it. If it is
missing, dispatch exits with code 4 — ask your human partner; do NOT hunt
for keys in keychains, dotfiles, or session archives.ai-review fallback — do not
write "what the model would probably say", and do not pass your own review
off as a member's.--yes on your own. --yes asserts that your human partner
saw the printed cost estimate and approved it in this session. Budget
gate refusals (exit 3) are a stop, not an obstacle to route around.Script: ${CLAUDE_SKILL_DIR}/scripts/council.mjs (always via this absolute
path — never a relative ./scripts/...).
| Input | Flags | Rubric |
|---|---|---|
| GitHub PR | --pr <N> | --rubric code |
| Unstaged / staged / branch diff | (default) / --staged / --branch [base] | --rubric code |
| Plan or design doc | <file> or --plan <file> | --rubric plan |
| Any other document/files | <file...> or --input-file <f> | --rubric doc |
Preset: code rubric → --preset code; otherwise the default preset is
already right. --models a,b,c overrides for custom councils.
--personas runs the council in coverage mode: each member gets a
distinct focus lens (correctness, security, design, testing, operations)
on top of the shared rubric. This trades consensus signal for breadth —
agreement counting is invalid across different assignments, and the
synthesis protocol switches to coverage mode. Prefer it for broad material
(a large plan, a many-concern diff); prefer the identical-rubric default
when the question is "is this correct?" and agreement should mean
something.
node ${CLAUDE_SKILL_DIR}/scripts/council.mjs review <flags> --dry-run
Show the user the per-model table and total. If the estimate exceeds the confirmation threshold (default $1), you MUST get an explicit go-ahead in this session before step 3.
node ${CLAUDE_SKILL_DIR}/scripts/council.mjs review <same flags> [--yes]
The script fans out in parallel, retries once on 429/5xx, aborts hung
members at the timeout, persists everything, and prints RUN_DIR=<path> as
its last line.
| Exit | Meaning | Your move |
|---|---|---|
| 0 | Quorum met (check degraded in manifest) | Synthesize (step 4) |
| 1 | Usage/input error (bad slug, empty diff, oversized payload) | Fix per the message; slug errors include suggestions — update roster, retry |
| 2 | Quorum failed | Report which members failed and why; offer ai-review fallback; do NOT synthesize or self-substitute |
| 3 | Budget gate blocked (nothing sent) | Relay the estimate to your human partner; only proceed how they decide |
| 4 | API key missing/rejected | Ask your human partner to set OPENROUTER_API_KEY |
Follow ${CLAUDE_SKILL_DIR}/references/synthesis.md step by step. Core
moves: members are anonymized (member-A…) — do not open
roster-key.json until the report step; agreement is counted over
delivered members; parse-failed members' raw text is read and included; top
findings are verified against the actual repo before being reported;
dissent is preserved as contested items and minority reports; ranking is
verified > severity > agreement > confidence.
Write report.md into the run dir per
${CLAUDE_SKILL_DIR}/references/report-template.md; give the user the
condensed version in chat with actual vs estimated cost. Then record the
verification outcomes (outcomes record, synthesis protocol step 8) — the
archive is what makes future rosters evidence-based.
Only on explicit user request, post findings with gh pr comment (or a
formal review via gh api). The script never posts anywhere.
A suggestion for material that may not need a frontier council — nothing enforces it:
--preset budget (3 cheaper members) first.default/max only if the budget run produced
majors/blockers or contested clusters — objective properties of
clusters.json, not a feeling.Each stage passes the same estimate and consent gates; escalation is a second run with its own estimate. Prior art: cascade cost controls (cheap-first with objective escalation triggers).
Each cluster in clusters.json has a fingerprint stable across runs
(built from files + title tokens, not member labels or line numbers). When
a council run follows an earlier run of the same material:
clusters.json; classify
clusters as new / persisting / resolved. Fingerprints are a hint —
confirm matches semantically before reporting them.Precedence: flags > AI_COUNCIL_* env > repo .ai-council.json >
~/.config/ai-council-review/config.json > bundled
references/presets.json (presets: default, code, budget, max,
smoke; scalars: budgetUsd, confirmThresholdUsd, timeoutMs,
quorum, preset).
Useful env: OPENROUTER_BASE_URL (testing), COUNCIL_TIMEOUT_MS,
REVIEW_BASE_BRANCH (for --branch).
Run artifacts live under ~/.local/state/ai-council-review/<repo>/<run-id>/
(override: --out). They contain the reviewed source — treat as sensitive;
never commit them.
node ${CLAUDE_SKILL_DIR}/scripts/council.mjs models # current council + live pricing
node ${CLAUDE_SKILL_DIR}/scripts/council.mjs models --verify a,b # diagnose slugs
Model slugs churn. When dispatch exits 1 with "Unknown model slug", the fix
is a roster update (config override or a patch to references/presets.json)
— pick the suggested replacement closest in capability.
npx claudepluginhub eins78/agent-skills --plugin tmux-controlGuides completion of development work by verifying tests, detecting environment, and presenting structured options for merge, PR, or cleanup.
Guides creation and editing of skills using test-driven development with pressure scenarios and subagents to verify agent compliance.
Dispatches multiple subagents concurrently for independent tasks without shared state. Use when facing 2+ unrelated failures or subsystems that can be investigated in parallel.