Summary
All 15 org repos currently have classic main protection applied and current
(verified live 2026-06-26) via scripts/apply-branch-protection.sh, required
check ok. The gap is not missing protection — it's that enforcement is
manual and incomplete:
- No drift-healing automation. The script is run by hand; nothing re-asserts
it on a schedule, so protection drift is invisible until someone notices.
- Tags/releases are unprotected, even though providers publish versioned
releases (tag deletion/force-push is currently possible).
Org is on GitHub Free, so org-level rulesets aren't available — we stay on the
per-repo scripted classic-protection approach, but make it self-healing.
Scope
- Scheduled drift-healing workflow in
.github that re-runs
apply-branch-protection.sh (or asserts + diffs) across the REPOS list on a
cron, and reports/fails on drift. Avoid passive compliance reporting — the run
should re-apply, not just observe.
- Needs an admin-scoped PAT secret (the default
GITHUB_TOKEN can't PUT
branch protection org-wide). Decision: store an admin PAT as an org/repo
secret for this workflow. (owner: provision the secret.)
- Extend the script to protect tags/releases (tag protection rules:
block deletion + force-push on v* tags at minimum).
- Keep the
ok required-check contract intact (renaming/removing it permanently
blocks PRs — see script comments).
Out of scope / deferred
- Revisiting the solo-dev
0 required approvals + enforce_admins posture —
intentional for now; revisit when more contributors join.
- Paying for GitHub Team to get real org rulesets — not now.
Acceptance
- A scheduled workflow re-asserts branch protection across all listed repos and
surfaces drift loudly.
v* tags are protected against deletion/force-push.
- New-repo onboarding still means "add to the
REPOS list" (documented).
Summary
All 15 org repos currently have classic
mainprotection applied and current(verified live 2026-06-26) via
scripts/apply-branch-protection.sh, requiredcheck
ok. The gap is not missing protection — it's that enforcement ismanual and incomplete:
it on a schedule, so protection drift is invisible until someone notices.
releases (tag deletion/force-push is currently possible).
Org is on GitHub Free, so org-level rulesets aren't available — we stay on the
per-repo scripted classic-protection approach, but make it self-healing.
Scope
.githubthat re-runsapply-branch-protection.sh(or asserts + diffs) across theREPOSlist on acron, and reports/fails on drift. Avoid passive compliance reporting — the run
should re-apply, not just observe.
GITHUB_TOKENcan't PUTbranch protection org-wide). Decision: store an admin PAT as an org/repo
secret for this workflow. (owner: provision the secret.)
block deletion + force-push on
v*tags at minimum).okrequired-check contract intact (renaming/removing it permanentlyblocks PRs — see script comments).
Out of scope / deferred
0 required approvals+enforce_adminsposture —intentional for now; revisit when more contributors join.
Acceptance
surfaces drift loudly.
v*tags are protected against deletion/force-push.REPOSlist" (documented).