Skip to content

Add default-branch-protection ruleset with FVM path-scoped review policy#8613

Open
Kay-Zee wants to merge 1 commit into
masterfrom
kan/fvm-review-policy-ruleset
Open

Add default-branch-protection ruleset with FVM path-scoped review policy#8613
Kay-Zee wants to merge 1 commit into
masterfrom
kan/fvm-review-policy-ruleset

Conversation

@Kay-Zee

@Kay-Zee Kay-Zee commented Jul 20, 2026

Copy link
Copy Markdown
Member

Codifies the master-branch protection policy as a ruleset spec in the repo, adds a small CLI tool for admins to apply changes, and a workflow that shouts if the live ruleset ever drifts from what's in git.

Motivation is FVM review capacity — with a small pool of reviewers and a growing stack of FVM PRs, we'd like an AI reviewer to be able to count as one of the two required approvals on FVM-only changes, without letting bot approvals
substitute for humans anywhere else. GitHub rulesets have a required_reviewers feature that expresses exactly this: for the pattern ["*", "!fvm/**"], the team @onflow/flow-core-protocol (what CODEOWNERS already says owns the repo)
must supply 2 approvals; on FVM-only PRs there's no team requirement, so any two approvers satisfy the global count. Assumption baked in: exactly one AI reviewer account exists on the repo — if we ever add a second, we'll want a follow-up
entry to keep "2 bots, 0 humans" impossible.

The rest of the ruleset is a 1:1 mirror of what's currently on master via legacy branch protection — same 48 required checks (strict mode), same code-owner review requirement, same "don't dismiss stale reviews", same admin-can-bypass
semantics via RepositoryRole id 5. Nothing about baseline enforcement is changing; the ruleset is just the modern container for it, with room for the path-scoped reviewer rule that classic branch protection doesn't support.

The read-only pattern is deliberate: the workflow only ever calls the API with administration: read, so there's no stored PAT and no write-capable service account. Policy changes flow through PRs (this file being reviewed like any
other), and an admin applies them locally with apply.sh using their own credentials. If someone hand-edits the ruleset in the UI, the daily verify run and the next PR touching this directory both fail loudly, naming the drifted field.
Trade-off vs full IaC: no auto-apply, admin has to run one command. Fine for something that changes a handful of times a year.

Rollout after merge: an admin runs apply.sh .github/rulesets/default-branch-protection.json to create the live ruleset, confirms verify-rulesets passes, then removes the legacy branch protection on master (which the ruleset now
supersedes). The verify-rulesets check itself isn't in the required-checks list yet — worth adding as a follow-up once we've observed the exact check-run name GitHub records for it.

Companion work — the actual AI reviewer install/config, and mirroring this to flow-go-internal — will land separately.

Summary by CodeRabbit

  • New Features

    • Added configuration for default-branch protection, including required reviews and status checks.
    • Added tooling to create or update repository rulesets from configuration files.
    • Added automated verification to detect differences between configured and active rulesets.
  • Documentation

    • Documented the ruleset management workflow, local application process, validation checks, and reviewer requirements.

@Kay-Zee
Kay-Zee requested a review from a team as a code owner July 20, 2026 22:33
@github-actions

Copy link
Copy Markdown
Contributor

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 1 package(s) with unknown licenses.
See the Details below.

License Issues

.github/workflows/verify-rulesets.yml

PackageVersionLicenseIssue Type
actions/checkout4.*.*NullUnknown License

OpenSSF Scorecard

PackageVersionScoreDetails
actions/actions/checkout 4.*.* 🟢 6.9
Details
CheckScoreReason
Maintained🟢 1024 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 10all changesets reviewed
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Binary-Artifacts🟢 10no binaries found in the repo
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Packaging⚠️ -1packaging workflow not detected
Pinned-Dependencies🟢 3dependency not pinned by hash detected -- score normalized to 3
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 9security policy file detected
SAST🟢 10SAST tool is run on all commits
Branch-Protection🟢 5branch protection is not maximal on development and all release branches

Scanned Files

  • .github/workflows/verify-rulesets.yml

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds a declarative default-branch protection ruleset, an administrator-run script for creating or updating GitHub rulesets, documentation for the operating model, and a read-only workflow that detects drift between JSON specifications and live rulesets.

Changes

Ruleset management

Layer / File(s) Summary
Default branch policy specification
.github/rulesets/default-branch-protection.json, .github/rulesets/README.md
Defines active protection for the default branch, including deletion and force-push restrictions, review requirements, bypass behavior, required status checks, and path-scoped reviewers.
Local ruleset application
.github/rulesets/apply.sh, .github/rulesets/README.md
Documents the administrator application process and adds validation plus idempotent create-or-update behavior using gh, jq, and the GitHub API.
Automated ruleset drift verification
.github/workflows/verify-rulesets.yml, .github/rulesets/README.md
Adds scheduled, push, pull request, and manual verification that compares normalized local specifications with live GitHub rulesets using read-only permissions.

Estimated code review effort: 3 (Moderate) | ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding a default-branch protection ruleset with FVM-scoped review requirements.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch kan/fvm-review-policy-ruleset

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
.github/rulesets/README.md (1)

