Navigate
HomeStart here
MusingsResearch & long-form
BuildingProjects & learnings
WorkProfessional practice
RunningTraining & races
AboutValues & identity
Notes & ArchiveJournals, essays, portfolio
← Back to Building
TOOLJun 2026

Finished Work Was Dying in 38 Worktrees

An estate audit across three repos found roughly ten finished deliverables stranded in worktrees nobody was sitting in. Committed locally, verified, and quietly dying.

gitworktreesjenn-oscloseoutoperations

38
worktrees

across three repos, most long abandoned

~10
stranded deliverables

finished, verified, never shipped

3
valid end states

shipped, preserved, or deferred with a reason

0
left stranded after

one sweep closed the whole estate

Agent sessions create worktrees the way meetings create action items: constantly, and with no natural cleanup step. By June I had 38 worktrees across three repos. Most were harmless clutter. The alarming part was what the audit found inside them: roughly ten pieces of finished work, committed locally in a worktree nobody was sitting in, never merged, never pushed. Real deliverables, done and verified, one branch sweep or one reboot away from not existing.

"Committed locally" feels safe because git feels safe. But a local commit in an abandoned worktree has the durability of a sticky note. Nothing references it, no remote holds it, and the next cleanup pass deletes it without ceremony. The work did not fail. It just never finished arriving.

So the rule became: a worktree session ends in exactly one of three states. Shipped, meaning merged and verified live where applicable. Preserved, meaning pushed to its own remote branch with a note on what finishing looks like. Or deferred, with a written reason. "Committed locally" is not on the list, on purpose.

The sweeper enforces it. It classifies every worktree in the estate: protected because a live session owns it, ship because content is not on main, preserve because it is orphaned work-in-progress, remove because it is clean or already merged, ghost because the directory outlived its registration, or review because the right call needs a human. It runs automatically at session close, and stranded work is treated as a blocking failure, not a notice.

Two judgment calls the tool deliberately refuses to automate. First, supersession: a stranded commit can be older than main's current truth for the same file, so shipping it blindly would regress the repo. You check the history before rescuing anything. Second, liveness at decision time: a snapshot from session start lies, so the sweep re-checks open file handles and directory activity at the moment of removal, and so should you. Deleting a worktree someone is actively working in is how you create the next failure-log entry.

WORKTREE ESTATE SWEEP
  PROTECTED -> live session owns it, never touch
  SHIP      -> content not on main, needs judgment
  PRESERVE  -> orphaned WIP, push to its own branch
  REMOVE    -> clean or already merged
  GHOST     -> directory outlived its registration
  REVIEW    -> ambiguous, a human decides

THE RULE
A session ends SHIPPED, PRESERVED, or DEFERRED.
"Committed locally" is not an end state.