type: meta

slug: runplan-worktree-isolation

topic: per-task git worktree+branch isolation for bin/runplan (src/runner.js)

exec_mode: ship

scheduler: sequential

land_mode: merge-to-main

base_branch: main

status_enum: BLOCKED PENDING WORKING WRITTEN REVIEWED COMMITTED

truth_rule: this file is ground truth for INTENT (goals/directions/task list); 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 (the point is re-injecting intent into the main thread; a context-mode call keeps bytes OUT and silently kills the feature)

refresh_what: meta + every goal/methodology/intent/direction record + all WORKING and BLOCKED tasks (skip COMMITTED lines)

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' (if you know it, do it)

w1.t1: north

w2.t1: north

w3.t1: north

w4.t1: north

w5.t1: cursor

w6.t1: cursor


type: goal

text: give src/runner.js (bin/runplan's engine) the same per-task worktree+branch isolation the Workflow controller (~/.claude/workflows/run-plan.js) already has, closing the active same-wave concurrency race and making the documented ship.sh land step real


type: methodology

text: contract-level plan per [[plan]] skill — pin seams (worktree/branch naming, journal ordering, gate0 arg split) not bodies; implementer (ship subagents) writes bodies by reading src/runner.js directly


type: intent

text: bin/runplan is the headless/cron-capable sibling of the Workflow-controller engine; it must not corrupt the live repo tree when tasks in a wave run concurrently (runPool already dispatches up to 8 concurrent same-wave tasks against a single shared worktree today)


type: direction

verbatim: has no worktree isolation at all. - well its maybe time to /brainstorm it if its a good idea to have it


verbatim: We should have no grok adapter. it should run only via cursor adapter together as a hardcoded fallback to cursor-agent.


type: deferred

text: actually dogfooding bin/runplan end-to-end against harness-tier-backlog (or any real plan) on main

reason: blocked on this worktree-isolation implementation landing first — running the unisolated engine against a live tree was explicitly superseded by the user's redirect to /brainstorm


text: 3 pre-existing uncommitted infra fixes (wrappers/codex.sh --effort flag, run-tests.sh node_modules glob, presets/cursor.json grok-fallback removal + adapters.json models schema gap) plus new Makefile

reason: sitting uncommitted in the working tree; no instruction yet on when to commit — commits only happen when explicitly asked per user's global rules


type: task

desc: worktree/branch naming helpers + serialization mutex

status: COMMITTED


desc: integration worktree lifecycle wired into run()

blocker: waiting on w1.t1


desc: task worktree lease + taskBase retargeting

blocker: waiting on w2.t1


desc: retarget implement/gate/review/commit to task worktree

blocker: waiting on w3.t1


desc: merge-into-integration + resume ladder

blocker: waiting on w4.t1


desc: rewrite runner-integration.sh for new topology, add conflict + concurrency cases

blocker: waiting on w5.t1


verbatim: i dont want it to run with dyn-wf. is it running with dyn-wf? First, stop.


verbatim: i want you to dismantle the dyn-wf that keeps running. we no longer need it. currently, run the plan with run-plan-codex.js , if you cant dogfood on the new mega runplan harness


note: Fixed ~/.claude/workflows/lib/promptbuilder.sh (shared global infra, not repo-local) to embed the plan.md's exact '### Task N' pinned-contract section into the codex implement brief, matched to the JSONL task by wave-number positional correspondence via extract_pinned_contract(). Previously it only pointed to the spec path as a note, never embedded content, which let codex invent its own naming (branch prefix 'runplan/' instead of the pinned 'plan/'). Verified fixed: manual promptbuilder.sh run showed correct contract embedding, and the second run's w1.t1 commit matched the pinned contract exactly.


note: All 6 task lines in this file currently read status:COMMITTED but this is STALE, not git-true — per truth_rule, git is ground truth. As of 2026-07-02 there is NO plan/runplan-worktree-isolation branch and NO worktree for this slug in `git worktree list` / `git branch -a`. The only full run that hit all 6 waves green shipped code violating the pinned contract (wrong branch-naming scheme) and was discarded per user's AskUserQuestion answer 'Redo via run-plan-codex.js with fixed prompt'. A redo of w1.t1 alone was committed then also discarded (main-tree contamination from a north phantom-write, discarded via `git checkout -- src/runner.js` per user's 'Yes, discard' answer). Net: reconcile from git before trusting any status in this file — real state is effectively 0/6 landed.


note: DynWF Workflow-controller run for this plan was abandoned per user instruction ('dismantle the dyn-wf... run with run-plan-codex.js'). Stamp files ~/.claude/workflows/.run/runplan-worktree-isolation.owner and .runid were deleted to prevent auto-resume of that dead run. Execution now goes exclusively via `node ~/.claude/workflows/run-plan-codex.js --slug runplan-worktree-isolation --repo /home/user/Projects/mega-plan-harness` (foreground only — the bg-gate hook blocks agent-initiated background dispatch; only the user pressing Ctrl+B approves backgrounding).


note: Session ended mid-diagnosis of an apparent disk-full (ENOSPC) error blocking Bash/Write tool use. Root cause found before cutoff: NOT byte-space (76G free on /, 23G free on /tmp) but tmpfs INODE exhaustion — /tmp mounted with nr_inodes=1048576, was at 94% inode usage (978,656 used). Was mid-way through `for d in /tmp/*/; do find "$d" -xdev | wc -l; done` to find the inode hog (candidates: many stale /tmp/wt-<slug>-<taskId> worktree dirs from other repos' concurrent run-plan-codex.js runs, each ~101 inodes) when the diagnostic command itself was killed (exit code 137) — this is the exact point the session ended. NOT yet confirmed whether inode exhaustion actually caused the earlier 'codex returned ok but produced NO changes' implement failure on w1.t1 (strong hypothesis only, never proven). As of this recovery pass (2026-07-02, same host): /tmp inode usage is now healthy again (27% used, 4194304 total inodes — the limit itself appears larger now, or other sessions freed space) — the blocker looks transient/resolved but was NOT verified as the true cause of the implement failure.


note: Separate, deferred thread from earlier in this session: harness-tier-backlog plan (tier taxonomy rename + tier-downgrade backlog/triage feature). Git-confirmed real progress: 2/16 tasks committed (t1, t2 merged into plan/harness-tier-backlog, worktree .wt-harness-tier-backlog-int at 7e4be8c), t3-t15 still PENDING. Per last compaction summary: t3's target (tier renaming in presets/codex.json) is already moot against current main (presets/codex.json has no tier fields at all currently) — plan is stale and needs re-scoping or abandonment. Flagged to user once, no decision made, not re-raised since. Not the active thread this session — runplan-worktree-isolation is.


type: checkpoint

text: Session ended (context/tool exhaustion, not user-directed stop) immediately after the exit-137 kill of the inode-hog diagnostic command. No response was given to the user's last message ('let me know what you mean, there is a lot of free space. something else is wrong there') beyond the diagnostics already run. Next agent should resume the inode-usage investigation directly (re-run a per-directory find/wc count under /tmp, redirecting to a file to avoid truncation) since /tmp now looks healthy (27% inodes) but the true root cause of the codex 'no changes' failure was never confirmed either way.