9.0 KiB
name, description
| name | description |
|---|---|
| debate-orchestrator | Orchestrates formal debates with proposition and opposition sides, coordinating debaters and judges through structured exchanges. Use when running debate exchanges, managing debate rounds, or continuing interrupted debates. |
Debate Orchestrator
Manages formal debate execution through deterministic state tracking and resumability.
State Machine
Debates cycle through 2 phases per exchange:
| current_phase | Action Required |
|---|---|
awaiting_arguments |
Spawn both debaters in parallel |
awaiting_judgment |
Spawn judge to evaluate all new arguments |
After judgment: cycle repeats with current_exchange incremented.
Key Properties:
- No "complete" state - orchestrator decides when to stop based on requested exchange count
- Parallel execution - both sides argue simultaneously each exchange
- Resumable - read state, execute required action, repeat
- Exchange 0 is special (opening) - both sides produce 3 independent arguments
- Exchange 1+ are rebuttal - sides produce single arguments with attacks/defends
Running Exchanges
1. Read State
Check {debate}/debate.md frontmatter (JSON format):
{
"current_exchange": 0,
"current_phase": "awaiting_arguments"
}
Extract motion from the # Motion section (first markdown heading after frontmatter).
2. Determine Exchange Type
Opening Exchange: current_exchange == 0
- Both debaters produce 3 independent arguments simultaneously
- Judge scores all 6 arguments
Rebuttal Exchange: current_exchange >= 1
- Both debaters produce 1 argument simultaneously
- Judge scores both new arguments
3. Execute Based on Phase + Exchange Type
Opening Exchange (Exchange 0)
When current_exchange == 0 and current_phase == awaiting_arguments:
Load template:
Read templates/debater-opening.md from this skill's directory.
Spawn both debaters in parallel:
Use a single message with two Task tool invocations to spawn both debaters simultaneously.
For each side (proposition and opposition):
-
Substitute placeholders in template:
{motion}: Extracted motion text{side}: Side name (propositionoropposition)
-
Spawn debater:
Use Task tool with subagent_type: "debater" Prompt: [substituted template content]
Process outputs:
After both debaters complete:
- Write proposition output to
/tmp/prop_arg.json - Write opposition output to
/tmp/opp_arg.json - Execute the python package
debate_ops:python3 {skill_base_dir}/debate_ops process-exchange {debate} 0 --prop-file /tmp/prop_arg.json --opp-file /tmp/opp_arg.json
Check result JSON for errors or warnings. On errors, state remains unchanged - report to user and halt. On warnings, note them and continue.
The script creates 6 argument files: prop_000a.md, prop_000b.md, prop_000c.md, opp_000a.md, opp_000b.md, opp_000c.md
State automatically updates to current_phase: awaiting_judgment.
Judge opening arguments:
When current_exchange == 0 and current_phase == awaiting_judgment:
Load template:
Read templates/judge.md from this skill's directory.
Substitute placeholders:
{argument_files}: Space-separated list of all 6 opening arguments:@{debate}/arguments/prop_000a.md @{debate}/arguments/prop_000b.md @{debate}/arguments/prop_000c.md @{debate}/arguments/opp_000a.md @{debate}/arguments/opp_000b.md @{debate}/arguments/opp_000c.md{motion}: Extracted motion text
Spawn judge:
Use Task tool with subagent_type: "judge"
Prompt: [substituted template content]
Process output:
- Use Write tool to save agent output to
/tmp/judge.json - Execute the python package
debate_ops:python3 {skill_base_dir}/debate_ops process-judge {debate} --json-file /tmp/judge.json
Check result JSON for errors or warnings. On errors, state remains unchanged - report to user and halt. On warnings, note them and continue.
State automatically updates to current_phase: awaiting_arguments, current_exchange: 1.
Rebuttal Exchange (Exchange 1+)
When current_exchange >= 1 and current_phase == awaiting_arguments:
Build argument context:
- List all files in
{debate}/arguments/ - Separate into proposition and opposition arguments:
- Proposition: Files matching
prop_*.md - Opposition: Files matching
opp_*.md
- Proposition: Files matching
- Filter to arguments from previous exchanges only:
- Extract exchange number from filename (e.g.,
prop_003→ exchange 3) - Include only arguments where exchange < current_exchange
- Extract exchange number from filename (e.g.,
- Sort by exchange number (chronological order)
Load template:
Read templates/debater-rebuttal.md from this skill's directory.
Spawn both debaters in parallel:
Use a single message with two Task tool invocations to spawn both debaters simultaneously.
For proposition debater:
- Substitute placeholders:
{motion}: Extracted motion text{side}:proposition{exchange}: Current exchange number{your_arguments}: Newline-separated list:@{debate}/arguments/prop_000a.md,@{debate}/arguments/prop_000b.md, etc.{opponent_arguments}: Newline-separated list:@{debate}/arguments/opp_000a.md,@{debate}/arguments/opp_000b.md, etc.
For opposition debater:
- Substitute placeholders:
{motion}: Extracted motion text{side}:opposition{exchange}: Current exchange number{your_arguments}: Newline-separated list of opposition arguments{opponent_arguments}: Newline-separated list of proposition arguments
Process outputs:
After both debaters complete:
- Write proposition output to
/tmp/prop_arg.json - Write opposition output to
/tmp/opp_arg.json - Execute the python package
debate_ops:python3 {skill_base_dir}/debate_ops process-exchange {debate} {current_exchange} --prop-file /tmp/prop_arg.json --opp-file /tmp/opp_arg.json
Check result JSON for errors or warnings. On errors, state remains unchanged - report to user and halt. On warnings, note them and continue.
State automatically updates to current_phase: awaiting_judgment.
Judge rebuttal arguments:
When current_exchange >= 1 and current_phase == awaiting_judgment:
Load template:
Read templates/judge.md from this skill's directory.
Substitute placeholders:
{argument_files}: Space-separated list of both new arguments:@{debate}/arguments/prop_{current_exchange:03d}.md @{debate}/arguments/opp_{current_exchange:03d}.md{motion}: Extracted motion text
Spawn judge:
Use Task tool with subagent_type: "judge"
Prompt: [substituted template content]
Process output:
- Use Write tool to save agent output to
/tmp/judge.json - Execute the python package
debate_ops:python3 {skill_base_dir}/debate_ops process-judge {debate} --json-file /tmp/judge.json
Check result JSON for errors or warnings. On errors, state remains unchanged - report to user and halt. On warnings, note them and continue.
State automatically updates to current_phase: awaiting_arguments, current_exchange incremented.
4. Decide When to Stop
After each phase, check if you should continue:
- Read the updated state from
{debate}/debate.md - Compare current exchange number to requested total exchanges
- If sufficient exchanges completed: stop and report
- Otherwise: loop back to step 1
The state itself doesn't track "completion" - you decide when done based on user request.
Error Handling
Processing scripts return:
{
"success": true/false,
"argument_id": "prop_001" | ["prop_000a", "prop_000b", "prop_000c"],
"errors": ["fatal errors"],
"warnings": ["non-fatal warnings"]
}
On errors:
- State remains unchanged - can safely retry
- Report error to user
- Ask how to proceed (retry, skip, abort)
On warnings:
- Note them
- Continue execution
- Mention warnings in completion summary
Note: By default the tmp files get deleted by the script. But if you face errors while writing to a tmp file because it already exists, just Read it and try again.
Resumability
Execution can be interrupted at any point and resumed by reading state:
- State indicates exactly what phase is needed next
- Execute that phase
- State updates atomically on success
- On failure, state remains unchanged - retry is safe
Completion Report
When requested exchanges complete, report current state:
✓ Completed {N} exchanges for '{debate_slug}'
**Current Scores** (zero-sum tug-of-war):
- Proposition: {total} ({count} arguments)
- Opposition: {total} ({count} arguments)
**Next steps**:
- Continue debating: `/debate-run {debate_slug} X` to run X more exchanges
- Generate report: `/debate-report {debate_slug}` to create comprehensive analysis with visualizations
Extract totals and counts from cumulative_scores in {debate}/debate.md frontmatter.
Total exchanges = current_exchange from debate.md.
Note on zero-sum scoring: Positive total = winning, negative total = losing, zero = even. One side typically has positive total, the other negative (tug-of-war).