docs(adr): propose a repository settings baseline by class#474
Open
ss-o wants to merge 6 commits into
Open
Conversation
Status PROPOSED. Changes no repository by itself. ADR-0009 declares a required, release-gating test suite for class-2 repositories. zsh-lint is class 2 and its default branch has no required status checks, no required reviews, and admins unenforced. The requirement is real policy enforced by nothing — the #464 pattern moved from CI to repository configuration. A survey of all 86 active public repositories found 75 with no rules at all on the default branch, and only two configured beyond a single rule. Those two disagree with each other, because no written standard exists: nothing in decisions, runbooks, or AGENTS.md mentions branch protection or rulesets, and the new-repository runbook never configures them. Organization-level rulesets would be the right mechanism but return 403 Upgrade to GitHub Team on the current plan, so per-repository configuration is the only option and drift is structural rather than accidental. That makes a declared baseline worth having. Records the costs honestly: required checks can deadlock, as wiki did this week; rules do not stop administrators; and enforce_admins is deliberately excluded because enabling it would have made that deadlock unrecoverable.
Contributor
There was a problem hiding this comment.
Pull request overview
Proposes a new ADR that defines a per-repository branch/ruleset settings baseline keyed to the org’s repository classes (ADR-0007), aiming to close gaps where declared policy exists but no repository configuration enforces it.
Changes:
- Add ADR-0013 documenting a settings baseline by repository class (required vs recommended settings).
- Document current-state findings (low adoption of protections/rulesets) and constraints (no org rulesets on current plan).
- Outline a staged rollout approach (ADR acceptance → update new-repo runbook → audit → gated apply).
Review feedback. The decision section said a ruleset is authoritative where both it and classic branch protection exist, contradicting the context section, which correctly states the effective rule is their union. The contradiction mattered: treating a ruleset as superseding classic protection is exactly the misreading that led to a wrong conclusion about wiki's main branch, where classic protection reports required_linear_history false while a ruleset enforces it. Neither system is authoritative. Both apply until classic protection is explicitly deleted, so an audit must read both sources and a repository counts as migrated only once the classic settings are removed.
Review feedback. decisions/ uses US spelling exclusively — behavior appears six times and behaviour none, organization eighteen times and organisation none. This ADR introduced the only two British spellings in the directory, which also makes the term harder to grep for.
Review feedback. The baseline table abbreviated three of the four class names — Deployed, Versioned and Meta against ADR-0007's Continuously deployed artifacts, Versioned tools and packages and Meta/infrastructure — which makes it easy to misread which class a row applies to. The four names now appear verbatim in a mapping above the table, with the columns keyed by number so the table stays narrow. Also drops the legend entry for a not-required symbol that no cell used, since it implied a distinction the baseline does not make.
Review feedback on subject-verb agreement. The quoted phrase named a table row, so singular agreement was defensible, but the sentence was ambiguous about whether it described the row or status checks in general. Naming the row explicitly removes the ambiguity instead of trading one reading for the other, and matches the following sentence, which already refers to rows.
Review feedback, and the claim was wrong rather than merely incomplete. Rollback was described as immediate because rulesets can be deleted. The baseline's first row is not a ruleset: renaming a default branch is not undone by deleting anything, GitHub's redirect does not update existing clones or references that name the branch in other repositories' workflows, documentation, or pinned uses: lines, and reverting means renaming back and repairing those references a second time. The row is now marked audit-only and excluded from any automated apply, the rollback section separates ruleset-expressed settings from the rename, and the irreversibility claim is scoped to what the audit actually applies. Only z-shell/web is non-conformant on that row, and it is called out as a deliberate one-off.
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.
Status PROPOSED. This changes no repository by itself — it declares the standard that a later audit would measure against.
The finding that prompted it
ADR-0009 states class-2 repositories have a test suite that is required and gates release tags.
z-shell/zsh-lintis class 2:{ "required_status_checks": null, "required_approving_review_count": 0, "enforce_admins": false }Declared policy, enforced by nothing. This is #464's pattern — documents describing a control that does not exist — moved from CI to repository configuration.
Survey of all 86 active public repositories
copilot_code_reviewzi,wiki)zi5,wiki1, all others 0masterz-shell/webThe two configured repositories do not agree with each other, which is expected: nothing in
decisions/,runbooks/, orAGENTS.mdmentions branch protection or rulesets, andrunbooks/new-repository.mdbootstraps labels, CI, and dependency automation without ever configuring protection.Why a per-repository baseline rather than central enforcement
An organization ruleset is the right mechanism and is what I would otherwise propose instead of this. It is unavailable on the current plan, and no custom properties are defined. Per-repository configuration is the only option, so drift is structural — which is the argument for declaring a baseline and measuring against it.
What the ADR deliberately does not do
labels-sync.rbpattern.enforce_admins. Enabling it would have made this week'swikideadlock unrecoverable: a required check whose failure could only be cleared by the merge it was blocking.Bypassed rule violationsand succeeds.Verification
Every factual claim was checked against the live API rather than asserted: the
zsh-lintprotection payload, the org-ruleset 403,webdefaulting tomaster, and thewikicase where classic protection reportsrequired_linear_history: falsewhile a ruleset enforces it on the same branch.Open question for review
The class table is the part most worth arguing with — particularly whether linear history should be required for class 1. It is what produced the
wikireconcile chore documented in #473, where the deployed branch diverges from the development branch after every promotion by construction. That cost may not be worth the benefit.