Title#
Persist worktree across phases, cleanup on task completion
Problem#
The per-phase create/destroy worktree lifecycle caused permanent stuck loops when git branch -D failed on a checked-out branch (issue #246). The aggressive pre-cleanup ran destructive git operations before each phase, making recovery impossible.
Task / Link#
Closes #272
Changes#
- Replace
WorktreeService.createWorktree()with idempotentgetOrCreateWorktree(): reuses existing worktree, attaches existing branch, or fresh-creates - Remove aggressive pre-cleanup (
git branch -D,git worktree remove --force) from worktree setup getOrCreateWorktree()runsgit fetch originon reuse to stay current- Remove per-phase
cleanupWorktree()fromPhaseRouterService.executePhase()finally block - Add terminal-state cleanup:
WorktreeService.cleanupWorktree()called inInternalAdapterService.advanceAndEnqueue()when task reachescomplete - Import
WorktreeModuleinInternalAdapterModulefor DI
Notes#
- Cleanup is wrapped in try/catch — failure is logged but does not fail the pipeline
- Concurrent phase safety maintained by the queue's serial-per-task guarantee
Testing#
- Unit tests updated for all three
getOrCreateWorktree()paths: worktree-exists-reuse, branch-exists-no-worktree, fresh-create - New unit tests in
InternalAdapterService: cleanup called on terminal state, NOT called on phase advancement - Phase-router tests updated: assert
cleanupWorktreeis NOT called after phase execution - All 696 unit tests pass; lint clean (no new errors)