Skip to content

Estate census: 124 of 456 repos carry retired or unsatisfiable ruleset rules (report only) #1004

Description

@hyperpolymath

Estate census: ruleset rules that are retired or cannot be satisfied

Owner ruling for this work was census the estate, report only. No ruleset was
written, updated or deleted. Every call was a GET.

Denominator

Count
Non-archived repos across hyperpolymath + metadatastician 456 (389 + 67)
Rows measured 456
Rows UNKNOWN (unreadable) 0

⚠ A correction to an earlier figure. An earlier pass reported the estate as
366 repos. That number came from gh repo list --limit 300, which returned
exactly 299 for hyperpolymath — a silent truncation at the limit. Re-run at
--limit 1000 the true count is 456. The earlier 366 should not be used.

The census was designed to mark private repos UNKNOWN (never CLEAN) if the
rulesets endpoint returned 403. In practice zero rows were UNKNOWN, because
the credential can read private rulesets — verified directly against a private
repo scored CLEAN: HTTP/2.0 200 OK, 2 rulesets returned. That repo is
genuinely clean under the filters (its branch ruleset is disabled; its other
ruleset targets tags). So CLEAN here means measured-and-clean, not
could-not-look.

Scope filters (and why)

Only rulesets with target = branch and enforcement = active are
counted.

  • update is legitimate on a tag ruleset, so counting it estate-wide
    would be a false positive.
  • A disabled ruleset has no teeth and cannot block anything.

Results

Verdict Repos
CLEAN 330
AFFECTED 124
NO_RULESETS 2

Positive control. hyperpolymath/rsr-template-repo is known-affected and was
carried through the run as a known-answer control. It is reported AFFECTED.
Had it come back CLEAN, every clean verdict in this table would be worthless.

The two populations are very different

Of the 124 AFFECTED, only 7 carry a genuinely retired rule type. The other
117 are affected solely by code_scanning at alerts_threshold: all.

A. Retired rule types — 7 repos

These carry one or more of code_quality, code_coverage,
required_deployments, update on an active branch ruleset. These are the four
types scripts/plan-ruleset-constraint-repair.rb lists as RETIRED.

Repo Private Retired/unsatisfiable rules present
hyperpolymath/conative-gating no update
hyperpolymath/-REPO- yes code_quality, code_coverage, required_deployments, code_scanning@all
hyperpolymath/rsr-template-repo no code_quality, code_coverage, code_scanning@all
metadatastician/burble no code_quality, code_coverage, code_scanning@all ×2
metadatastician/gossamer no code_quality, code_coverage, required_deployments, code_scanning@all ×2
metadatastician/large-language-michelangelo no code_quality, code_coverage, code_scanning@all ×2
metadatastician/_pathroot no code_quality, code_coverage, required_deployments, code_scanning@all ×2

(×2 means two separate active branch rulesets each contribute the flag.)

Why code_coverage and code_quality cannot be satisfied here. The binding
pipeline spec's coverage job uses no external coverage service — it appends a
markdown table to $GITHUB_STEP_SUMMARY. Nothing is ever uploaded to GitHub, so
a minimum_coverage threshold is unreachable by design. This is the vacuous
gate's mirror image: a gate that can never say yes.

B. code_scanning at threshold all — 117 further repos

alerts_threshold: all blocks a merge on any open alert of any severity,
including warning and note. This is not retired and is not invalid — it is a
policy choice — but at this threshold it will block merges on advisory findings
rather than on real defects, across a quarter of the estate.

This is flagged, not condemned. A gate that blocks on real findings is
working as intended; the question for the owner is whether all is the intended
severity floor on 117 repos.

C. No rulesets at all — 2 repos

Repo Private
hyperpolymath/evil-weevil yes
hyperpolymath/repo-guardian no

These have no ruleset protection on any branch.

Method

Read-only script, GET only, one repo per iteration (no for loop — the shape
is denied by policy), carrying the positive control described above. Per repo:

gh api "repos/$slug/rulesets"                # list
gh api "repos/$slug/rulesets/$id"            # detail, per ruleset
  -> skip unless .enforcement == "active"
  -> skip unless .target      == "branch"
  -> collect [.rules[]?.type]
  -> flag code_scanning where any
     .parameters.code_scanning_tools[].alerts_threshold == "all"

Output rows: slug <TAB> {UNKNOWN|NO_RULESETS|CLEAN|AFFECTED} <TAB> private=… <TAB> flags <TAB> all-rule-types.
No duplicate slugs were emitted (checked with cut -f1 | sort | uniq -d).

Acceptance criteria

  • Owner decides whether the 7 retired-rule repos should be repaired, and by
    what mechanism. Note that scripts/plan-ruleset-constraint-repair.rb
    refuses to plan a repair for a repo with no pull_request rule
    (ArgumentError: Missing pull-request protection) — see rsr-template-repo: no ruleset requires pull requests on any branch #1003. That guard
    is correct; the cure is to add the missing protection, not bypass it.
  • Owner decides whether code_scanning alerts_threshold: all is the
    intended severity floor across 117 repos, or should be trimmed.
  • Owner decides whether evil-weevil and repo-guardian should have
    branch protection at all.
  • Any repair is applied by a sanctioned, tested applier — not by hand-crafted
    PUT bodies that bypass the planner's precondition.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Ji1bq3TypfycfUPAR7hSxR

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

    governancePolicy, rulesets, standards, compliance, and their enforcementpriority:p3Low - nice to haverefactorRestructuring that preserves observable behaviourscope:estateAffects many or all repos across the estatestatus:readyFully specified and ready to be picked up

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions