Left undone deliberately by #260 and stated in PR #285's "What This Does NOT Do".
The gap
#260 made a server refusal fail the spawn instead of being swallowed into Tower's log. The spawn now throws SessionStartFailedError and the operator sees it.
The worktree is already on disk at that point, and no builder row is written, because persistSpawnedBuilder runs in the caller and never gets there. So the worktree exists with nothing in global.db keyed to it.
afx cleanup takes a project, an issue, or a task id, and resolves the worktree from the builder row. With no row there is nothing to name.
Recoverable, but not discoverably
cleanup.ts has an orphan path: findOrphanWorktrees scans the builders directory for directories with no live builder row. So the worktree can be removed. Nothing tells the operator that, and SessionStartFailedError says nothing about the directory it left behind.
This is how the workspace accumulates the state #275 is about: 12 worktrees holding 185 MB that nothing reclaimed.
What would close this
- Name it in the error. One sentence: the worktree at
<path> is orphaned, afx cleanup removes it. The server's own refusal message already closes its loop this way.
- Or remove the worktree as part of failing the spawn, so a failed spawn leaves nothing behind. That is the stronger fix and needs care: a worktree with work in it must never be removed, and a spawn that failed at session start has none.
Related
Left undone deliberately by #260 and stated in PR #285's "What This Does NOT Do".
The gap
#260 made a server refusal fail the spawn instead of being swallowed into Tower's log. The spawn now throws
SessionStartFailedErrorand the operator sees it.The worktree is already on disk at that point, and no builder row is written, because
persistSpawnedBuilderruns in the caller and never gets there. So the worktree exists with nothing inglobal.dbkeyed to it.afx cleanuptakes a project, an issue, or a task id, and resolves the worktree from the builder row. With no row there is nothing to name.Recoverable, but not discoverably
cleanup.tshas an orphan path:findOrphanWorktreesscans the builders directory for directories with no live builder row. So the worktree can be removed. Nothing tells the operator that, andSessionStartFailedErrorsays nothing about the directory it left behind.This is how the workspace accumulates the state #275 is about: 12 worktrees holding 185 MB that nothing reclaimed.
What would close this
<path>is orphaned,afx cleanupremoves it. The server's own refusal message already closes its loop this way.Related