Skip to content

fix(refresh-repo,git-workflow-standards): catch zero-ahead branches; split into prune-branches#445

Merged
JacobPEvans-personal merged 2 commits into
mainfrom
fix/stale-branch-cleanup
Jul 24, 2026
Merged

fix(refresh-repo,git-workflow-standards): catch zero-ahead branches; split into prune-branches#445
JacobPEvans-personal merged 2 commits into
mainfrom
fix/stale-branch-cleanup

Conversation

@openbao-service-broker

@openbao-service-broker openbao-service-broker Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

What

clean_gone only deletes [gone] branches. It missed two dead branches whose commits were already fully in main — one had a live remote, one was remote-only after its PR merged. The real "nothing useful" signal is ahead-count against the default branch, not remote-tracking status.

Changes

  • refresh-repo Step 5: stale check is unconditional, not gated on [gone]. Three passes cover every ref shape — worktree-paired, bare local, remote-only. Any local delete now also deletes a live matching remote branch, with a pre-push ancestry recheck.
  • New skill prune-branches carries that whole procedure (and --sweep/--prune-stale) out of refresh-repo, which drops from ~264 lines to 131 — invoking it for PR-readiness + sync no longer loads the full cleanup prose.
  • wrap-up folds the old external commit-commands:clean_gone step into prune-branches, called right after refresh-repo in Path A — prune-branches is a strict superset, so the separate step and the external dependency both go away.
  • Every stale cross-reference this touched — plugin.json, both plugins' README/ARCHITECTURE diagrams, sync-main, troubleshoot-worktree, session-status, pr-sweep, skills-registry — updated.

Safety (independent Opus review before landing)

Dropping [gone] on its own would let the rule autonomously delete origin/main on a git-flow repo (main is routinely an ancestor of develop). Fixed with a protected-branch guard — default branch, checked-out-anywhere, referenced by an open PR as --head or --base — re-checked unconditionally on every pass. Also added: the open-PR check covers --base, not just --head; the remote delete re-confirms ancestry immediately before the push, not once at the top of the run.

Quality pass (/simplify, 4-agent review)

  • git-workflow-standards was re-deriving refresh-repo's mechanism and git-flow rationale instead of pointing at it — trimmed to the concept, now points at prune-branches.
  • Protected's open-PR check was 2 live gh pr list calls per candidate branch; now one repo-wide call up front, tested by set membership.
  • Every negative-framed instruction (never/NOT/NEVER) rewritten as a direct positive statement, per explicit user direction; cut wording flagged as filler or cross-file duplication.

Test plan

  • Every touched file passes this repo's markdown lint hook.
  • Cross-reference sweep: no remaining clean_gone reference outside the (unrelated, external) Anthropic plugin's own permission string; no remaining "refresh-repo does cleanup" claim anywhere.
  • Mermaid node IDs in all three touched ARCHITECTURE.md diagrams verified defined-and-referenced.
  • Dry-run trace against the two real dead branches that motivated this: one caught by the bare-local pass, one by the remote-only pass.
  • No code to build/test — documentation-only change to agent instructions.

🤖 Generated with Claude Code

https://claude.ai/code/session_012s1AcPKsXaLT5e1n6G9M2u

…not just [gone]

clean_gone only deletes [gone] branches; it found nothing to clean on a repo
carrying two dead branches whose commits were already fully contained in
main (pure ancestors, never [gone] since their remotes were still live).
The real signal for "nothing useful" is ahead-count against the default
branch, not remote-tracking status — [gone] was only ever a narrowing proxy
for "probably merged."

- refresh-repo Step 5 (renamed Branch and Worktree Cleanup): the stale
  ahead-count check is now unconditional, no longer gated on [gone]. Three
  passes cover every ref shape: worktree-paired (existing), bare local
  branches with no worktree, and remote-only branches with no local ref at
  all. Any local delete now also deletes the matching live remote branch.
- git-workflow-standards: same rule, condensed to match this file's prose
  style, kept in sync per its own documented expectation.

Widening "ahead of default" to run without [gone] is only safe because a
protected-branch guard (default branch, checked-out-anywhere, referenced by
an open PR as --head or --base) now runs first and unconditionally on every
one of the three passes independently — dropping that guard would let the
rule autonomously delete origin/main on a git-flow repo, since main is
routinely an ancestor of develop there. The remote-delete step also
re-confirms ancestry immediately before the destructive push (not once at
the top of the run), since git push origin --delete ignores tip state and
a race would silently discard new commits.

Independently reviewed (Opus, high effort) before landing; the review
caught the git-flow guard gap, an incomplete open-PR check (--head only,
missing --base), and the missing pre-push recheck — all three folded in.

Assisted-by: Claude:claude-opus-4-8
Claude-Session: https://claude.ai/code/session_012s1AcPKsXaLT5e1n6G9M2u
…ches

/simplify (4-agent review: reuse, simplification, efficiency, altitude) on
the prior commit's diff, plus a direct user request to split refresh-repo
so invoking it doesn't load the full branch-cleanup procedure by default.

- New skill github-workflows:prune-branches carries Step 5 (Protected/Stale/
  three-pass/remote-delete) and the Cross-Repo Operating Modes wholesale.
  refresh-repo drops from ~264 lines back to 131 — a caller that only wants
  PR-readiness + sync no longer pays for cleanup prose it isn't using.
- git-workflow-standards' "Stale branch" paragraph was re-deriving refresh-
  repo's mechanism and git-flow safety rationale instead of pointing at it
  (reuse + altitude agents, independently). Trimmed to the concept, now
  points at prune-branches as the procedure's new home.
- Protected's open-PR check was 2 live `gh pr list` calls per candidate
  branch; now one repo-wide `--json headRefName,baseRefName` call up front,
  tested by set membership (efficiency agent).
- Applied every negative-framed instruction rewrite the simplification
  agent proposed (never/NOT/NEVER -> positive statements) and cut the
  wording it flagged as filler or cross-file duplication.
- wrap-up's Path A folds the old external `commit-commands:clean_gone` step
  into `/prune-branches` (invoked right after `/refresh-repo` in A1) —
  prune-branches is a strict superset of clean_gone's `[gone]`-only scope,
  so the separate step and the external plugin dependency both go away.
- Updated every stale cross-reference this split or the clean_gone removal
  touched: plugin.json skill registration, both plugins' README/ARCHITECTURE
  diagrams, and the Related Skills sections in sync-main, troubleshoot-
  worktree, session-status, pr-sweep, skills-registry.

Assisted-by: Claude:claude-opus-4-8
Claude-Session: https://claude.ai/code/session_012s1AcPKsXaLT5e1n6G9M2u
@openbao-service-broker openbao-service-broker Bot changed the title fix(refresh-repo,git-workflow-standards): catch zero-ahead branches, not just [gone] fix(refresh-repo,git-workflow-standards): catch zero-ahead branches; split into prune-branches Jul 24, 2026
@JacobPEvans-personal
JacobPEvans-personal merged commit 97f6b05 into main Jul 24, 2026
28 checks passed
@JacobPEvans-personal
JacobPEvans-personal deleted the fix/stale-branch-cleanup branch July 24, 2026 15:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant