Clean up a completed custom worktree
If a completed WU’s worktree remains after cleanup, run the recovery command from the primary checkout:
When the WU records an explicit worktree_path and claimed_branch, recovery
uses those exact bindings. A custom suffix or branch name does not require
renaming the worktree or deleting the branch. The default lane/id path is used
only for older records that never recorded a worktree path.
Both worktree and worktree-pr local claim modes use these checks. A
branch-only or branch-pr record does not authorize local-worktree removal.
The recorded path must be confined beneath the configured worktrees directory. Its native registration and its own WU record must agree with the canonical claim. Cleanup checks status, leases, recent activity, local changes, settled branch state and a positively confirmed zero-ahead count. It preserves active, unlanded, mismatched or uncertain targets and honors configured worktree retention. Resolve the reported condition before trying again; there is no new force flag for this recovery.
Successful cleanup promotes memory, makes the native verified quarantine copy, and records the cleanup audit before removing the selected directory and Git registration. It preserves the branch and its history, the canonical WU YAML, and the DONE stamp. Other worktrees remain untouched.
Memory files may be Git-ignored local evidence or tracked project data. Before promotion, Git must confirm every untracked file is ignored in both the source worktree and destination; tracked files do not exempt unignored siblings. Ignored files are mirrored locally only after that check. Tracked memory is merged from the latest integration snapshot and published through the normal push-only transaction; cleanup refuses local-only mode or a rejected publication, leaving the source worktree available for retry. The checked-out main tree is not modified by tracked memory promotion. Archive paths are also resolved against each checkout’s own migration sentinel, so cleanup can safely handle a migrated primary checkout and an unmigrated worktree.
For an already removed recorded worktree, recovery reports a successful no-op only when neither the path nor a registration for its recorded branch remains. A recorded custom worktree with a broken registration refuses for diagnosis. The legacy interrupted-cleanup fallback remains available for older records without a recorded path.
A worktree nested inside another worktree
Section titled “A worktree nested inside another worktree”LumenFlow never creates a worktree inside another worktree. The host git adapter refuses a worktree path that lies at or inside a registered linked worktree, and refuses a relative path when its directory is a subdirectory of a checkout (git would resolve it against that subdirectory). Create worktrees from the primary checkout root, or pass an absolute path.
A nested registration left by an older version cannot be cleared by the claim-binding proof, because its record names the top-level path. Retire it from the primary checkout:
Retire removes a nested worktree only when all of these hold: the WU record on
the freshly fetched delivery branch is done and its done stamp is there; the
recorded worktree path is this registration with the nesting removed; the
worktree is on the WU’s lane branch with a clean tree and a HEAD that is already
on the delivery branch; the delivery remote advertises no claim marker for the
WU; and no live process has the worktree as its working directory (on Linux and macOS the process list is read; on Windows retire renames the directory to a unique sibling and straight back,
and a refused rename (EBUSY, EPERM or EACCES) means a process holds it; any
other failure, or a failed restore, refuses and is reported with both paths). The process check cannot see root, other-user or
container processes, so it reduces accidents without proving absence; the clean
tree and landed-commit checks are what protect your work. Retire also refuses,
for any worktree, while another registered worktree lies inside it, and so does
every other removal path (wu:prune, wu:cleanup, wu:done, wu:recover):
the git adapter itself refuses to remove a worktree that holds another
registered worktree, because the removal would delete that worktree and its
unlanded work. Retire or move the inner worktree first. Anything else
refuses and changes nothing, and a refusal by git never deletes the directory
(wu:recover --action nuke and --action cleanup report the refusal and
keep the directory).
A done WU’s leftover directory that git no longer registers, or reports
prunable (for example a broken admin link after an interrupted wu:done
cleanup), is cleared by the same command, pnpm wu:recover --id WU-XXXX --action retire. It deletes the directory only when its real path is strictly
inside the worktrees root and is not the main checkout, the WU is done with its
stamp on the delivery branch and no claim marker, no worktree is registered
inside it, and no live process uses it. The directory’s .git must be a file
whose gitdir points into this repository’s .git/worktrees/ (a full clone or a
foreign checkout is never deleted), and neither the directory nor any component
under the worktrees root may be a symbolic link or junction. On Windows the
delete never follows a link and a failed delete is audited as partial.
Anything unproven refuses with
RETIRE_LEFTOVER_UNPROVEN and the exact reason, and the lane branch is left
alone. A retire of a nested worktree
appends audit records with the actor and
session: an attempt before the removal and the outcome after it.
wu:prune follows the same rule: its orphan sweep refuses a directory that still
holds a registered worktree, and the tmp-worktree sweep reports git’s refusal
instead of deleting the tree. If a Windows probe could not rename a worktree
back, a <worktree>.wu-probe-* directory remains; retire, wu:prune and the
orphan sweep refuse while one exists and name it. Rename it back by hand.
A registered worktree inside the worktree being removed counts even when its
directory is missing, because that is what a stranded Windows probe leaves (the
inner worktree renamed to <name>.wu-probe-*, still registered, holding
uncommitted work). The scan for stranded probes covers the directory beside
every registered worktree, nested ones included. wu:recover --action cleanup
and the consistency repairs also refuse their repository-wide stale-metadata
prune while a stranded probe, or an unrelated registration with a missing
directory, exists; run wu:prune to clear stale registrations first.