plugins/base/skills/socratic-duel/SKILL.md
Run a bounded, evidence-driven two-agent debate into a separate rp1 debate artifact with backend locks only.
npx skillsauth add rp1-run/rp1 socratic-duelInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
§ROLE: Debate participant and debate artifact steward for /rp1-base:socratic-duel.
§OBJ
{TARGET_PATH} as read-only Markdown source material.debate_path under {workRoot}/debates/.{TOPIC} or the inferred effective topic.ACCEPTED_CONSENSUS, DISSENT, MAX_TURNS, TIMEOUT, or INVALIDATED.§BOUNDARY
/rp1-base:artifact-templates; do not implement or expect TypeScript template rendering.status is not debate truth. Treat the debate artifact as the debate record.rp1:socratic-duel boundary markers during normal recording.§TURN_RULES and §OUTCOMES in sync with plugins/base/agents/socratic-duel-participant.md.§CTX
RUN_ID, projectRoot, workRoot, codeRoot, resolved arguments.CURRENT_HOST: claude-code, codex, gh-copilot, opencode, amp, else unknown; default codex.TARGET_PATH: required absolute readable .md or .markdown source path. Do not require write access.TOPIC: optional. If blank, read the source document and use the first Markdown heading as the effective topic, falling back to the source filename stem.PARTICIPANT_NAME: required unique participant identity; do not replace it with CURRENT_HOST.MODEL_ID: if unknown, keep unknown-model; do not invent model metadata.debate_path, source_path, topic, and topic_slug come from join and are authoritative after registration.stateDiagram-v2
[*] --> preparing
preparing --> waiting_for_participant : peer_missing
preparing --> debating : ready
waiting_for_participant --> debating : peer_ready
waiting_for_participant --> closing : wait_timeout
debating --> debating : yielded
debating --> waiting_for_participant : peer_wait
debating --> closing : terminal
closing --> completed : accepted_or_dissent_or_timeout
closing --> invalidated : validation_failed
completed --> [*]
invalidated --> [*]
§EMIT On every primary state entry:
rp1 agent-tools emit --harness $CURRENT_HOST \
--workflow socratic-duel \
--type status_change \
--run-id {RUN_ID} \
--step {CURRENT_STATE} \
--data '{"status":"running","target":"{TARGET_PATH}","topic":"{TOPIC}"}'
Emit artifact_registered exactly once, immediately after the first Write that creates {debate_path} (in debating). Path is relative to workRoot:
rp1 agent-tools emit --harness $CURRENT_HOST \
--workflow socratic-duel \
--type artifact_registered \
--run-id {RUN_ID} \
--step debating \
--data '{"path":"debates/{DEBATE_FILENAME}","storageRoot":"work_dir","type":"markdown","source_path":"{source_path}","topic":"{topic}","duel_id":"{duel_id}"}'
Participant registration:
rp1 agent-tools emit --harness $CURRENT_HOST \
--workflow socratic-duel \
--type status_change \
--run-id {RUN_ID} \
--step preparing \
--unit participant:{participant_id} \
--data '{"status":"completed","event":"participant_registered","duel_id":"{duel_id}","participant_id":"{participant_id}","participant_count":"{participant_count}","source_path":"{source_path}","debate_path":"{debate_path}","topic":"{topic}"}'
Participant waiting, lock ownership, and lock release remain diagnostic unit events:
rp1 agent-tools emit --harness $CURRENT_HOST \
--workflow socratic-duel \
--type status_change \
--run-id {RUN_ID} \
--step waiting_for_participant \
--unit participant:{participant_id} \
--data '{"status":"waiting","event":"participant_waiting","duel_id":"{duel_id}","reason":"{reason}","retry_after_seconds":"{retry_after_seconds}","wait_until":"{wait_until}","debate_path":"{debate_path}","topic":"{topic}"}'
rp1 agent-tools emit --harness $CURRENT_HOST \
--workflow socratic-duel \
--type status_change \
--run-id {RUN_ID} \
--step debating \
--unit participant:{participant_id} \
--data '{"status":"completed","event":"lock_acquired","duel_id":"{duel_id}","lease_expires_at":"{lease_expires_at}","debate_path":"{debate_path}","topic":"{topic}"}'
rp1 agent-tools emit --harness $CURRENT_HOST \
--workflow socratic-duel \
--type status_change \
--run-id {RUN_ID} \
--step closing \
--unit participant:{participant_id} \
--data '{"status":"completed","event":"lock_released","duel_id":"{duel_id}","closed":"{closed}","debate_path":"{debate_path}","topic":"{topic}"}'
Turn composition and artifact update:
rp1 agent-tools emit --harness $CURRENT_HOST \
--workflow socratic-duel \
--type status_change \
--run-id {RUN_ID} \
--step debating \
--unit turn:{turn_number} \
--data '{"status":"running","event":"turn_composing","duel_id":"{duel_id}","participant_id":"{participant_id}","debate_path":"{debate_path}","topic":"{topic}"}'
rp1 agent-tools emit --harness $CURRENT_HOST \
--workflow socratic-duel \
--type status_change \
--run-id {RUN_ID} \
--step debating \
--unit turn:{turn_number} \
--data '{"status":"completed","event":"artifact_updated","duel_id":"{duel_id}","participant_id":"{participant_id}","candidate_convergence":"{candidate_convergence}","terminal_outcome":"{terminal_outcome}","debate_path":"{debate_path}","topic":"{topic}"}'
Terminal conclusion-only artifact updates use the same event shape with --step closing and --unit conclusion:{terminal_outcome}.
Candidate convergence emits btw_update only:
rp1 agent-tools emit --harness $CURRENT_HOST \
--workflow socratic-duel \
--type btw_update \
--run-id {RUN_ID} \
--step debating \
--data '{"message":"Candidate convergence detected; duel remains active until explicit terminal criteria are met.","metadata":{"duel_id":"{duel_id}","turn_number":"{turn_number}","candidate_convergence":true,"debate_path":"{debate_path}","topic":"{topic}"}}'
Terminal completion closes the run. Use status:"completed" for ACCEPTED_CONSENSUS, DISSENT, MAX_TURNS, and TIMEOUT:
rp1 agent-tools emit --harness $CURRENT_HOST \
--workflow socratic-duel \
--type status_change \
--run-id {RUN_ID} \
--step completed \
--close-run \
--data '{"status":"completed","outcome":"ACCEPTED_CONSENSUS|DISSENT|MAX_TURNS|TIMEOUT","duel_id":"{duel_id}","summary":"{summary}","debate_path":"{debate_path}","source_path":"{source_path}","topic":"{topic}"}'
Terminal invalidation closes the run as failed with a reason:
rp1 agent-tools emit --harness $CURRENT_HOST \
--workflow socratic-duel \
--type status_change \
--run-id {RUN_ID} \
--step invalidated \
--close-run \
--data '{"status":"failed","outcome":"INVALIDATED","duel_id":"{duel_id}","message":"{invalidation_reason}","debate_path":"{debate_path}","source_path":"{source_path}","topic":"{topic}"}'
§PROC
preparing
preparing.TARGET_PATH before joining: it must be absolute, readable, and end in .md or .markdown. Do not check or require source write access.invalidated with INVALIDATED, status:"failed", a clear message, and --close-run; stop without editing files.TOPIC, first Markdown heading, or filename stem.rp1 agent-tools socratic-duel join \
--target "{TARGET_PATH}" \
--topic "{EFFECTIVE_TOPIC}" \
--debate-dir "{workRoot}/debates" \
--participant-name "{PARTICIPANT_NAME}" \
--harness "$CURRENT_HOST" \
--model-id "{MODEL_ID}" \
--run-id "{RUN_ID}"
duel_id, participant_id, participant_count, status, source_path, topic, topic_slug, debate_path, and next_step.participant_registered with --unit participant:{participant_id}. Do not emit artifact_registered yet -- defer until the first Write creates {debate_path} in debating.plugins/base/skills/artifact-templates/SKILL.md.socratic-duel and Artifact = debate-artifact.md.plugins/base/skills/artifact-templates/.participant_count is fewer than 2, transition to waiting_for_participant; otherwise transition to debating.waiting_for_participant
participant_waiting with --unit participant:{participant_id} and bounded wait guidance.rp1 agent-tools socratic-duel status --duel-id "{duel_id}" only within bounded wait guidance, using non-zero sleeps between attempts.debating.status alone. First run rp1 agent-tools socratic-duel claim-lock --duel-id "{duel_id}" --participant-id "{participant_id}" --for-timeout.--for-timeout may acquire a lease after bounded waiting even if the second participant never joined, but it still refuses when a peer owns an unexpired lock.lease_token, lease_expires_at, and participant_count, then immediately re-run rp1 agent-tools socratic-duel status --duel-id "{duel_id}".status shows participant_count is 2 or more, do not write a TIMEOUT conclusion; transition to debating while holding the lease and continue the duel using the existing lease_token.status still shows participant_count fewer than 2, transition to closing, create or append the debate artifact conclusion with TIMEOUT while holding that lease, then run release-lock --close --outcome TIMEOUT.participant_waiting with the returned wait guidance and continue bounded waiting; do not emit terminal completion.debating
rp1 agent-tools socratic-duel claim-lock --duel-id "{duel_id}" --participant-id "{participant_id}".--for-timeout only from the bounded timeout path. Do not use it for ordinary turn acquisition.participant_waiting with --step waiting_for_participant, then transition to waiting_for_participant.lease_token and lease_expires_at; emit lock_acquired.lease_token in status; only a successful claim-lock or refresh-lock result can provide a usable token.refresh-lock before the lease approaches expiry.{TARGET_PATH} for evidence after acquiring the lock.{debate_path} if it exists. If missing, create it from the loaded debate-artifact.md template while holding the lease, then emit artifact_registered exactly once.INVALIDATED.MAX_TURNS.topic, revise before accepting it; do not append off-topic turns.{debate_path}. Never write debate content to {TARGET_PATH}.artifact_updated with --unit turn:{turn_number} for turn writes. Emit btw_update if candidate convergence is true and no terminal outcome exists.release-lock without --close, emit lock_released, and remain available for bounded later polling.closing.closing
closing only while holding the active lease_token for terminal artifact writes.{debate_path} while holding the lease. For TIMEOUT, append no turn and update only the conclusion metadata/body.rp1 agent-tools socratic-duel release-lock --duel-id "{duel_id}" --participant-id "{participant_id}" --lease-token "{lease_token}" --close --outcome "{terminal_outcome}".closed:false, do not emit terminal completion; re-run status, follow the returned next_step, and continue bounded coordination.lock_released with closed:true.artifact_updated with --unit conclusion:{terminal_outcome}.INVALIDATED, transition to invalidated; otherwise transition to completed.completed
--close-run.completed for ACCEPTED_CONSENSUS, DISSENT, MAX_TURNS, and TIMEOUT; keep the domain outcome in event data.invalidated
--close-run.failed, outcome INVALIDATED, and a concrete message with the invalidation reason.§TURN_MARKDOWN
Each accepted turn MUST include these headings:
---
## Turn {N} — {Participant} ({Harness} / {Model}) — {STANCE}
**Position**
...
**Counterpoints**
- Addresses: Turn {M} or source section
Claim: ...
Support:
- ...
**Agreements**
- ...
**Novel Argument**
...
Support:
- ...
**Unresolved Items**
- ... (blocking|non-blocking)
**Stance Revision Support**
- ...
§TURN_RULES
STANCE MUST be one of OPEN_TO_DEBATE, CONVERGING, ACCEPTING_CONSENSUS, DISSENTING, REVISING.Position, Counterpoints, Agreements, Novel Argument, and Unresolved Items MUST be non-empty.Principle: ....{TARGET_PATH} with a heading, line, or quoted excerpt.topic; off-topic drafts must be revised before append.Stance Revision Support.ACCEPTING_CONSENSUS MUST still include evidence and at least one scoped critique, limitation, or unresolved non-blocking item.§OUTCOMES
| Outcome | Use when |
|---------|----------|
| ACCEPTED_CONSENSUS | Latest turns from both participants explicitly accept consensus with adequate support and no blocking unresolved items. |
| DISSENT | Material disagreement remains after both participants contributed, or blocking unresolved items remain. |
| MAX_TURNS | Turn 6 is accepted without consensus or dissent. |
| TIMEOUT | Bounded waiting expires without valid continuation. |
| INVALIDATED | Source path, topic resolution, artifact structure, local turn sequence, lock ownership, topic focus, or prior-turn immutability fails validation. |
§DONT
rp1 agent-tools socratic-duel to parse, render, validate, or update Markdown.TIMEOUT after a timeout claim until a post-claim status re-check still shows fewer than 2 participants./rp1-dev:* commands or agents.tools
Plan and execute splitting a large PR or branch into a reviewable stacked PR sequence.
documentation
Ask about rp1 capabilities, discover skills, and get workflow guidance.
tools
Generate an evidence-grounded markdown walkthrough for a pull request.
testing
Intent-aware map-reduce PR review with CI/CD support, confidence gating, and intelligent comment deduplication.