Context: #2597
Problem
reclaimable-worktree rests entirely on git status --porcelain being empty at the worktree root, and its evidence line says exactly that. But git status --porcelain cannot see ignored files, and removing a worktree directory destroys them. The finding's stated evidence does not cover the content most likely to be lost.
Evidence
263 reclaimable-worktree findings were emitted in one run. Independent verification re-ran git status --porcelain on a sample of 8 and confirmed all 8 genuinely empty — the finding is accurate as stated. Checking --ignored on the same sample found:
…/songwriting-enable-plugin — ignored .claude/observability/ and .work/handoffs/, i.e. session handoff files, plausibly irreplaceable
…/chezmoi-worktrees/352-bump-markdownlint-cli2 — ignored node_modules/ only, harmless
- the remaining 6 — nothing ignored
So the loss vector is real but not universal, which is precisely why it needs to be surfaced per worktree rather than assumed either way.
Two related facts, both verified, that bound this issue:
- Stashes are not a loss vector.
refs/stash lives in the common gitdir (git-worktree REFS: all refs/ are shared except refs/bisect, refs/worktree, refs/rewritten), so git stash list from a linked worktree returns the repository's stack. Removing a worktree directory cannot orphan a stash. The skill's decision to scope stashes out is correct — but the wording should say why, because as written it reads like an acknowledged gap.
- Uncommitted working-tree content is the only true data loss on removal. Index, per-worktree HEAD reflog, and
config.worktree survive a directory removal and are destroyed later by prune, not by the removal itself.
Proposed change
- Extend the evidence gathering to
git status --porcelain --ignored and surface the ignored entries in the finding.
- Classify well-known regenerable paths (
node_modules/, target/, .venv/, bin/, obj/, dist/) separately from everything else, so the signal is not drowned by build output.
- A worktree whose only ignored content is regenerable keeps its current disposition; one with non-regenerable ignored content is reported as such and is not offered for directory removal without naming what will be destroyed.
- Amend the stash wording to state that stashes are repository-global and therefore unaffected by worktree removal, rather than merely out of scope. Check
git stash list once per repository, never per worktree — every worktree reports the same shared stack, and doing it per worktree implies an isolation that does not exist.
Acceptance criteria
- Every
reclaimable-worktree finding names its ignored entries or states that there are none.
- Non-regenerable ignored content downgrades or annotates the finding rather than being invisible.
- The skill's stash wording explains the shared-stack mechanism.
- Stash state is collected once per repository.
Context: #2597
Problem
reclaimable-worktreerests entirely ongit status --porcelainbeing empty at the worktree root, and its evidence line says exactly that. Butgit status --porcelaincannot see ignored files, and removing a worktree directory destroys them. The finding's stated evidence does not cover the content most likely to be lost.Evidence
263
reclaimable-worktreefindings were emitted in one run. Independent verification re-rangit status --porcelainon a sample of 8 and confirmed all 8 genuinely empty — the finding is accurate as stated. Checking--ignoredon the same sample found:…/songwriting-enable-plugin— ignored.claude/observability/and.work/handoffs/, i.e. session handoff files, plausibly irreplaceable…/chezmoi-worktrees/352-bump-markdownlint-cli2— ignorednode_modules/only, harmlessSo the loss vector is real but not universal, which is precisely why it needs to be surfaced per worktree rather than assumed either way.
Two related facts, both verified, that bound this issue:
refs/stashlives in the common gitdir (git-worktreeREFS: allrefs/are shared exceptrefs/bisect,refs/worktree,refs/rewritten), sogit stash listfrom a linked worktree returns the repository's stack. Removing a worktree directory cannot orphan a stash. The skill's decision to scope stashes out is correct — but the wording should say why, because as written it reads like an acknowledged gap.config.worktreesurvive a directory removal and are destroyed later byprune, not by the removal itself.Proposed change
git status --porcelain --ignoredand surface the ignored entries in the finding.node_modules/,target/,.venv/,bin/,obj/,dist/) separately from everything else, so the signal is not drowned by build output.git stash listonce per repository, never per worktree — every worktree reports the same shared stack, and doing it per worktree implies an isolation that does not exist.Acceptance criteria
reclaimable-worktreefinding names its ignored entries or states that there are none.