chore: commit the ruleset payloads under .github/rulesets - #2
Merged
Conversation
`omp-relayd` and `omp-toolgate` both keep the exact GitHub ruleset API payload
in the repository, and this repository's protection existed only in a settings
screen. GitHub does not read these files -- there is no protection-as-code
feature -- so they buy two things: the protection is reviewable in a diff
instead of being invisible to review, and re-applying it after an accident is
one `gh api --input` call rather than a reconstruction from memory.
Both payloads are field-for-field identical to the live rulesets, checked with
the deep key-sorted comparison `omp-relayd` documents:
gh api "repos/$OWNER/$REPO/rulesets/$ID" |
jq -S '[.rules[] | {(.type): .parameters}] | add' > /tmp/live.json
jq -S '[.rules[] | {(.type): .parameters}] | add' .github/rulesets/main.json |
diff - /tmp/live.json && echo "no drift"
main.json (ruleset 21701346) is byte-identical to `omp-relayd`'s, which already
carries `allowed_merge_methods: ["merge"]` and
`require_extra_approval_for_unattributed_changes: true`. tags.json (ruleset
21701352) is byte-identical to `omp-toolgate`'s. A future difference is
therefore real drift rather than serialisation noise.
`required_reviewers: []` is declared rather than omitted. GitHub fills that
field in on the `pull_request` rule at creation time, and omitting it cost
`omp-toolgate` an extra pull request to make the committed payload match the
live one.
The `ci` job's comment now names `.github/rulesets/main.json` explicitly,
because that file hard-codes the literal string `ci` and nothing verifies the
two agree: renaming the job would block every merge with no failing job to
point at.
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
Adopts the shape
omp-relaydandomp-toolgatealready use: the exact GitHub ruleset API payloads live in the repository under.github/rulesets/, instead of the protection existing only in a settings screen.Both rulesets on this repository were created out of band, so nothing in the tree recorded what protection is in force:
main(branch,active) — no committed record of which rules apply, which merge methods are permitted, or thatciis the one required check.release-tags(tag,active) — no committed record thatrefs/tags/v*refuses deletion and non-fast-forward, which is what keeps a published release from silently diverging from the tag it was built from.GitHub does not read these files. There is no protection-as-code feature, and this change does not pretend otherwise. What the files buy is narrower and still worth having: the protection becomes reviewable in a diff, and re-applying it after an accident is one
gh api --method PUT --inputcall rather than a reconstruction from memory.Fidelity to the live rulesets
Both payloads are field-for-field identical to what is live, checked with the deep key-sorted comparison
omp-relayddocuments rather than by eye:The files are also byte-identical to their counterparts in the reference repositories:
main.jsontoomp-relayd's, which already carriesallowed_merge_methods: ["merge"]andrequire_extra_approval_for_unattributed_changes: true, andtags.jsontoomp-toolgate's. A future difference is therefore real drift rather than serialisation noise.required_reviewers: []is declared rather than omitted on purpose. GitHub fills that field in on thepull_requestrule at creation time, and omitting it costomp-toolgatean extra pull request before its committed payload matched the live ruleset.What the payloads record
main.json, targeting~DEFAULT_BRANCHwithbypass_actors: []— so the rules apply to the owner too:deletion,non_fast_forwardmaincannot be deleted or rewoundpull_requestrequired_approving_review_count: 0, so a sole maintainer is not deadlocked by GitHub's refusal to let an author approve their own PR.required_review_thread_resolution: true.allowed_merge_methods: ["merge"]required_status_checksci, withstrict_required_status_checks_policy: truetags.json, targetingrefs/tags/v*:deletionandnon_fast_forwardonly. Creation is deliberately unrestricted —release.ymlderives the published version from the tag name, so what has to be immutable is where av*tag points once it exists.One rule is worth calling out because it is a latent trap rather than a setting:
require_extra_approval_for_unattributed_changes: truecombined withrequired_approving_review_count: 0means a PR containing a commit GitHub cannot attribute to an account needs one approval, which a sole maintainer cannot self-provide. Every commit onmainis currently attributed topashifikavia a linked address, so it does not fire; a commit authored from a machine whosegit config user.emailis not linked would be unmergeable.ci's comment now names the file.github/rulesets/main.jsonhard-codes the literal stringci, and nothing mechanically verifies that it matches the aggregating job's name. Renaming the job would block every merge with no failing job to point at, so the comment says so, and says that runtime jobs are never named in the ruleset — adding or removing one means editingneedsand nothing else.Key files changed
.github/rulesets/main.jsonmainbranch ruleset payload (ruleset 21701346), byte-identical toomp-relayd's.github/rulesets/tags.jsonrelease-tagstag ruleset payload (ruleset 21701352), byte-identical toomp-toolgate's.github/workflows/ci.ymlcijob's comment now names the ruleset file that depends on its nameTest plan
jq emptyon both payloads — valid JSONIDENTICALfor both, transcript abovediffagainst the reference repositories' files — byte-identicalmainrejected (Changes must be made through a pull request.,Required status check "ci" is expected.), measured with a throwaway empty commit before this branch was cut, then discardedci / hygieneandci / bunpass on this PR — the only source change is a comment, sobunis expected green unchanged, andhygienestill finds its 8 pinneduses:referencesci / cigreen, which is also the first exercise of the now-activerequired_status_checksrule on a real PRThis change touches no runtime code.
install checkremains skipped on pull requests by design.🤖 Generated with Claude Code