/** * Question escalation (issue #41): the protocol that lets a headless * worker ask the CALLER's user a question. Transport is the prompt - no * harness ships native question conveyance - so hcn prepends a protocol * contract (escalateQuestions true, the default) or the state-the- * assumption instruction (false). The worker's final message then carries * a fenced `hcn-question` block; detection is structured-first (fields * parsed from the block, prose rendered downstream from them). * * Ratified design note (2026-08-19): autonomy and escalateQuestions are * independent flags carving the same substrate by ORIGIN - autonomy = * interrupts the harness raises (permission gates), escalateQuestions = * interrupts the model raises (judgment gaps). The true-mode preamble * must therefore never conflate asking with permission: "you may ask" is * never "you lack permission." Both preambles open with the same marker * so composition is idempotent (a composed prompt is never re-composed). */ /** The shared first line of both preambles - also the idempotence marker * for composeEscalatedPrompt. */ export const QUESTION_PREAMBLE_MARKER = "[hcn question protocol]"; export const ESCALATION_PREAMBLE = `${QUESTION_PREAMBLE_MARKER} You are running headless: no one is watching this session live, but a caller relays answers between turns. This protocol never changes your permissions - asking is not how you obtain permission, and it never removes any permission this run already has. Use the tools you have exactly as granted. If and only if a genuine decision you cannot make defensibly blocks correct progress, ask by ending your turn: emit one fenced code block tagged hcn-question, as the last content of your final message, containing a single JSON object: \`\`\`hcn-question {"question": "", "options": ["