Skip to content

fix(teams): close remaining cleanup gaps for worktrees and session dirs#40

Open
tmustier wants to merge 1 commit intomainfrom
fix/sym-41-worktree-session-cleanup
Open

fix(teams): close remaining cleanup gaps for worktrees and session dirs#40
tmustier wants to merge 1 commit intomainfrom
fix/sym-41-worktree-session-cleanup

Conversation

@tmustier
Copy link
Copy Markdown
Owner

@tmustier tmustier commented Apr 3, 2026

Summary

Closes remaining cleanup gaps for worktrees and session directories (SYM-41 / #9).

PRs #14 and #30 added the core cleanup infrastructure (cleanupWorktrees, gcStaleTeamDirs, session_shutdown handler). This PR closes the remaining gaps:

Changes

1. Standalone git worktree prune on startup (worktree.ts)

  • New pruneStaleWorktreeRefs() function — runs git worktree prune on the working repo
  • Called in session_start to clean up dangling .git/worktrees/ entries from sessions whose team directories were already deleted (crash, manual rm, partial cleanup)
  • Lightweight and safe to run every startup; only removes bookkeeping for worktree dirs that no longer exist

2. Pass repoCwd to startup GC (leader.ts)

  • gcStaleTeamDirs now receives ctx.cwd so cleanupWorktrees can find the repo root even when worktree directories are gone from disk

3. Smarter session_shutdown cleanup (leader.ts)

  • Replaces teamDirHasAnyTasks with teamDirHasActiveTasks — checks for pending/in-progress tasks only
  • Team dirs with only completed tasks are now cleaned up at session end instead of waiting 24h for startup GC
  • Completed tasks have already been reported back to the leader and serve no ongoing purpose

4. Remove hadTeammates guard (leader.ts)

  • session_shutdown now attempts dir cleanup regardless of whether RPC teammates were active
  • Safety checks (no live attach claim, no online workers, no active tasks) are sufficient guards
  • Previously, any session that used RPC teammates left its dir for 24h even when all work was done

5. Pass repoCwd to cleanupTeamDir in shutdown (leader.ts)

  • Ensures proper worktree metadata cleanup even when the team dir's worktree subdirs are being removed

Testing

  • 8 new integration tests in integration-cleanup-test.mts:
    • pruneStaleWorktreeRefs cleans orphaned .git/worktrees/ metadata
    • pruneStaleWorktreeRefs handles non-git directories gracefully
    • gcStaleTeamDirs removes dirs with only completed tasks
  • All 325 smoke tests pass
  • All 56 integration-cleanup tests pass (48 existing + 8 new)
  • Lint + typecheck clean (no new errors)

Resolves #9

Addresses SYM-41 / GitHub #9 — remaining gaps after PRs #14 and #30:

1. Standalone git worktree prune on startup: adds pruneStaleWorktreeRefs()
   called in session_start to clean up dangling .git/worktrees/ entries
   from sessions whose team directories were already deleted (crash,
   manual rm, or partial cleanup). Lightweight and safe to run every time.

2. Pass repoCwd to startup GC: gcStaleTeamDirs now receives ctx.cwd so
   cleanupWorktrees can find the repo root even when worktree dirs are gone.

3. Smarter session_shutdown cleanup: replaces teamDirHasAnyTasks with
   teamDirHasActiveTasks — team dirs with only completed tasks are now
   cleaned up at session end instead of waiting 24h for startup GC.
   Completed tasks have already been reported back and serve no purpose.

4. Removes hadTeammates guard: session_shutdown now attempts dir cleanup
   regardless of whether RPC teammates were active. The safety checks
   (no live attach claim, no online workers, no active tasks) are
   sufficient guards.

5. Passes repoCwd to cleanupTeamDir in session_shutdown for proper
   worktree metadata cleanup.

Tests: 8 new integration tests covering pruneStaleWorktreeRefs (orphan
cleanup, non-git dir) and gcStaleTeamDirs (completed-only tasks are GC'd).
All 325 smoke + 56 integration-cleanup tests pass.
@tmustier tmustier added the symphony Managed by pi-symphony label Apr 3, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 14e3528fe4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +149 to +150
} catch {
// Unreadable task file — skip.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Treat unreadable task JSON as active during shutdown cleanup

teamDirHasActiveTasks now skips task files that fail readFile/JSON.parse, so a team with malformed or partially written task JSON can be misclassified as having no active tasks; in session_shutdown that allows cleanupTeamDir(...) to delete the entire team directory and lose unresolved task data. The previous teamDirHasAnyTasks logic was fail-closed for this case, so this change introduces a new data-loss path when task files are corrupted or in an unexpected format.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

symphony Managed by pi-symphony

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Worktrees and session directories accumulate on disk and are never automatically cleaned up

1 participant