Skip to content

Harden the main ruleset: no pull-request requirement, non-strict status checks, and a duplicate ruleset #60

Description

@wormeyman

Branch protection went live on main on 2026-07-30, as repository rulesets rather than classic branch protection (the classic /branches/main/protection endpoint 404s - worth knowing, because that 404 reads like "unprotected" and is not).

Current state, read from the API rather than the UI:

Ruleset EJ (id 20021316, enforcement: active, targets ~DEFAULT_BRANCH):

  • deletion
  • non_fast_forward
  • required_status_checks: context verify (integration 15368 = GitHub Actions), strict_required_status_checks_policy: false
  • bypass_actors: [] - nobody can override, including the owner. That is the right call and should stay.

Ruleset EJNOFORCE (id 19839107, enforcement: active, same target): deletion + non_fast_forward only.

This already does the main job: #55 and #57 were correctly blocked as soon as it turned on, because their branches predate .github/workflows/verify.yml and therefore had no verify run at all. Three follow-ups, in descending order of how much they matter.

1. There is no "require a pull request" rule

EJ requires the verify check but does not require changes to arrive via a pull request. A direct push to main is not structurally forbidden.

Whether that matters depends on intent. The required check makes a direct push awkward but the repo's own history says the risk is real: a commit meant for a feature branch has landed on main here before (see the note in CLAUDE.md about verifying git branch --show-current in the same command as a commit). If PR-only is the intent, add a pull_request rule. If direct pushes for docs-only fixes are wanted, leave it and this can be closed as deliberate.

2. strict_required_status_checks_policy is false

So a branch does not have to be up to date with main to merge. A PR can pass verify against an older main and land on a main it was never tested against.

That is not hypothetical here - it happened twice this week in the same afternoon:

A PR whose green check predates either of those was measured against a different gate.

Leaving it false is defensible while several PRs are open, since true forces every branch to rebase and re-run before it can merge. But it should be a decision, not a default. Suggestion: flip it to true once the current queue (#55, #57) is drained, when the cost is near zero.

3. EJNOFORCE is fully subsumed by EJ

Both are active, both target the default branch, and EJNOFORCE's two rules (deletion, non_fast_forward) are both already in EJ. Two overlapping active rulesets is a state where a future edit to one looks effective and is not. Fold it in and delete it, or rename it to say what it is for.

Why this is worth writing down rather than just doing

The prerequisite relationship runs the other way from how it looks: narrow automerge is only safe because this ruleset exists (see the separate issue), so weakening any of it later silently weakens that too.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions