{"type":"meta","schema":"session-state/v1","slug":"preflight-decision-gate","topic":"Pre-flight human-decision gate for run-plan workflows","created":"2026-06-27","exec_mode":"direct","scheduler":"dag-parallel","base_branch":"master","status_enum":["BLOCKED","PENDING","WORKING","WRITTEN","REVIEWED","COMMITTED"],"truth_rule":"this file is ground truth for INTENT; git is ground truth for DONE-NESS — reconcile statuses against git, never trust a COMMITTED line with no commit","refresh_how":"native Read of THIS file — NEVER ctx_execute/ctx_search","refresh_what":"meta + every goal/methodology/intent/direction record + all WORKING and BLOCKED tasks","refresh_when":["wave/phase boundary","any task status change","after a compaction system-reminder","before calling advisor"],"update_rule":"on status change, rewrite that task's single line in place; append new tasks/session_memory as new lines","report_rule":"at session end emit brief: done / blocked / deferred / canceled — NO next action"}
{"type":"goal","text":"Surface every foreseeable human decision in a run-plan BEFORE the Workflow launches, as one fully-informed decision sheet; record answers as durable pre-authorizations in the plan JSONL; then run end-to-end with no human blocker in the middle. Engine fail-closed HALTs on any unresolved decision regardless of launch path."}
{"type":"methodology","text":"Be critical/robust, best-practice not hacky. No stubs in deliverable code. Doc edits to agent-facing skills MUST follow agent-doc-authoring register. Engine checks: tests for every fail-closed branch + negative proof (run-plan-det-extraction discipline). No drift: ONE shared decisionResolved(t) predicate used by both schedulers."}
{"type":"intent","text":"run-plan.js is a Workflow controller and CANNOT call AskUserQuestion (main-thread only) — that is WHY it HALTs mid-run on user-gated tasks. Move all human decisions to a main-thread pre-flight gate in the launch path so the Workflow runs uninterrupted on pre-authorizations."}
{"type":"direction","verbatim":"i want to give user fully informed infomation to make a dfesition before workflow is run , so we have no human blockers or questions in the middle"}
{"type":"direction","verbatim":"Major Architectural changes, Policy changes\\ambiguity, anything that until now would require a human in the loop (per project's definition, different projects have different rules)"}
{"type":"direction","verbatim":"you can just create primitives and reuse the primitives for the different versions, to not break any and avoid the drift"}
{"type":"deferred","text":"Removing failure-driven correctness halts (merge conflict, integration gate red, MAX_FIX/MAX_REVIEW)","reason":"Out of scope — a decision sheet cannot pre-answer 'the code will fail to compile when combined'. Only foreseeable DECISIONS are pre-authorized; correctness failures still HALT and need a human."}
{"type":"anchor","path":"docs/specs/2026-06-27-preflight-decision-gate-design.md","what":"spec"}
{"type":"anchor","path":"workflows/run-plan.js","what":"engine — add decisionResolved(t) predicate + load validation (trust boundary, C4)"}
{"type":"anchor","path":"skills/run-plan/SKILL.md","what":"launch path — insert main-thread pre-flight decision gate (C3)"}
{"type":"anchor","path":"skills/brainstorm/SKILL.md","what":"session-state/v1 schema — enriched gated record + task.requires_decision + binds_meta (C1)"}
{"type":"anchor","path":"skills/plan/SKILL.md","what":"planner decision-enumeration pass (C2)"}
{"type":"anchor","path":"docs/plans/2026-06-27-preflight-decision-gate.md","what":"plan"}
{"type":"task","id":"w1.t1","wave":1,"phase":1,"desc":"Engine enforcement + tests: extend S_MANIFEST (gated array + task.requires_decision survive additionalProperties:false), P.load parses gated lines, add shared decisionGate(t) + load-time validation (dup id / answer∉options / dangling ref / OPEN binds_meta), call decisionGate before lease in both schedulers, inject resolved answer into P.implement/implementNorth. Extend test-run-plan-scheduler.mjs with scenario.gated + decision cases. Acceptance: node test-run-plan-scheduler.mjs → 0 failed.","status":"COMMITTED","deps":[],"files":["workflows/run-plan.js","workflows/lib/test-run-plan-scheduler.mjs"],"blocker":null}
{"type":"task","id":"w1.t2","wave":1,"phase":1,"desc":"brainstorm/SKILL.md session-state/v1 schema: enriched gated record (status/answer/options/category/blast_radius/source/binds_meta) + task.requires_decision + unified-model note (no new decision type); point to plan's enumeration rule. agent-doc-authoring register.","status":"COMMITTED","deps":[],"files":["skills/brainstorm/SKILL.md"],"blocker":null}
{"type":"task","id":"w1.t3","wave":1,"phase":1,"desc":"plan/SKILL.md decision-enumeration pass: per-task gated+requires_decision, run-level gated.binds_meta, per-project policy source (## Pre-flight gate policy in CLAUDE.md else baseline categories), fork boundary (param-inject vs plan-time re-plan, no branch-skip). Canonical source; agent-doc-authoring register.","status":"COMMITTED","deps":[],"files":["skills/plan/SKILL.md"],"blocker":null}
{"type":"task","id":"w1.t4","wave":1,"phase":1,"desc":"run-plan/SKILL.md main-thread pre-flight gate step (before Workflow launch): collect OPEN gated, graph-hash-gated scan backstop, consolidated AskUserQuestion sheet, write-back RESOLVED + binds_meta→meta field, stamp meta.preflight.task_graph_hash. Honesty note: sheet=UX, engine=trust boundary; only foreseeable decisions removed. agent-doc-authoring register.","status":"COMMITTED","deps":[],"files":["skills/run-plan/SKILL.md"],"blocker":null}
{"type":"session_memory","note":"~/.claude repo has NO git remote → exec_mode=direct, local commits only, NO PR. Same constraint as the dag-parallel plan."}
{"type":"session_memory","note":"Unified model: NO new 'decision' record type — enrich existing 'gated' with lifecycle (status OPEN/RESOLVED, answer, options, category, blast_radius). task.requires_decision replaces free-text user-blockers; deps stays task→task only."}
{"type":"session_memory","note":"Two binding kinds: per-task (task.requires_decision → engine HALT per task) and run-level (gated.binds_meta → writes a meta field e.g. base_branch/exec_mode, HALT at load if OPEN). Both surface on the same sheet."}
{"type":"session_memory","note":"CUT (YAGNI): requires_decision_equals, pre-authored dual branches, 'skipped' task status — would force cross-cutting status_enum/CANCELED change for a fork shape no real plan produces. status_enum UNTOUCHED. Forks = param-injection (one task) or plan-time re-plan."}
{"type":"session_memory","note":"Scan backstop gated behind meta.preflight.task_graph_hash — LLM scan is non-deterministic; re-running every launch would break idempotent resume. Re-scan ONLY when graph changes."}
{"type":"session_memory","note":"Per-project policy seam: '## Pre-flight gate policy' section in project CLAUDE.md (additive over baseline categories irreversible|fork|input|policy|architecture). Absent ⇒ baseline floor; irreversible destructive op always gated."}
