Skip to content

What proves an agent worktree safe to remove, and what if it cannot be proved #446

Description

@blooop

Question

What exactly proves an agent worktree safe to remove, and what is the answer when the proof cannot be obtained?

Principle 1 says fail towards keeping. This ticket turns that into one predicate somebody can read, because right now the answer is spread across a reachability check, a dirty check with a pathspec exclusion, a lock check, and an arm that had no probe at all.

The cases, each needing a stated verdict:

  • Unpushed commits; branch absent from the remote entirely; branch present but local ahead.
  • Detached HEAD, where there is no branch for a branch-keyed check to find and the admin dir's HEAD is the only thing reaching the commit.
  • Dirty working tree; staged-but-uncommitted index; untracked files.
  • Untracked content that is not a worktree under a worktree's own .claude/worktrees/, which review finding S4 established is currently excluded from the dirty check and skipped by the sweep, so it is neither reported nor protected.
  • git worktree locked, which dl --prune cannot reclaim agent worktrees inside live workspaces' clones (104 GB measured) #426 Ask 2 says is never removed implicitly.
  • Stashes: refs/stash lives in the shared repository, so it survives the directory. Confirm and write it down so nobody re-checks it.

And the cases where the check itself cannot run, which is where principle 1 actually bites:

  • Remote-tracking refs that are stale or absent, because the clone is cut from the sibling .bare and repointed at the forge with no fetch of its own. Asking the clone alone reports pushed-and-merged branches as unpushed; asking the bare gives an answer as of the last fetch. Neither is live, and --prune must not start doing network I/O.
  • A registered path that is a container path and does not resolve on the host.
  • A gitfile tail that does not normalise to a name under <clone>/.git/worktrees/ (traversal, doubled or trailing separators, absolute vs relative, a tail naming a different worktree's admin dir).

Decide whether the honest answer is a boolean, or a value that distinguishes proved safe, proved unsafe, and could not be proved — the third being the one principle 1 cares about, and the one a boolean has to lie about. Whatever it is, the output has to be able to say which case a kept worktree fell in, because "kept" with no reason is what makes a straggler invisible.

Run /constructive-modeling.

How the answer gets tested: one table-driven test with a row per case above, including the unprovable ones, each asserting the verdict and the reason string.

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions