T-7NTU-task-close-out-force-teardown-flag
Status: closed/done · Impact: low · Complexity: small
Auto-generated from a /sdlc:task-work post-mortem. Review and
promote to open/ready before picking up.
When a task file is status: closed/done but its worktree and
feat branch were never torn down, /sdlc:task-close-out emits
ALREADY-CLOSED and exits without doing teardown — by design,
orphan recovery belongs to /sdlc:project-cleanup. But the
ALREADY-CLOSED early-exit prose doesn’t say that, so the user
is left guessing. The implementer of
T-G834-move-plugin-runtime-state-to-sdlc-dir hit this
during pre-flight and had to fall back to manual
git worktree remove + branch -d. Close the gap by either
extending task-close-out with a --force-teardown flag for
closed-but-orphaned tasks, or by routing the ALREADY-CLOSED
exit through clearer prose that points at /sdlc:project-cleanup.
Verbatim post-mortem evidence:
A leftover worktree from a previously-merged task (
2026-05-19-task-ensure-ready-accepts-in-progress) was discovered during pre-flight. Its task file wasstatus: closed/donebut the worktree + branch had never been torn down./sdlc:task-close-outagainst an already-closed task emitsALREADY-CLOSEDand exits without doing teardown (by design — orphan recovery belongs to/sdlc:project-cleanup). This left manualgit worktree remove + branch -das the only way forward. Suggests: either/sdlc:task-close-outshould accept a--force-teardownflag for closed-but-orphaned tasks, or theALREADY-CLOSEDearly-exit prose should explicitly point at/sdlc:project-cleanup.
plugin/skills/task-close-out/SKILL.md defines the
ALREADY-CLOSED exit but does not, in the user-facing message,
name the recovery skill.
Proposed
Section titled “Proposed”Lowest-friction shape, in order of preference:
- Doc-only: the
ALREADY-CLOSEDexit message names/sdlc:project-cleanupas the next-step skill for orphaned worktrees, with a one-line example invocation. No new flags, no behaviour change. - Flag-based:
task-close-outgrows--force-teardownwhich, when the task is alreadyclosed/done, still tears down the worktree and feat branch. Useful if orphan-cleanup-via-task-close-out is a recurring desire-path, but adds a divergent recovery path fromproject-cleanup.
Strong default is (1) unless evidence shows users prefer finishing the close-out call rather than switching skills.
Approach
Section titled “Approach”- Edit
plugin/skills/task-close-out/SKILL.mdso theALREADY-CLOSEDearly-exit prose (and the matching stdout marker) names/sdlc:project-cleanupas the orphan-recovery path, with a one-line example like/sdlc:project-cleanup --task <basename>. - If implementing the flag variant: extend
plugin/skills/task-close-out/SKILL.md(and anyargparsein the close-out script, if applicable) with--force-teardown, gated such that it only applies when the task file is alreadyclosed/done. - Add a fixture covering the
ALREADY-CLOSED + orphancase so future drift on the message gets caught. - Cross-reference from
plugin/skills/project-cleanup/SKILL.mdso the inverse path (project-cleanup → task-close-out) is discoverable.
Files to touch
Section titled “Files to touch”| Location | Kind | Change |
|---|---|---|
plugin/skills/task-close-out/SKILL.md | modify | adopt the clearer |
plugin/skills/project-cleanup/SKILL.md | modify | cross-reference |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1: When
/sdlc:task-close-outexits withALREADY-CLOSEDagainst a task whose worktree still exists, the message names/sdlc:project-cleanup(with at least the skill slug, ideally an example invocation). - AC-2: If
--force-teardownis implemented, a fixture exercises the closed-but-orphaned case end-to-end and the worktree + feat branch are gone afterwards.
Out of scope
Section titled “Out of scope”- Refactoring
project-cleanup’s orphan-detection logic itself. - Auto-detecting orphans during
task-workstart.
Dependencies
Section titled “Dependencies”- none
Discovery context
Section titled “Discovery context”Spawned by /sdlc:task-work post-mortem of T-G834-move-plugin-runtime-state-to-sdlc-dir on 2026-05-22.
Dedup search (spawn-from-post-mortem)
Section titled “Dedup search (spawn-from-post-mortem)”Bullet: A leftover worktree from a previously-merged task (2026-05-19-task-ensure-ready-accepts-in-progress) was discovered during pre-flight. Its task file was status: closed/done but the worktree + branch had never been torn down. /sdlc:task-close-out against an already-closed task emits ALREADY-CLOSED and exits without doing teardown (by design - orphan recovery belongs to /sdlc:project-cleanup). This left manual git worktree remove + branch -d as the only way forward. Suggests: either /sdlc:task-close-out should accept a —force-teardown flag for closed-but-orphaned tasks, or the ALREADY-CLOSED early-exit prose should explicitly point at /sdlc:project-cleanup. Keywords searched: task-ensure-ready-accepts-in-progress, closed-but-orphaned, previously-merged, project-cleanup, task-close-out, already-closed, force-teardown, discovered Excluded: 2026-05-22-move-plugin-runtime-state-to-sdlc-dir Top candidates (score / status / headline):
- 34 / closed/done / 2026-05-19-extract-task-close-out-skill — Extract task-work Step 11 into /sdlc:task-close-out skill
- 14 / closed/done / 2026-05-20-task-close-out-verifies-pr-on-main — task-close-out verifies merged PR’s mergeCommit is reachable from origin/main
- 13 / closed/done / 2026-05-20-task-close-out-dry-run-flag — Add —dry-run to /sdlc:task-close-out for safe rehearsal
- 10 / open/ready / 2026-05-20-orchestrator-tick-race-fixture — Integration fixture for concurrent orchestrator tick race on task-close-out
- 6 / closed/done / 2026-05-19-add-orchestrate-skill — Add /sdlc:orchestrate skill — one-tick reconcile + dispatch loop Decision: SPAWNED