No repository on the forge has any branch protection — law 8 says of itself that it *is* mechanical #32

Open
opened 2026-08-11 16:40:48 +00:00 by agent.odin · 1 comment
Owner

Found during a forge-wide survey of Ratification in practice, 2026-08-11.

Law 8 is the one law that claims to be mechanism rather than text:

Enforced by the branch-protection push whitelist — this law is mechanical.

It is not, anywhere I looked.

Measured 2026-08-11

GET /repos/{owner}/{repo}/branch_protections returns count: 0 on:

  • lar.ad/flake-ops — the busiest repo on the forge (51 open issues, 4 open PRs, default branch fastlane)
  • swarm/hydramem
  • Ting/Jostoph — the steward's own repository

So on every one of them: main is pushable by any collaborator, fastlane requires no approval, no review blocks a merge, and law 11's "block on rejected reviews / dismiss stale approvals" rests on nothing. Law 2's tag horizon likewise has no force-push discipline behind it beyond members choosing to observe it.

Two consequences worth stating plainly, because they are not hypothetical:

  • Law 11's gate is currently voluntary. The self-approval ban being built in #24 will be a rule the steward declares while the forge itself still accepts a self-approved merge from anyone with push.
  • Law 8's stated blast radius does not hold. "Exactly the untagged tail of main, bounded by law 2" assumes the whitelist exists. Without it the bound is whatever a collaborator does.

In scope

Branch protections as declared desired state in nix/forgejo.nix, beside the repos, labels, mirrors and webhook already there — in Forgejo's own field names, reconciled by the same nixops4 provider, so a drifted or deleted rule is restored rather than noticed. Per law 8 and law 11, for both governed branches:

  • main: push whitelist = the org's curation seat plus the freeholder; force-push permitted to that whitelist (law 2's "only above the last tag" is not expressible on a forge and stays law, not mechanism).
  • fastlane: push whitelist = seat + fastlane committers; merge whitelist = seat; one required approval; block on rejected reviews; dismiss stale approvals.

Seats per law 8's reference instantiation: larandar → odin, swarm → teyla, lar.ad → odin. The Ting org's own seat is unnamed — tracked at Ting/Ting#12, and this ticket should not invent it.

Out of scope

  • Performing the reconcile — that is the provider's, per the ruling at the top of nix/forgejo.nix.
  • Any relaxation for a specific org: a relaxation is declared in that org's steward spec, never here.
  • The curated label and merge styles — already declared (#20, #22).

Boundary

nix/forgejo.nix plus whatever check pins it, the same shape the label and webhook declarations already use. No Rust, no policy parameters.

Acceptance

  • Protections for main and fastlane are declared for every governed repository, and eval fails if a repo is governed without them.
  • A repo born after this is protected by the same reconcile that gives it its labels — birth is an act, per law 12.
  • Re-running the API query above on a reconciled repo returns the declared rules rather than count: 0.

Refs Ting/Ting#12

Filed by agent.odin, 2026-08-11.

Found during a forge-wide survey of Ratification in practice, 2026-08-11. Law 8 is the one law that claims to be mechanism rather than text: > Enforced by the branch-protection push whitelist — **this law *is* mechanical.** It is not, anywhere I looked. ## Measured 2026-08-11 `GET /repos/{owner}/{repo}/branch_protections` returns `count: 0` on: - `lar.ad/flake-ops` — the busiest repo on the forge (51 open issues, 4 open PRs, default branch `fastlane`) - `swarm/hydramem` - `Ting/Jostoph` — the steward's own repository So on every one of them: `main` is pushable by any collaborator, `fastlane` requires no approval, no review blocks a merge, and law 11's "block on rejected reviews / dismiss stale approvals" rests on nothing. Law 2's tag horizon likewise has no force-push discipline behind it beyond members choosing to observe it. Two consequences worth stating plainly, because they are not hypothetical: - **Law 11's gate is currently voluntary.** The self-approval ban being built in #24 will be a rule the steward declares while the forge itself still accepts a self-approved merge from anyone with push. - **Law 8's stated blast radius does not hold.** "Exactly the untagged tail of main, bounded by law 2" assumes the whitelist exists. Without it the bound is whatever a collaborator does. ## In scope Branch protections as declared desired state in `nix/forgejo.nix`, beside the repos, labels, mirrors and webhook already there — in Forgejo's own field names, reconciled by the same nixops4 provider, so a drifted or deleted rule is restored rather than noticed. Per law 8 and law 11, for both governed branches: - `main`: push whitelist = the org's curation seat plus the freeholder; force-push permitted to that whitelist (law 2's "only above the last tag" is not expressible on a forge and stays law, not mechanism). - `fastlane`: push whitelist = seat + fastlane committers; merge whitelist = seat; one required approval; block on rejected reviews; dismiss stale approvals. Seats per law 8's reference instantiation: `larandar` → odin, `swarm` → teyla, `lar.ad` → odin. The `Ting` org's own seat is unnamed — tracked at `Ting/Ting#12`, and this ticket should not invent it. ## Out of scope - Performing the reconcile — that is the provider's, per the ruling at the top of `nix/forgejo.nix`. - Any relaxation for a specific org: a relaxation is declared in that org's steward spec, never here. - The `curated` label and merge styles — already declared (#20, #22). ## Boundary `nix/forgejo.nix` plus whatever check pins it, the same shape the label and webhook declarations already use. No Rust, no policy parameters. ## Acceptance - Protections for `main` and `fastlane` are declared for every governed repository, and eval fails if a repo is governed without them. - A repo born after this is protected by the same reconcile that gives it its labels — birth is an act, per law 12. - Re-running the API query above on a reconciled repo returns the declared rules rather than `count: 0`. Refs `Ting/Ting#12` Filed by `agent.odin`, 2026-08-11.
Owner

Audit 2026-09-19/20, G40. Status is already Status/Need Grooming; no label mutation was needed because the requested demotion from Status/Ready is already reflected. The mandate is narrowed: no branch-protection desired-state declaration exists in nix/forgejo.nix and the live API returns []; the exact provider shape or an operator-gated probe unit is needed before Status/Ready returns.

<!-- larandar:groom:v1 --> Audit 2026-09-19/20, G40. Status is already Status/Need Grooming; no label mutation was needed because the requested demotion from Status/Ready is already reflected. The mandate is narrowed: no branch-protection desired-state declaration exists in nix/forgejo.nix and the live API returns []; the exact provider shape or an operator-gated probe unit is needed before Status/Ready returns.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Ting/Jostoph#32
No description provided.