docs(agents): reap spent branches every tick and return to the default branch#2200
docs(agents): reap spent branches every tick and return to the default branch#2200devantler wants to merge 5 commits into
Conversation
…t branch Maintainer direction 2026-07-16: "You never clean up old branches locally or on the remote. I expect you to always clean up and switch back to the default branch after a tick." Every tick's worktree branch survived the tick and nothing reaped it, so the first sweep found ~1,140 spent branches (monorepo alone: 589 local; .github: 35 stale remote). Adds branch-cleanup.sh and makes the sweep an end-of-tick duty. The safety property is the keep-set: deleting a remote branch closes its open PR, so open-PR heads, worktree-held branches, the default branch and non-claude/* branches are never touched. Notably `git branch --merged main` cannot be used here — the portfolio squash-merges, so a merged branch's commits are never in main and the PR state is the only authoritative signal. Verified by running it: 1137 branches reaped across 15 repos, zero open PRs harmed (delete-set asserted to intersect open-PR heads in zero places, and every remote deletion carries MERGED/CLOSED or >14d-no-PR evidence). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codex review |
1 similar comment
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8adfd16fa7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…flagged Fetch/PR-query/manifest failures now ABORT (an empty keep-set from a failed query would have deleted every open PR's branch); remote deletes require PR evidence at the branch's CURRENT sha and are CAS-guarded with --force-with-lease; the open-PR keep-set is re-fetched just before the delete loop; the no-PR age heuristic is removed entirely (commit time is not push time) in favour of report-only candidates; delete/checkout failures propagate via exit 3. AGENTS.md ordering fixed: remove your own worktree BEFORE the sweep. RED/GREEN: bogus-slug run aborts with 0 deletions; monorepo dry-run keeps all 42 worktree/open-PR branches. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codex review |
|
Caution Review failedAn error occurred during the review process. Please try again later. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6bae508dd6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…mmit loss, per-delete TOCTOU PR evidence now binds to devantler-tech-owned heads (a fork PR sharing a branch name can no longer license deleting the origin branch); local -D requires the tip to be reachable from a remote ref (unpushed-only work is kept and reported); and each remote deletion re-checks for a just-opened PR, failing closed on query failure. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codex review |
|
Caution Review failedAn error occurred during the review process. Please try again later. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e1c85c63b8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…als, trap-based return, rejection counter Local deletes now use update-ref -d with the expected sha (CAS) and accept MERGED/CLOSED PR evidence at the exact sha (a squash-merged branch whose remote ref was already pruned is remote-reachable from nothing and would have piled up forever); return-to-default runs first AND on every abort via the EXIT trap, which also un-keeps the tick's own checked-out branch; remote rejections get their own surfaced counter; the evidence bound is 1000 and documented fail-closed; the final-guard residual TOCTOU window is documented as accepted (no server-side conditional delete exists). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5cf5e9eba6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…ore update-ref -d A detached start (an initialized submodule at its superproject pin) is now left exactly as-is — checking out the default branch there silently moved the submodule off its pin. And since update-ref -d bypasses the checked-out-branch refusal git branch -D has, each local delete now re-checks the live worktree list first. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 436f673c2c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| # has, so re-check the live worktree list right before deleting — a | ||
| # concurrent session may have checked the branch out since the keep-set | ||
| # snapshot. | ||
| if git worktree list --porcelain 2>/dev/null | grep -Fxq "branch refs/heads/$b"; then |
There was a problem hiding this comment.
Abort when worktree enumeration fails
When git worktree list --porcelain fails, such as during a transient read or worktree-metadata error, this pipeline returns nonzero and the if condition is treated as false, so execution falls through to git update-ref -d. Because that command bypasses checked-out-branch protection, the script can delete a claude/* branch active in another worktree and subsequently remove its matching closed-PR remote, leaving the live worktree with a dangling/unborn HEAD; capture and validate the worktree-list result separately and abort on failure.
Useful? React with 👍 / 👎.
| if ! git fetch origin --prune -q 2>/dev/null; then | ||
| echo "$SLUG: ABORT — git fetch failed; refusing to act on stale refs" >&2 | ||
| exit 1 |
There was a problem hiding this comment.
Restore the checkout when the initial fetch fails
When this runs from an attached claude/* checkout during a network, authentication, or origin outage, the fetch failure exits before START_BRANCH, return_to_default, and the EXIT trap are established, so the repository remains on the spent branch. That branch is then worktree-protected on the next sweep, defeating the explicit end-of-tick return-and-reap guarantee; install the checkout-restoration path before fetching while still aborting cleanup when the fetch fails.
Useful? React with 👍 / 👎.
Why
You told me I never clean up old branches, locally or on the remote, and that you expect cleanup and a
return to the default branch after every tick. You were right: nothing ever reaped them, so every tick's
branch survived it. The first sweep found ~1,140 spent branches — monorepo alone had 589 stale
local branches, and
.githubhad 35 stale remote ones. It is noise in every branch list, and it hidesthe handful of branches that actually matter.
What
Makes the sweep a standing end-of-tick duty and adds the script that does it. The one thing that makes it
safe: deleting a remote branch closes its open PR, so open-PR branches are never touched — a branch is
only reaped with positive evidence that it is spent.
Already run against the live portfolio: 1,137 branches reaped across 15 repos, zero PRs harmed, with
every deletion recorded so it can be restored.
Fixes nothing user-facing; this is agent-definition upkeep.