| name | sparring |
| description | Use when the user says "sparring", "run sparring with Claude", "do sparring with Claude", "do sparring with GPT-5", "sparring with Codex", "sparring my plan with Claude", "discuss this approach with Codex", "get a second opinion through sparring", "give me the sparring transcript", "read the long sparring answer", or asks to leave a sparring session running. Runs a model-vs-model sparring flow through the bundled sparctl harness for planning, brainstorming, second opinions, code review, architecture critique, or normal dialogue; uses one ask-session command that creates or continues provider-native state, and uses tmux only when explicitly needed for live/fallback sessions. |
Sparring
Use this skill after it has been selected for a sparring request with another CLI agent. The skill turns that request into a concrete workflow through the bundled sparring harness.
Production rule: use ask-session with a unique temporary state file. The same command creates the provider-native session on the first turn and resumes it on later turns. Use tmux only when non-interactive CLI mode is unavailable or when the user explicitly wants a live attachable TUI session; do not expose tmux as a second normal workflow.
Scope
After this skill is selected, use it only for sparring-style requests with another model or CLI agent. Do not use it for ordinary non-interactive shell commands where stdout alone is the requested result.
Requirements
This skill expects:
- The bundled
bin/sparctl, lib/print-agent.sh, and lib/tmux-agent.sh files from this skill folder.
- The requested opponent CLI installed, for example
claude or codex.
timeout from GNU coreutils for non-interactive CLI calls.
tmux only when using explicit live TUI mode.
Resolve the harness path in this order:
- Use this skill's own bundled harness:
<skill directory>/bin/sparctl.
- If the runtime exposes a “Base directory for this skill” line, treat that directory as
<skill directory>.
- If you are developing the skill locally and
SPARRING_HOME is explicitly set, it may override the bundled path for testing only.
- If no executable bundled
bin/sparctl exists, report SPARRING_HARNESS_MISSING and include the skill directory you checked.
Do not silently fall back to raw tmux when sparctl is missing; the harness contains the tested session and tmux behavior.
Language Rule
Use the user's request language for the opponent prompt and for the final response.
If the user writes in Russian, send the opponent a Russian prompt and return Russian output. If the user writes in English, send the opponent an English prompt and return English output. If the user mixes languages, prefer the dominant language of the task.
When asking the opponent for structured output, include the language requirement explicitly:
Answer in Russian because the user's original request is in Russian.
Supported Opponent Backends
Opponent names in the user's request describe intent; harness names describe installed CLI backends. The model used behind each backend depends on that CLI's own configuration.
The bundled non-interactive providers support these CLI backends:
| Harness backend | CLI command |
|---|
claude | claude -p |
codex | codex exec |
Common wording for claude: Claude, Claude Code, Anthropic CLI, the Claude CLI.
Common wording for codex: Codex, Codex CLI, OpenAI Codex, GPT through Codex.
Do not treat backend names as model names. Claude Code, GPT-5, or another model may be configured behind an installed CLI. If the user names only a model family, do not silently choose a backend unless the request or current context clearly says which installed CLI should represent it. Ask a short clarification or use an explicitly configured harness/backend.
Before using a provider, check that the corresponding CLI exists:
command -v claude
command -v codex
If the CLI is missing, report it directly and do not substitute another agent silently.
Harness Commands Used By This Skill
Use the resolved bundled sparctl path. In examples below, $SPARRING_HARNESS means the executable at <skill directory>/bin/sparctl.
Default command for a fresh sparring session:
$SPARRING_HARNESS ask-session <name> /tmp/<name>-sparring.log "<prompt>" /tmp/<name>-turn.txt
Command meanings:
ask-session: non-interactive CLI call with provider-native session state (claude --session-id then claude --resume; codex exec then codex exec resume) plus a local audit file.
Non-interactive providers receive prompts through stdin, not argv. This keeps long session prompts away from process listings and avoids shell argument-size limits. Empty successful provider answers are treated as errors by the harness.
General Sparring Loop
Use this loop for planning, architecture discussion, brainstorming, second opinions, code review, and normal dialogue:
- Resolve the opponent backend from the user's wording and available CLI tools. If the user names only a model family without a clear CLI backend, ask one short clarification instead of guessing.
- Build a prompt in the user's language asking for an independent response that follows the structured sparring protocol below. Tell the opponent to answer directly in the provider response, not by creating files, plans, notes, or other artifacts. Remind the opponent to counter the common model tendency to be agreeable: their role is to test the task critically, not to please the user or the main agent.
- Use
ask-session with a unique temporary state file. Reuse that same state file for follow-up turns in the same sparring flow. Do not reuse old state files for unrelated requests because provider-native session state can carry stale context.
- Read the output file and compare the opponent's answer with your own position: what you accept, what you reject, what remains disputed, and what new questions appeared.
- If required user data is missing, stop the sparring instead of debating on invented assumptions. Return to the user with a concise question list explaining what data is needed, why it matters, and which decisions are blocked.
- If important disputed points remain, send a focused follow-up turn. Name the exact disagreements and ask the opponent to defend strong arguments, revise weak ones, or propose a synthesis.
- Continue only while the next turn can improve the decision: unresolved high-impact disagreements, unchecked assumptions, outdated approach risks, important trade-offs, or shallow/over-agreeable answers.
- Stop when the key decisions are agreed, or when remaining disagreements are clearly documented as trade-offs that cannot be resolved without external/user data.
- Delete the temporary output file after reading it unless the user explicitly asks to keep artifacts.
- If continuing the debate, keep the same
ask-session state file and send the next turn through it.
- If the sparring is finished, delete the state/session file too unless the user explicitly asks to keep it.
- Answer the user with a structured synthesis, not a raw transcript.
Opponent Output Rules
The opponent must answer directly in the provider response captured by the harness. Do not ask the opponent to create files, write plans, save notes, update repository files, or put the full answer somewhere else for later reading. The harness already writes the provider response to the configured output file; extra opponent-created artifacts make the sparring loop easy to misread or prematurely stop.
If the opponent says it needs to reference evidence, it should quote or summarize the relevant evidence in the direct answer. If the opponent cannot answer without missing data, it should list the missing data directly in the answer instead of creating a separate file or asking the main agent to inspect an artifact.
Continue/Stop Gate
After every opponent answer, explicitly decide whether another sparring turn is useful. Continue the sparring when the next turn can still change the recommendation, especially when any of these are true:
- The opponent made a factual claim that conflicts with observed evidence.
- The opponent named a blocker or high-severity risk that was not independently verified.
- The opponent skipped a disputed point, gave an evasive answer, or answered too shallowly for the risk level.
- Your own verification after the opponent answer produced new evidence that the opponent has not addressed.
- The opponent's recommendation depends on a trade-off that remains unresolved and material.
Stop the sparring only when the key claims are verified or clearly marked as unverified, high-impact disagreements are resolved or preserved as explicit trade-offs, and another turn is unlikely to improve the decision. Do not turn the first opponent answer into a final user-facing synthesis when the gate says a focused rebuttal would still be useful.
Structured Sparring Protocol
The opponent prompt should make the opponent work in layers, not jump straight into implementation details:
- First, fix the subject of discussion: what task was understood, what the main goal is, what constraints matter, and which assumptions are being made.
- Then check the high-level framing: whether the right problem is being solved, whether the proposed direction is necessary, whether there is unnecessary complexity, duplicated concepts, or a simpler model.
- Check freshness: whether the proposed approaches, patterns, libraries, APIs, and tools are current. When freshness matters and the opponent has web access, ask it to use web search or current documentation before recommending a solution.
- Produce a list of disputed points: what should be challenged, what is weak, where alternatives exist, where trade-offs exist, and what must be decided before a final answer.
- Only after that, answer the concrete request.
The goal is not artificial agreement. The goal is the best tested solution after criticism. If consensus is not possible, preserve the disagreement as an explicit trade-off with reasons.
For the opponent prompt, adapt this shape into the user's language:
<User task in the original language>
You are the second participant in a sparring session. Do not accept the framing automatically: check whether the task is understood correctly, challenge weak assumptions, identify unnecessary complexity, and then answer the concrete request. Also check whether the proposed approaches, patterns, libraries, APIs, and tooling are current rather than outdated; when freshness matters and you have web access, use web search or current documentation before recommending a solution. Answer in the same language as the user's task. Do not edit files.
Do not create files, plans, notes, or other artifacts. Put the full answer directly in this response. If you need to cite evidence, quote or summarize it here instead of writing it elsewhere.
First fix the subject of discussion: restate the understood task, main goal, important constraints, and key assumptions. Then check the high-level framing, freshness of approaches/tools, and possible simplifications. After that, list the disputed points that should be challenged or decided before a final conclusion.
If required user data is missing, say exactly what is missing and why the decision is blocked. Do not invent missing data or continue on hidden assumptions.
Important: models often tend to agree with and please the user or another agent. In this role, counterbalance that bias: test assumptions critically, name weak points directly, and do not agree if the position seems incomplete, overcomplicated, outdated, or wrong. At the same time, do not argue artificially when the arguments are genuinely strong.
If the main agent's next turn contains doubts or objections to your position, do not agree automatically: defend your assessment where it is strong, clarify weak spots, and state explicitly what should be reconsidered.
Non-Interactive CLI Examples
Fresh sparring session:
$SPARRING_HARNESS ask-session claude /tmp/claude-sparring.log "<prompt>" /tmp/claude-turn.txt
$SPARRING_HARNESS ask-session codex /tmp/codex-sparring.log "<prompt>" /tmp/codex-turn.txt
Tmux Live Mode
Use tmux mode only when non-interactive CLI mode is unavailable, fails due limits/auth, or the user explicitly wants an attachable live session. Decide this operationally; do not present tmux as a separate standard mode unless it remains running for the user.
$SPARRING_HARNESS start [--replace] <name> <agent-command>
$SPARRING_HARNESS start claude
$SPARRING_HARNESS start --replace claude
$SPARRING_HARNESS ask-watch <name> "<prompt>" /tmp/<name>-watch.txt
$SPARRING_HARNESS transcript <name> /tmp/<name>-transcript.txt
$SPARRING_HARNESS stop <name>
Here <name> is the harness agent name, for example claude; the tmux session is named spar-<name>. Persistent starts are safe by default: start <name> fails if spar-<name> already exists. Use --replace only when intentionally killing and recreating that session. If start reports SPAR_SPAWN_SESSION_EXISTS, do not retry with --replace automatically; ask whether the user wants to attach, stop, or replace the existing session.
Tell the user they can attach manually with:
tmux attach -t spar-<name>
Long Answers
For non-interactive CLI mode, the full answer is written directly to the output file. Read it with the file reading tool using offsets/limits if it is long.
For tmux mode, prefer ask-watch or transcript for very long answers because rendered scrollback can be noisy and bounded.
Session Lifecycle
If using non-interactive CLI mode, cleanup temporary output/state files after summarizing unless the user asks to keep them. This is mandatory for routine review/sparring: after reading /tmp/<name>-turn.txt, remove it; remove /tmp/<name>-sparring.log when the dialogue will not continue.
If the user asks for an ongoing tmux sparring session, leave it running and report the attach command.
If the user asks for a quick tmux test, cleanup after the test:
$SPARRING_HARNESS stop <name>
Reporting Back
Report briefly:
- Use a structured, human-readable synthesis rather than a transcript dump.
- Include a short final recommendation first.
- Include the understood task, high-level framing checks, disputed points, agreements, changed decisions, compared alternatives, remaining trade-offs, and next steps.
- Use tables, short lists, and comparisons when they make the result easier to scan.
- If missing user data stopped the sparring, return a question table with: question, why it is needed, and what decision it affects.
- Mention which opponent backend and mode were used (
ask-session or tmux), but keep mechanics secondary to the decision.
- Mention state/session file paths only if they remain useful for continued sparring.
- Preserve the user's language in the final answer unless they explicitly ask otherwise.