Problem
Worktrees created for PR work currently survive long after the PR is merged or closed. Over time, clean merged worktrees accumulate into hundreds of directories and hundreds of GiB of disk usage.
The 2026-04-29 incident found 215 homeboy@* worktrees using ~592 GiB; removing 208 clean ones freed ~572.7 GiB.
Proposed solution
Teach DMC worktree cleanup to use PR lifecycle state as a first-class cleanup signal.
For each worktree with GitHub metadata or inferable branch/remote context:
- Detect whether the associated PR is merged, closed, open, or missing.
- Mark clean merged/closed worktrees as cleanup candidates.
- Keep dirty or unpushed worktrees protected with explicit reason buckets.
- Prefer cached/bounded GitHub lookups so cleanup remains usable at large workspace sizes.
CLI behavior
wp datamachine-code workspace worktree cleanup --dry-run --format=json should include PR lifecycle reason buckets, for example:
{
"summary": {
"candidates": 42,
"skipped": 8
},
"candidates": [
{
"path": "/Users/chubes/Developer/homeboy@feat-old-thing",
"reason": "pr_merged",
"pr": "https://github.com/Extra-Chill/homeboy/pull/1234",
"estimated_size_bytes": 3221225472
}
]
}
Safety requirements
- Never remove dirty worktrees automatically.
- Never remove worktrees with unpushed commits automatically.
- If PR lookup fails, do not treat that as merged/closed.
- Make
--skip-github still work for local-only cleanup.
- Human output should make it obvious why each worktree is or is not removable.
Acceptance criteria
- Cleanup can identify clean worktrees whose PR is merged.
- Cleanup can identify clean worktrees whose PR is closed/unmerged.
- Dirty/unpushed merged-PR worktrees are skipped with explicit reasons.
- JSON output remains parseable with no mixed progress text.
- GitHub lookups are bounded/cached enough to handle hundreds of worktrees.
Problem
Worktrees created for PR work currently survive long after the PR is merged or closed. Over time, clean merged worktrees accumulate into hundreds of directories and hundreds of GiB of disk usage.
The 2026-04-29 incident found
215homeboy@*worktrees using ~592 GiB; removing208clean ones freed ~572.7 GiB.Proposed solution
Teach DMC worktree cleanup to use PR lifecycle state as a first-class cleanup signal.
For each worktree with GitHub metadata or inferable branch/remote context:
CLI behavior
wp datamachine-code workspace worktree cleanup --dry-run --format=jsonshould include PR lifecycle reason buckets, for example:{ "summary": { "candidates": 42, "skipped": 8 }, "candidates": [ { "path": "/Users/chubes/Developer/homeboy@feat-old-thing", "reason": "pr_merged", "pr": "https://github.com/Extra-Chill/homeboy/pull/1234", "estimated_size_bytes": 3221225472 } ] }Safety requirements
--skip-githubstill work for local-only cleanup.Acceptance criteria