{"type":"meta","schema":"session-state/v1","slug":"runplan-dep-provisioning","topic":"deterministic dependency provisioning for per-task worktrees in bin/runplan (src/runner.js) — lockfile-keyed immutable cache + CoW materialize","created":"2026-07-04","exec_mode":"ship","scheduler":"sequential","land_mode":"merge-to-main","base_branch":"main","gate0_mode":"strict","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 — 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":"give per-task worktrees deterministic dependency provisioning so gate0 strict stops failing on environmental missing-node_modules reds, via a lockfile-keyed immutable cache + copy-on-write materialization that installs once per unique lockfile and reuses everywhere"}
{"type":"methodology","text":"contract-level plan per [[plan]] skill — pin seams (provision-deps.sh CLI surface, cache key, runner.js wiring point, distinct dep-provision-failed error) not bodies; implementer reads src/runner.js + lib/gates.sh + lib/resolve-seat.sh directly. Provisioning is deterministic/non-LLM → lives in lib/provision-deps.sh invoked via runCli, mirroring gate0. NEVER a seat."}
{"type":"intent","text":"builds on the landed worktree-isolation topology (per-task worktree at repoRoot/tmp/wt-<slug>--<taskId>); provisioning runs BEFORE the coder (not just the gate) so the coder can verify its own work, replacing the old engine's non-deterministic agent-installs-deps-itself behavior"}
{"type":"anchor","path":"docs/specs/2026-07-02-runplan-worktree-isolation-design.md","what":"spec — § Dependency provisioning is source of truth for design+rationale"}
{"type":"anchor","path":"docs/plans/2026-07-04-runplan-dep-provisioning.md","what":"plan — pinned per-task contracts (### Task N)"}
{"type":"task","id":"w1.t1","wave":1,"phase":1,"seat":"coder","tier":"medium","desc":"lib/provision-deps.sh: toolchain detection (corepack packageManager -> lockfile precedence) + CLI contract skeleton (detect/provision, exit 17 = dep-provision-failed)","status":"PENDING","deps":[],"requires_decision":null,"files":["lib/provision-deps.sh"],"blocker":null}
{"type":"task","id":"w2.t1","wave":2,"phase":1,"seat":"coder","tier":"medium","desc":"cache key (sha256 pmId+node+arch+lockfile) + atomic populate (flock, temp+rename commit, frozen offline install per pm, chmod read-only) under repoRoot/.runplan-cache/deps/","status":"PENDING","deps":["w1.t1"],"requires_decision":null,"files":["lib/provision-deps.sh"],"blocker":"waiting on w1.t1"}
{"type":"task","id":"w3.t1","wave":3,"phase":1,"seat":"coder","tier":"medium","desc":"materialize into worktree (reflink->hardlink->copy probe, memoized) + pnpm/yarn-berry native-store delegation (no custom cache, must not assume node_modules exists)","status":"PENDING","deps":["w2.t1"],"requires_decision":null,"files":["lib/provision-deps.sh"],"blocker":"waiting on w2.t1"}
{"type":"task","id":"w4.t1","wave":4,"phase":1,"seat":"coder","tier":"medium","desc":"wire provisionDeps into src/runner.js runTask after ensureTaskWorktree, before coder dispatch; provision intWt too; distinct dep-provision-failed throw (never conflated with gate-not-green)","status":"PENDING","deps":["w3.t1"],"requires_decision":null,"files":["src/runner.js"],"blocker":"waiting on w3.t1"}
{"type":"task","id":"w5.t1","wave":5,"phase":1,"seat":"coder","tier":"medium","desc":"cache GC (LRU by mtime keep-N AND byte-cap, never evict live-worktree key, sweep orphan *.tmp.*) + .gitignore .runplan-cache/","status":"PENDING","deps":["w4.t1"],"requires_decision":null,"files":["lib/provision-deps.sh","src/runner.js",".gitignore"],"blocker":"waiting on w4.t1"}
{"type":"task","id":"w6.t1","wave":6,"phase":1,"seat":"coder","tier":"medium","desc":"extend test/runner-integration.sh: green-with-no-manual-install, install-once-per-key, distinct-entry-on-lock-change, dep-provision-failed-not-gate-red, real-node_modules-unchanged (no leak)","status":"PENDING","deps":["w5.t1"],"requires_decision":null,"files":["test/runner-integration.sh"],"blocker":"waiting on w5.t1"}
