* enhancement(#40): integrate branch pruning into /gsd-cleanup archival workflow
Adds a prune_local_branches step to cleanup.md (between archive_phases and
commit) that force-deletes local branches whose upstream is gone — keeping
local clones symmetric with delete_branch_on_merge on GitHub.
Key design choices vs. PR #562 (the local-model draft):
- dry-run step shows stale branches using cached tracking refs only; git
fetch --prune is deferred to the execution step so the dry-run is
non-side-effecting
- awk uses { if ($1 != "*") print $1 } form to explicitly exclude the
currently checked-out branch (the * prefix in git branch -vv output),
not a prose note that lets xargs receive literal * as an argument
- git fetch --prune runs exactly once, in prune_local_branches, eliminating
the TOCTOU window between a preview fetch and an execution fetch
- two new negative-contract tests: identify_completed_milestones must not
run git branch commands; show_dry_run must not run git fetch --prune
Closes#40
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore: regenerate changeset using repo script (correct format)
Replaces hand-written fragment (used `/** ... */` comment syntax)
with one generated by `npm run changeset -- --type Changed --pr 562`.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: address codex review blockers — protect main/next/trunk, align dry-run with execution
Codex adversarial review (pre-PR gate) flagged two blockers:
1. awk filter only excluded '*' (current branch) but not protected names.
main/next/trunk/develop could be force-deleted if their upstream was
gone. Fix: use !~ /^\*$|^main$|^next$|^trunk$|^develop$/ regex match.
2. Dry-run enumerated from cached tracking refs; execution re-ran
git fetch --prune, creating a TOCTOU window between what the user
confirmed and what got deleted. Fix: move git fetch --prune into
show_dry_run (prefetch for display accuracy); prune_local_branches
now enumerates from the already-fetched state with no second fetch.
Updated 14 structural tests to match new design (added protected-name
exclusion test; inverted show_dry_run fetch assertion).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>