Repository navigation
Feat/branch gates applier - #1043
Merged
Merged
Conversation
…cified but nothing performed
config/rulesets/README.adoc has said so since it was written: "the propagation
mechanism is still missing by design, and this note is the reminder that a
template fix without an applier is a half fix." That was literally true —
nothing in this repository read config/rulesets/gates.json as DATA. Every
reference was prose, or tests/test_governance_reusable_shape.sh asserting the
file's contents. gates.json specified a context derivation that no code
performed, so required_status_checks was never propagated to any repository.
apply-tag-ruleset-canon.sh is the TAG applier; this is its branch sibling.
CONTEXTS ARE DERIVED, NEVER TYPED
Per gates.json, contexts come from the check names the latest default-branch
run of each gate workflow actually emitted, via
/actions/workflows/{file}/runs?branch=<default>&per_page=1
/actions/runs/{id}/jobs
A hand-typed context that nothing emits is a PHANTOM: it can never turn
green, so it blocks the branch permanently.
THE REFUSAL THAT MATTERS
Zero derivable contexts => report UNGATED and write NOTHING. A
required_status_checks rule carrying an empty list is a VACUOUS GATE: it
reports "protected" in every summary view while requiring nothing, which is
strictly worse than having no rule, because it is indistinguishable from a
working one.
EXACTNESS GUARD
A ruleset PUT replaces the whole object. The planned body, normalised with
the required_status_checks rule removed from both sides, must be
byte-identical to the source; anything else moved is a refusal. Without it,
one jq slip strips required_signatures from every repo it touches, silently.
DELIBERATE NON-ACTIONS
* never creates a ruleset (NORULESET is reported, not repaired) — creating
branch protection where none exists is a policy act, not a gate-fill;
* never removes the four retired rule types unless --strip-retired is passed
— the estate census was ruled report-only;
* two active branch rulesets => AMBIGUOUS, fail closed. Rulesets are
ADDITIVE: filling one of a pair leaves the other enforcing and the repo
stays blocked by a rule nothing announced.
--require-green N implements the standing ruling on #956, "require the
reliably-green set": a context that is currently red becomes a merge deadlock
the instant it is required. `skipped` and `neutral` count as green, because
GitHub treats both as satisfying a required status check.
TESTS — a passing suite would not have been evidence
scripts/tests/branch-gates-apply-test.sh runs 18 controls, two of which are
MUTANTS that must go red:
A. delete the zero-context refusal -> the applier writes the vacuous
empty-list rule (verified by inspecting the captured PUT body);
B. make the body-builder also drop required_signatures -> the exactness
guard refuses.
Both die. The suite exercises the applier through a `gh` shim, so it needs
no network and no credentials.
Two defects were found by these controls rather than in review: the
--strip-retired jq filter used `index(.type)`, where jq rebinds `.` to the
array so `.type` was always null (the same class of bug apply-baseline-test.sh
was written to pin), and the exactness guard rejected its own honest control
because ADDING the required_status_checks rule legitimately changes the rules
array length.
Both files are committed 100755 — a suite committed 0644 passes every local
run and dies in CI at exit 126 before a single control executes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ji1bq3TypfycfUPAR7hSxR
Contributor
|
Warning Review limit reachedNext included review available in 53 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (2)
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 |
hyperpolymath
enabled auto-merge (squash)
September 23, 2026 09:27
Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com>
hyperpolymath
disabled auto-merge
September 23, 2026 09:28
hyperpolymath
enabled auto-merge (squash)
September 23, 2026 09:28
|
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.



Summary
Closes #
Type of change
How has this been verified?
Checklist
git commit -S).SPDX-License-Identifier(code/configMPL-2.0,prose
CC-BY-SA-4.0); I did not relicense existing files.Notes for reviewers