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.