23-25: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Specify the language for fenced code blocks.

Adding a language identifier (such as sh or bash) to fenced code blocks improves markdown readability by enabling proper syntax highlighting.

  • .github/rulesets/README.md#L23-L25: Add sh to the opening backticks.
  • .github/rulesets/README.md#L53-L55: Add sh to the opening backticks.
  • .github/rulesets/README.md#L134-L136: Add sh to the opening backticks.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/rulesets/README.md around lines 23 - 25, Specify the shell language
on the opening fences for all three command examples in
.github/rulesets/README.md: lines 23-25, 53-55, and 134-136. Add the sh
identifier while preserving each example’s existing command and content.

Source: Linters/SAST tools

.github/workflows/verify-rulesets.yml (1)

32-32: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Prevent credential persistence in the checkout action.

Setting persist-credentials: false ensures the GITHUB_TOKEN isn't left in the local git config, reducing the risk of accidental exposure in subsequent steps.

🛡️ Proposed fix
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v4
+        with:
+          persist-credentials: false
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/verify-rulesets.yml at line 32, Update the
actions/checkout@v4 step in the workflow to set persist-credentials to false,
ensuring the checkout action does not retain the GITHUB_TOKEN in local Git
configuration.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/rulesets/apply.sh:
- Around line 46-47: Paginate both rulesets index requests by adding the gh api
pagination option to the calls in .github/rulesets/apply.sh lines 46-47 and
.github/workflows/verify-rulesets.yml lines 37-38; no other logic changes are
needed.

In @.github/workflows/verify-rulesets.yml:
- Around line 24-27: Remove the invalid administration entry from the workflow’s
permissions block, leaving contents: read as the required permission for the
ruleset verification job.

---

Nitpick comments:
In @.github/rulesets/README.md:
- Around line 23-25: Specify the shell language on the opening fences for all
three command examples in .github/rulesets/README.md: lines 23-25, 53-55, and
134-136. Add the sh identifier while preserving each example’s existing command
and content.

In @.github/workflows/verify-rulesets.yml:
- Line 32: Update the actions/checkout@v4 step in the workflow to set
persist-credentials to false, ensuring the checkout action does not retain the
GITHUB_TOKEN in local Git configuration.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d44e5258-e129-4869-833b-2f2446a29f02

📥 Commits

Reviewing files that changed from the base of the PR and between ad55d25 and 1c68f54.

📒 Files selected for processing (4)
  • .github/rulesets/README.md
  • .github/rulesets/apply.sh
  • .github/rulesets/default-branch-protection.json
  • .github/workflows/verify-rulesets.yml

Comment thread .github/rulesets/apply.sh
Comment on lines +46 to +47
id=$(gh api "/repos/$repo/rulesets" \
| jq -r --arg n "$name" '.[] | select(.name == $n) | .id')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Paginate the gh api call to ensure all rulesets are retrieved.

Both files list repository rulesets without pagination. By default, the GitHub API paginates results (30 items per page). If the repository accumulates many rulesets, a single call may not return the complete list, causing drift detection or apply logic to silently miss existing rulesets. Adding --paginate automatically fetches and merges all pages.

  • .github/rulesets/apply.sh#L46-L47: Add --paginate to the gh api call fetching the rulesets index.
  • .github/workflows/verify-rulesets.yml#L37-L38: Add --paginate to the gh api call fetching the rulesets index.
📍 Affects 2 files
  • .github/rulesets/apply.sh#L46-L47 (this comment)
  • .github/workflows/verify-rulesets.yml#L37-L38
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/rulesets/apply.sh around lines 46 - 47, Paginate both rulesets index
requests by adding the gh api pagination option to the calls in
.github/rulesets/apply.sh lines 46-47 and .github/workflows/verify-rulesets.yml
lines 37-38; no other logic changes are needed.

Comment on lines +24 to +27
permissions:
administration: read
contents: read

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Remove the invalid administration permission scope.

The administration scope is not a valid permission for GITHUB_TOKEN in GitHub Actions. Its presence will cause a workflow syntax error, preventing the job from running entirely. The contents: read scope is generally sufficient to read rulesets.

🔨 Proposed fix
 permissions:
-  administration: read
   contents: read
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
permissions:
administration: read
contents: read
permissions:
contents: read
🧰 Tools
🪛 actionlint (1.7.12)

[error] 25-25: unknown permission scope "administration". all available permission scopes are "actions", "artifact-metadata", "attestations", "checks", "contents", "deployments", "discussions", "id-token", "issues", "models", "packages", "pages", "pull-requests", "repository-projects", "security-events", "statuses"

(permissions)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/verify-rulesets.yml around lines 24 - 27, Remove the
invalid administration entry from the workflow’s permissions block, leaving
contents: read as the required permission for the ruleset verification job.

Source: Linters/SAST tools

"*",
"!fvm/**"
],
"approvals_needed": 2

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be 3 if we want 2 reviewers + AI, before we switch to 1 reviewer + AI

@janezpodhostnik
janezpodhostnik requested a review from a team July 21, 2026 15:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants