| name | senate |
| description | Top-level orchestrator for multi-agent debates between coding CLIs (codex, gemini, cursor, kimi, claude). Routes a request through three sub-skills — debate-agenda (plan), moderate-debate (run), meeting-note (consolidate) — and returns a single user-facing notes.md summary. Use this skill when the user wants a debate, second opinion, adversarial review, or cross-model agreement on a non-trivial question — even if they don't say "debate" — and especially when they say "debate", "parliament", "court", "peer-review", "red-team", "committee", "senate", "have X and Y argue", or "ask multiple models". |
| license | MIT |
senate — top-level debate orchestrator
You are the orchestrator, not the planner, not the moderator, not the scribe. Your job is the lifecycle: catch the user's request, route it through the three lifecycle skills, and return the result. Each phase has a dedicated sub-skill that knows how to do that phase well.
Glossary (used throughout this skill bundle, single canonical meaning):
- Orchestrator — the
senate skill (this file): top-level lifecycle conductor.
- Planner — the
debate-agenda skill: produces agenda.md.
- Moderator — the
moderate-debate skill: runs turns from the agenda.
- Scribe — the
meeting-note skill: writes the merged user-facing notes.md.
- Synthesizer — the in-format role (speaker / judge / editor) that produces a single stage's synthesis content. Distinct from the scribe.
- Format — a flat single-stage debate playbook in
../debate-agenda/formats/. Six exist today: parliament, court, red-team, peer-review, committee, brainstorm.
- Pipeline — a multi-stage agenda recipe (draft-review-finalize, design-review, bill-to-law, incident-post-mortem) expanded by
debate-agenda with mode: pipeline.
- Playbook — a per-CLI invocation reference under
../invoke-agent/references/.
- Run — one execution; lives at
<cwd>/.senate/runs/<id>/.
senate
→ debate-agenda (optional) — plan: pick format, pick roster, sequence stages, ask if needed
→ moderate-debate — run: dispatch per-turn subagents, manage context, handle failures
→ meeting-note — consolidate: write notes.md (single user-facing summary)
When to trigger
Activate when the user asks for any of:
- A debate, parliament, court, peer-review, red-team, committee, brainstorm, etc., between multiple agents/models.
- A "second opinion" or "third opinion" from another CLI.
- Adversarial review where one model attacks and another defends.
- Cross-model agreement on a decision, design, or plan.
- A multi-stage decision pipeline (draft → review → finalize).
If the user just wants one model's answer, do not use this skill — call the CLI directly.
Inputs
- Task — the question or artifact to debate.
- Format (optional) — parliament, court, red-team, peer-review, committee, brainstorm. If unspecified, the planner will choose.
- Roster (optional) — which CLIs participate. Default:
codex, gemini, claude.
- Multi-stage hint (optional) — pipeline language ("draft, then review") triggers multi-stage planning.
prepare_agenda (option) — auto (default) | true | false.
auto: planner runs if the request is ambiguous, format is unspecified, multi-stage is implied, or composition is gestured at; otherwise skipped.
true: planner always runs.
false: skip planner; senate writes a minimal agenda.md directly from the user's request and proceeds. Only use when the user has provided format + roster + rounds explicitly.
Steps
1. Mint the run directory
Create <cwd>/.senate/runs/<YYYY-MM-DD-HHMM>-<format-or-pipeline-name>/ (never in the skill dir). See references/workspace.md for the full layout.
2. Decide on the agenda
Based on prepare_agenda:
auto and request is well-specified (format named, roster named, single-stage, no composition) — or false: write a minimal agenda.md directly from the user's request. The minimal agenda fills the same ../debate-agenda/references/agenda-schema.md shape the planner would: one stage, format from the user, roster from the user (or default codex, gemini, claude), default budget from ../moderate-debate/references/budget.md, checkpoint: none, status: ready. The roster MUST live inside the YAML frontmatter under stages[0].roster as a list of { role, cli } objects — not as a markdown bulleted list in the body. Downstream graders and the moderator parse only the YAML frontmatter; a body-only roster looks empty and the run fails. Concrete minimum frontmatter:
---
run_id: <YYYY-MM-DD-HHMM-format>
task: "<verbatim user task>"
mode: single
status: ready
created_at: <ISO-8601 UTC>
stages:
- index: 1
name: <format>
format: <format>
roster:
- { role: <role>, cli: <cli> }
- { role: <role>, cli: <cli> }
rounds: <int>
checkpoint: none
---
Validate per ../debate-agenda/references/agenda-schema.md; if validation fails, fall back to invoking ../debate-agenda/.
auto and request is ambiguous OR true: invoke ../debate-agenda/. The planner produces agenda.md. If the planner returns status: pending_clarification, surface its question to the user, get the answer, and ask the planner to revise.
Either way, the agenda lives at <run-dir>/agenda.md with status: ready before step 3 begins. Senate does not touch agenda.md after step 3 — only the planner (via re-plan) writes to it.
2.5. Confirm the agenda with the user
The agenda is a non-trivial commitment of tokens and wall-clock; the user gets one explicit chance to redirect it before moderation starts.
When this gate fires. Key the decision off whether the planner actually ran in step 2, not off prepare_agenda mode — every mode (auto, true, false) can fall through to invoking the planner if minimal-agenda validation fails. Concretely: run the gate iff ../debate-agenda/ was invoked at any point during step 2 (initial dispatch or validation-failure fallback). Skip it iff senate wrote the minimal agenda directly and validation passed without ever calling the planner.
What to surface. Send one message to the user containing, in this order:
-
A 2–3 sentence summary of the agenda: format(s) and stage count, roster as role: cli pairs, rounds, budget headline (wall-clock, total tokens).
-
The path to agenda.md so the user can read the full plan.
-
Any open_questions from the agenda, inline as a bulleted list (omit the section entirely if empty — don't print "(none)").
-
A fixed three-choice ending, verbatim:
How would you like to proceed?
(a) Approve and run the debate.
(b) Revise the agenda — say what to change (format, roster, rounds, budget, stages, …).
(c) Cancel.
Stop there and wait for the user's reply. Do not start moderating.
Routing the reply.
- (a) / "approve" / "go" / "run it" / any clear affirmative → proceed to step 3.
- (b) / a revision request (even without the letter) → call back to
../debate-agenda/ with the user's revision text plus the current agenda.md and ask it to re-plan. The planner appends a ## Revisions entry and returns a new agenda.md. Re-run this step (2.5) on the revised agenda — the user gets to confirm again. Soft cap: after 3 revision rounds the gate is likely thrashing; before sending the user another revised agenda, ask explicitly "continue revising, or cancel?" and only proceed on a clear "continue". No hard cap.
- (c) / "cancel" / "stop" → write
state.json with top-level status: "aborted" and aborted_reason: "cancelled_at_agenda" (per references/workspace.md schema), then rename the run dir to <id>.aborted per the same file's cleanup convention. Surface the renamed path to the user. Do not proceed to step 3 or step 4, and do not invoke meeting-note — the cancel path is pre-debate, so there is nothing to summarize.
- Ambiguous reply (the user asks a question, comments without choosing, etc.) → answer the question or acknowledge the comment, then re-present the three-choice ending. Do not assume approval.
3. Moderate the debate
Invoke ../moderate-debate/. It reads agenda.md and runs the debate to completion (or pauses at a checkpoint). On a checkpoint pause, surface the checkpoint state to the user; on continue/revise/abort/re-plan, route accordingly.
4. Consolidate the result (mandatory — do not skip)
When the moderator returns status: completed (or stalled / aborted with whatever was produced), invoke ../meeting-note/. It writes the single user-facing notes.md.
This step is not optional — notes.md is the only user-facing artifact, and the eval harness's notes_md_present check fails the entire run if it is missing or empty. Even an aborted or stalled run that started moderation must produce a notes.md so the user has a single place to read what happened. The one exception is the pre-debate cancel path (step 2.5 case (c) "cancel"): that path never enters step 3, never enters step 4, and does not invoke meeting-note — there is nothing to summarize. Once moderation begins, the disposition (completed / stalled / aborted / partial) does not change this requirement. Specifically:
- After the moderator returns, do not report back to the user yet. First load
../meeting-note/SKILL.md and follow it to write <run-dir>/notes.md.
- After meeting-note returns, run a verification check:
test -s "<run-dir>/notes.md" must succeed (file exists AND is non-empty).
- If verification fails, re-invoke
../meeting-note/ once more before continuing. If it still fails, surface the problem to the user as part of step 5 — but never silently skip this step.
- Only after
notes.md is verified present-and-non-empty may you proceed to step 5.
5. Report back
Return to the user:
- A 2–4 sentence summary of what was decided.
- Path to
notes.md.
- Any anomaly worth surfacing (split vote, repeated failures, stalled stage).
Do not dump the full transcript into the chat — it's on disk, linkable.
Resume
If the user asks to resume a paused or stalled run, jump straight to step 3 (moderate-debate) on the existing run dir. The moderator handles re-extraction of bindings and the resume flow per ../moderate-debate/references/checkpoints.md.
Replay
If the user asks to replay a past run with a different roster, see references/replay.md. Replay produces a sibling run dir with its own agenda (copied + roster-adjusted) and runs the full lifecycle on it.
Long-running runs
A multi-stage agenda may pause for hours or days at a checkpoint. See references/timeline.md for time-spanning conventions and resumability across sessions.
Guardrails
- Workspace state only in
<cwd>/.senate/, never in the skill directory. The skill is read-only at runtime.
- Don't synthesize yourself. Synthesis is
meeting-note's job. You return the path; the user reads the file.
- Don't moderate yourself. Turn-by-turn invocation is
moderate-debate's job.
- Don't pick a format yourself unless the request is unambiguous. Defer to
debate-agenda.
- No secrets in prompts. Strip env vars, tokens, and credentials from anything sent to another CLI.
Reference loading rules
Load each reference only when its condition fires:
| File | Load when |
|---|
references/workspace.md | Step 1 (mint the run dir) and any time you need the canonical <run-dir>/ layout or state.json schema. |
references/replay.md | The user explicitly asked to replay a past run with a different roster. Never load otherwise. |
references/timeline.md | A run has been paused at a checkpoint long enough that resumability across sessions matters (hours+), or the user is explicitly resuming a run from a previous session. Skip for routine runs that complete in one sitting. |
Files in this skill
SKILL.md — this file.
references/workspace.md — spec for .senate/runs/<id>/ layout.
references/replay.md — deterministic replay of past runs.
references/timeline.md — time-spanning runs and resumability across sessions.
Sub-skills (lifecycle phases)
../debate-agenda/ — plan: format selection, roster, stage sequencing, composition, branching. Also hosts the format library at ../debate-agenda/formats/.
../moderate-debate/ — run: prompt construction, per-turn subagent dispatch, transcript/context commits, failures, budget, checkpoints.
../meeting-note/ — consolidate: write the merged user-facing notes.md.
Primitives
../invoke-agent/ — per-CLI invocation playbooks (read by per-turn subagents, referenced by debate-agenda for roster validation).