Problem
workspace cleanup safe --dry-run reports destructive-looking removal counts and double-counts the same inventory across internal stages.
Evidence
With 5 stale unlocked lock resources, dry-run reported both lock_prune_start.removed_count: 5 and lock_prune_end.removed_count: 5, then summarized lock_files_removed: 10 even though applied: false.
The same run summarized 1,348 blockers for a 684-worktree inventory because blocker totals from cleanup_eligible and active_no_signal stages were added together. Example: 70 active_no_signal rows became 140 in blockers_by_reason.
Expected
- Dry-run uses
would_remove, never removed, for mutation counters.
- Summary resource counts are deduplicated across orchestration stages.
- Per-stage attempts remain available separately for diagnostics.
Acceptance criteria
A dry-run over N stale locks reports removed: 0, would_remove: N, and a deduplicated blocker total no greater than the unique inventory unless explicitly labeled as stage observations.
AI assistance
- AI assistance: Yes
- Tool: OpenAI gpt-5.6-sol via OpenCode/Kimaki
- Used for: Live cleanup diagnosis and issue drafting
Problem
workspace cleanup safe --dry-runreports destructive-looking removal counts and double-counts the same inventory across internal stages.Evidence
With 5 stale unlocked lock resources, dry-run reported both
lock_prune_start.removed_count: 5andlock_prune_end.removed_count: 5, then summarizedlock_files_removed: 10even thoughapplied: false.The same run summarized 1,348 blockers for a 684-worktree inventory because blocker totals from
cleanup_eligibleandactive_no_signalstages were added together. Example: 70active_no_signalrows became 140 inblockers_by_reason.Expected
would_remove, neverremoved, for mutation counters.Acceptance criteria
A dry-run over N stale locks reports
removed: 0,would_remove: N, and a deduplicated blocker total no greater than the unique inventory unless explicitly labeled as stage observations.AI assistance