003 escalate halt resolve resume
003: ESCALATE as halt → resolve → resume¶
- Status: Accepted
- Context: When the validator quorum splits without blockers (e.g., 1 pass, 1 warn under unanimous), the engine needs a mechanism to request human judgment. A simple block would not distinguish this case from a hard-stop blocker, and the orchestrator needs structured information to decide.
- Decision: ESCALATE populates
pending_disagreementon theLoopState(loop.py:352,484) with phase, policy, validator results, and policy decision. The CLI emits a structured JSON payload (halt_type="escalated") including per-validator justifications. The orchestrator (human or automated) reads the payload and callssnodo resolve <session_id> <task_id> --decision proceed|halt. The resolution is stored in the session checkpoint'sdecisionsdict. On resume, the governance node checks for a resolution: ifproceed,resolution_overrideis set and validation is skipped; ifhalt, the task is blocked. - Consequences: ESCALATE is a structured workflow, not a generic block. The resolution is single-use (consumed after governance reads it). The structured halt payload mirrors the same envelope for both ESCALATE and blocker halts, with
halt_typeas a discriminator. Thesnodo resolveCLI command writes directly to the session decisions store. - Alternatives considered: Auto-retry with different thresholds — rejected; human judgment is the orchestrator's decision, not the engine's. Block without structured data — rejected; the orchestrator needs validator-level justifications to decide. Always proceed on warn — rejected; contradicts INV3 semantics.
- Evidence: Audit log entry 54 (2025-05-27, Task 7.10), commit
f7f10a27;loop.py:342-374,470-502,run_cmd.py:542-585.