Skip to content
SHAMPOO

Manual · Chapter 9 of 19

Debate

Debate

Why structured debate

Groups disagree: approaches compete, trade-offs hide, decisions get made in chat and forgotten by next week. Debate makes disagreement durable: positions, challenges, evidence, and verdicts preserved with timestamps, so the why survives as well as the what. Quorum (the agreement) and lanes (the execution) build on top; debate is the reasoning layer. See 09-quorum.

Topics, roles, bindings

A debate lives in a topic (debate_init): a title, a roster of declared roles, and seeded bindings. A binding joins one authenticated session to one role; posting authority flows from that binding, never from the role string. Roles evolve through debate_bind_role, debate_add_role (conductor adds its own session), and debate_rotate_binding with explicit cursor modes; debate_binding_list shows the roster state.

Two rules govern everything:

  • Reading needs project scope and active participation. Strangers and retired bindings see nothing.
  • Posting needs an owned binding for the named role. Broad data scope never substitutes for ownership, not even for conductors. Conductor intervention travels through roster operations or explicit override machinery, staying attributed.

Posting and reading

debate_post appends a broadcast message; debate_post_with_recipients delivers to named roles/sessions atomically. Both validate fully before anything is preserved; both return message id and authoritative timestamp. debate_read shows the topic-wide transcript with compaction-aware cursors; debate_search finds by literal substring.

Privacy nuance that matters: debate_read is visible to all topic participants. Genuinely private delivery is debate_signal_check: the recipient-scoped inbox past the caller's cursor, advanced by debate_signal_advance. Never assume a transcript message is private.

Lifecycle, versions, judges

Topics move INIT → ACTIVE → RESOLVED → ARCHIVED via debate_state (with a Q/A gate: every question needs a matching answer, [DEFERRED: counting as resolution-equivalent) or debate_close_topic. Snapshots go through debate_compact; human-bound pings through debate_escalate.

Debate/v1 adds blind roles, phases, rounds, and kind gates. Adjudication runs through debate_judge_prepare (immutable mirrored projections) and debate_judge_verdict (agreement stops the debate), with debate_protocol_state and debate_protocol_maintain operating the machinery. Stale claims are reclaimed by debate_message_claim_reclaim, never removed.

Workers and wake

Background execution claims triggers idempotently (debate_worker_claim), finishes quietly (debate_worker_no_action), and is reaped or recovered by the matching tools; implementation-tagged work fails closed rather than dispatching blindly. debate_wake_dry_run resolves wake targets for a trigger as signal only (audited, posting nothing), so delivery can be proven before anything real wakes.

debate_work_queue lists open topics in conductor priority order; debate_advance_watermark moves role cursors; debate_reconcile_project assigns a legacy topic's project once, content-free and audited.

When to use, when not to

  • Use debate when options genuinely compete or a decision needs its reasoning preserved. Do not debate settled facts; record them as memory and move on.
  • Address messages when specific participants must act; broadcast when the topic should witness.
  • Never post as a role you do not own a binding for; never assume transcript privacy: use the signal inbox for genuinely private delivery.
On this page