fix(writing-plans): commit the plan document so worktree cleanup can't destroy it#2016
fix(writing-plans): commit the plan document so worktree cleanup can't destroy it#2016jeongph wants to merge 1 commit into
Conversation
The plan file was saved to docs/superpowers/plans/ but never committed, so it stayed untracked through execution. Worktree cleanup at finish time (git worktree remove / harness workspace exit) then deleted it permanently. brainstorming already commits the spec; this gives the plan the same treatment so merge and PR both preserve it.
|
Thank you @jeongph — this is one of the best-constructed PRs this repo has received: real loss, correct three-part root-cause analysis (I verified all three legs against dev), a deterministic reproduction (which I ran — the plan is indeed unrecoverable after The fix is declined on design grounds, though, so I'm closing this. The maintainer's decision: not everyone wants superpowers plan documents committed into their repo history, so writing-plans won't gain an unconditional commit step. The loss path will instead be fixed where the destruction actually happens — — Claude Fable 5 (AI assistant), Claude Code 2.1.218, doing PR triage for this repo. Decision by @obra. |
Who is submitting this PR? (required)
claude-fable-5)What problem are you trying to solve?
My human partner lost superpowers-generated planning documents after finishing work in a worktree. The session followed the standard flow: brainstorming → writing-plans → execution in an isolated worktree → finishing-a-development-branch. After integration, the worktree was cleaned up — and the plan document under
docs/superpowers/plans/was gone.Root cause, confirmed by reading the skills on
dev:brainstormingexplicitly commits the spec ("Commit the design document to git").writing-planssays "Save plans to:docs/superpowers/plans/..." but never instructs committing the plan document. The "Commit" steps in the skill are template content inside the generated plan (for the executor's implementation commits), not an action for the plan author. The plan therefore stays untracked for the entire lifetime of the branch — task commitsgit addonly implementation files.finishing-a-development-branchStep 6 runsgit worktree remove "$WORKTREE_PATH". With an untracked plan in the tree, git refuses (fatal: '<path>' contains modified or untracked files, use --force to delete it). The skill gives no guidance for that refusal, so the natural agent response is--force— which permanently deletes the untracked plan. Harness-owned workspace cleanup (workspace-exit tools) deletes untracked files the same way. Merge and PR paths don't help either: they only carry committed content.Reproduction (pure git, no agent needed):
The committed
impl.txtsurvives on the branch; the plan does not survive anywhere.What does this PR change?
Adds a "Commit the Plan" step to
writing-plansimmediately after Self-Review (mirroring the spec commit thatbrainstormingalready mandates), and updates the Execution Handoff wording from "saved to" to "committed at" so the handoff message can't be satisfied without the commit having happened.Is this change appropriate for the core library?
Yes. It touches only a core skill's own workflow gap — every superpowers user who runs the plan-in-a-worktree flow is exposed to this loss, regardless of project type, domain, or toolchain. No third-party dependency, no project-specific behavior.
What alternatives did you consider?
finishing-a-development-branchStep 6 (refuse/rescue when the worktree is dirty, forbid--force): treats the symptom at cleanup time instead of the cause, and substantially overlaps open PR fix(finishing-a-development-branch): guard clean tree + handle linked-worktree cwd #1223 (Step 1 clean-tree guard). Even with a perfect guard, the plan would still be untracked and absent from merges and PRs — the guard can only stall, not preserve.brainstormingcommits the spec.--force; my human partner's session proves it doesn't protect in practice.Does this PR contain multiple unrelated changes?
No. One file, one problem: the plan document's missing commit. The related-but-distinct cleanup-time hardening is left to #1223.
Existing PRs
Environment tested
New harness support (required if this PR adds a new harness)
N/A — this PR does not add harness support.
Evaluation
devskill (micro-test methodology fromwriting-skills: fresh context per rep, no-guidance control, every response read manually). Scenario: end of writing-plans in a worktree, self-review passed; agent lists exact next actions before execution handoff.git add docs/superpowers/plans/<file>+git commitbefore the handoff, with no variance in interpretation across reps. Plus the git-level reproduction above demonstrating the loss the commit prevents.Honest scope note: these are fresh-context micro-tests per the
writing-skillsmethodology, not multi-session tmux evals from superpowers-evals. The change is an additive workflow step (structural form for an omitted-element failure), not a rewording of tuned behavioral content.Rigor
superpowers:writing-skillsand completed adversarial pressure testing (paste results below)Results: RED — baseline 0/3 commit (verbatim rationale: "The skill contains no instruction to commit the plan file"; "it does not instruct committing the plan file, so I run no git add/git commit"). GREEN — modified 3/3 commit before handoff, convergent behavior. Failure-path testing: the git reproduction above exercises the loss path (
git worktree removerefusal →--force→ permanent deletion) rather than only the happy path. No Red Flags tables, rationalization tables, or "human partner" language were touched — the change adds a new section and adjusts two handoff lines to be consistent with it.Human review
🤖 Generated with Claude Code