{"type": "meta", "schema": "session-state/v1", "slug": "autonomy-p3-daemon", "topic": "P3 \u2014 harnessd daemon A1, decision inbox A5, notifications W9, trust ramp W10, budgets V2, digest V1, queues/windows X1/X4/X6, handoff bundles X11, run reports X12, control-api token auth", "created": "2026-07-08", "exec_mode": "ship", "scheduler": "sequential", "land_mode": "merge-to-main", "base_branch": "main", "gate0_mode": "strict", "depends_on": ["autonomy-p2b-resolver-watchdog"], "status_enum": ["BLOCKED", "PENDING", "WORKING", "WRITTEN", "REVIEWED", "COMMITTED"], "truth_rule": "this file is ground truth for INTENT (goals/task list); git is ground truth for DONE-NESS \u2014 reconcile statuses against git, never trust a COMMITTED line with no commit", "report_rule": "at session end emit brief: done / blocked / deferred / canceled"}
{"type": "goal", "text": "babysitter eliminated: daemon owns launch\u2192monitor\u2192resolve\u2192resume\u2192escalate\u2192report; full chaos suite green end-to-end unattended incl. crash-resume and pre-authorized default decision; soak clean"}
{"type": "anchor", "path": "spec/DAEMON.md", "what": "canonical spec \u2014 state machine, tick loop, sockets, inbox, re-attach, auth, tests"}
{"type": "anchor", "path": "spec/IMPLEMENTER-NOTES.md", "what": "READ FIRST \u2014 library+CLI-first seam; daemon is a scheduler of library calls"}
{"type": "anchor", "path": "docs/plans/2026-07-08-autonomy-p3-daemon.md", "what": "plan \u2014 pinned per-task contracts (### Task N)"}
{"type": "intent", "text": "after this plan lands, W13 dogfooding governs: P4+ (DAG scheduler, lesson loop, message bus, UI, adapters, self-improvement P5.6) are authored as runplan plans and executed BY the harness at autonomy level 1"}
{"type": "gated", "id": "g-protected-whitelist", "status": "RESOLVED", "source": "author", "category": "policy", "needs": "approve engine-src whitelist for this run", "why": "P2b protected-path gate quarantines any task touching engine src/ when the target repo IS the harness; this entire plan modifies engine src/ \u2014 operator must whitelist at preflight per V1 (never at run time)", "options": ["proceed", "abort"], "binds_meta": null, "answer": {"protectedPaths": ["src/"]}, "resolved_by": "user"}
{"type": "gated", "id": "g-notify-channel", "status": "RESOLVED", "source": "author", "category": "input", "needs": "notification channel config: ntfy topic URL + token, or generic webhook URL \u2014 written to ~/.harness/config.json before Task 4 dispatch", "why": "W9 needs a real operator-owned channel; no default exists and inventing one would silently drop escalations", "options": ["ntfy", "webhook"], "binds_meta": null, "answer": "ntfy", "resolved_by": "user"}
{"type": "task", "id": "w1.t1", "wave": 1, "phase": 3, "seat": "coder", "tier": "high", "desc": "daemon core bin/harnessd + src/daemon.js per spec/DAEMON.md: state machine every edge, 8-step idempotent tick loop, stateless I8, re-attach; resolver called as library (plan Task 1)", "status": "PENDING", "deps": [], "requires_decision": "g-protected-whitelist", "files": ["bin/harnessd", "src/daemon.js", "src/daemon.test.js"], "blocker": null}
{"type": "task", "id": "w1.t2", "wave": 1, "phase": 3, "seat": "coder", "tier": "high", "desc": "decision inbox src/inbox.js per spec \u00a7 Decision inbox: payloads verbatim, d-<seq> ids, first-answer-wins 409, default auto-answer only level \u22652, bundle-before-notification (plan Task 2)", "status": "PENDING", "deps": [], "requires_decision": "g-protected-whitelist", "files": ["src/inbox.js", "src/inbox.test.js"], "blocker": null}
{"type": "task", "id": "w2.t1", "wave": 2, "phase": 3, "seat": "coder", "tier": "high", "desc": "daemon control socket verbs + runplan --unattended submit client + runplan answer; foreground mode unchanged; supervisor socket untouched (plan Task 3)", "status": "PENDING", "deps": ["w1.t1", "w1.t2"], "requires_decision": "g-protected-whitelist", "files": ["src/daemon.js", "bin/runplan", "src/runner.js"], "blocker": "waiting on wave 1"}
{"type": "task", "id": "w2.t2", "wave": 2, "phase": 3, "seat": "coder", "tier": "medium", "desc": "notifications src/notify.js per spec: config via resolveConfig, ntfy actions with auth header, notify.failed + retry \u00d73 \u2192 give up, never blocks decisions (plan Task 4)", "status": "PENDING", "deps": [], "requires_decision": "g-protected-whitelist", "files": ["src/notify.js", "src/notify.test.js"], "blocker": null}
{"type": "task", "id": "w3.t1", "wave": 3, "phase": 3, "seat": "coder", "tier": "high", "desc": "control-api token auth per spec auth paragraph: ~/.harness/token 0600, Bearer required, timingSafeEqual, 401, localhost/Tailscale bind only; proxy answer+status (plan Task 5)", "status": "PENDING", "deps": ["w2.t1"], "requires_decision": "g-protected-whitelist", "files": ["src/control-api.js"], "blocker": "waiting on w2.t1"}
{"type": "task", "id": "w3.t2", "wave": 3, "phase": 3, "seat": "coder", "tier": "medium", "desc": "systemd user units (harnessd.service Restart=on-failure, daily timer) + systemd-run scoped agent spawns with setsid/ulimit fallback probed at startup (plan Task 6)", "status": "PENDING", "deps": [], "requires_decision": "g-protected-whitelist", "files": ["systemd/", "bin/harness-init.sh"], "blocker": null}
{"type": "task", "id": "w4.t1", "wave": 4, "phase": 3, "seat": "coder", "tier": "high", "desc": "W10 trust ramp submit gate + V2 budget enforcement in tick (task\u2192budget-exceeded, run\u2192pause+decision) + V1 digest src/digest.js + W5 status cache + W12 backup in timer (plan Task 7)", "status": "PENDING", "deps": ["w1.t1", "w2.t1", "w2.t2", "w3.t1", "w3.t2"], "requires_decision": "g-protected-whitelist", "files": ["src/daemon.js", "src/digest.js"], "blocker": "waiting on wave 3"}
{"type": "task", "id": "w5.t1", "wave": 5, "phase": 3, "seat": "coder", "tier": "high", "desc": "X1 meta-plan dep queue (cycle detection, accept_partial, blocked-on-dep escalation) + X6 run windows (--now override) + X4 maintenance ladder with preemption (plan Task 8)", "status": "PENDING", "deps": ["w4.t1"], "requires_decision": "g-protected-whitelist", "files": ["src/daemon.js"], "blocker": "waiting on w4.t1"}
{"type": "task", "id": "w6.t1", "wave": 6, "phase": 3, "seat": "coder", "tier": "medium", "desc": "X11 escalation handoff bundles (before notification, linked) + X12 run report from the SAME journal reducer, committed with landing (plan Task 9)", "status": "PENDING", "deps": ["w5.t1"], "requires_decision": "g-protected-whitelist", "files": ["src/report.js", "src/daemon.js"], "blocker": "waiting on w5.t1"}
{"type": "task", "id": "w7.t1", "wave": 7, "phase": 3, "seat": "coder", "tier": "medium", "desc": "ungate P3 chaos (daemon-kill re-attach, unattended end-to-end, default decision) + soak N cycles zero orphans \u2014 epic definition of done (plan Task 10)", "status": "PENDING", "deps": ["w6.t1"], "requires_decision": null, "files": ["test/chaos/scenarios/"], "blocker": "waiting on w6.t1"}
