feature(ci): add the dispatchable branch sweep - #321
Merged
Conversation
Companion to PyAutoBrain's `bin/branch_sweep.sh` — this repo hosts the trigger, the Brain hosts the logic (the workflow checks Brain out, so there is one implementation and no copy to drift). Why it exists: a cloud Claude session can audit branches but cannot delete a remote ref (403 for the session credential; no delete-ref call in its GitHub tool surface), so cleanup was laptop-only. A sweep on 2026-08-25 found 176 branches here, 135 of them provably contained in main, and could not act on any of it. A workflow's GITHUB_TOKEN has the `contents: write` this repo already grants dashboard_refresh.yml, so the sweep runs here instead. Dispatch with mode=audit (the default) to see the contained / unmerged / protected split in the run summary; mode=delete to act, with an optional limit for a first cautious batch. The weekly cron is audit-only and forces that mode regardless of input, so nothing is ever removed unattended. Note this is the backstop, not the fix: this repo has "Automatically delete head branches" off, which is why every merged PR head since #22 is still present. Turning that on prevents the pile-up; the sweep clears what predates it, branches pushed without a PR, and heads whose PR closed unmerged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KwqicJpMqmcT5RVbyNwdKq
The PR-time spawn contract test failed on the new workflow: every tracked file must match a MIND_RULES entry, so spawn can decide whether it travels into the fresh-slate template. `branch_sweep.yml` matched nothing. DROP, on both of rule 9c's existing grounds. It checks out PyAutoLabs/PyAutoBrain for the sweep logic — dashboard_refresh.yml's failure mode, where owner substitution yields the literal YOURORG/PyAutoBrain and the run dies on checkout — and it carries a weekly cron, which rule 9's no-unattended-trigger condition rejects independently. A fresh org would inherit a scheduled job that fails every Sunday and cannot be made to work until it has a Brain. The sweep is worth having in a mature organism; it is worth re-adding deliberately rather than by inheritance. Spec table extended first, then mirrored into MIND_RULES, in the order the assertion message asks for. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KwqicJpMqmcT5RVbyNwdKq
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
A cloud Claude session can audit branches but cannot delete a remote ref — 403 for the session credential, and no delete-ref call in its GitHub tool surface. So cleanup was laptop-only. A
/repo_cleanupsweep on 2026-08-25 found 176 branches here, 135 of them provably contained inmain, and could not act on any of it.A workflow's
GITHUB_TOKENhas thecontents: writethis repo already grantsdashboard_refresh.yml, so the sweep runs here instead.What's here
One workflow. This repo hosts the trigger; PyAutoBrain hosts the logic — the workflow checks Brain out and runs
bin/branch_sweep.sh, so there is one implementation and no copy to drift.Dispatch with
mode=audit(the default) to see the contained / unmerged / protected split in the run summary;mode=deleteto act, with an optionallimitfor a first cautious batch. The weekly cron is audit-only and forces that mode regardless of input, so nothing is ever removed unattended.The safety gates live in the script, not the workflow: never
main, neverarchive/condemned/*(PyAutoGut transit refs — voiding one early destroys the recovery path the Gut exists to provide), never an open PR's head, never a branch git cannot prove is contained.This is the backstop, not the fix
This repo has Settings → General → "Automatically delete head branches" off, which is why every merged PR head since #22 is still present. Turning that on prevents the pile-up. The sweep clears what predates it, branches pushed without a PR, and heads whose PR closed unmerged — none of which auto-delete covers.
Merge order
Merges after PyAutoLabs/PyAutoBrain#278, which puts
branch_sweep.shon Brain'smain. Dispatching this before that lands would fail at the checkout step.🤖 Generated with Claude Code
https://claude.ai/code/session_01KwqicJpMqmcT5RVbyNwdKq
Generated by Claude Code