debate_state
- Category: debate
- Access: write
- Audience: advanced (ordinary users do not normally call this directly)
Purpose
Moves a topic along INIT to ACTIVE to RESOLVED to ARCHIVED, posting a synthetic STATE message and retiring bindings in the same atomic unit. RESOLVED requires every Q to hold a matching A reply.
Arguments
Required: topic_id, role, new_state.
Optional: reason.
-
topic_id: existing debate topic. -
role. Note: Must be a declared role whose binding the caller owns; no star or conductor exception. -
new_state. Note: One of INIT, ACTIVE, RESOLVED, ARCHIVED; only forward lifecycle moves are valid. -
reason. Note: Recorded inside the synthetic STATE message body.
Result
Object with old_state, new_state, ts, blocking_questions, transition_msg_id, body, retired_bindings, and retired_worker_claims. When the Q/A gate blocks, old and new states equal the current state and blocking_questions lists the open questions.
Boundaries
Lifecycle authority comes from the caller's owned binding on the named role. A body starting with [DEFERRED: counts as resolution-equivalent for the gate. A direct kind=STATE post bypasses the Q/A gate (pinned behaviour); this tool never bypasses it.
Lifecycle / side effects
Transition, STATE message, and binding retirement succeed or fail together with an audit/history event. RESOLVED retires active bindings; ARCHIVED retires active plus diagnostic bindings. Nothing is ever physically removed.
Errors
Unknown topic or undeclared role answers with uniform vocabulary. Illegal transitions and open-question blocks are rejected with the blocking list. Unowned roles deny as not-found.
Example
{
"new_state": "RESOLVED",
"reason": "Packaging decision adopted",
"role": "CONDUCTOR",
"topic_id": "<uuid>"
}
Result shape:
{
"blocking_questions": [],
"new_state": "RESOLVED",
"old_state": "ACTIVE",
"transition_msg_id": "<uuid>",
"ts": "<iso-8601>"
}
See also
debate_close_topic, debate_post, debate_read, debate_bind_role, debate_worker_reap.