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
🤖 Generated with Claude Code
https://claude.ai/code/session_01Ji1bq3TypfycfUPAR7hSxR
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
hyperpolymath+metadatasticianUNKNOWN(unreadable)⚠ 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 returnedexactly 299 for
hyperpolymath— a silent truncation at the limit. Re-run at--limit 1000the true count is 456. The earlier 366 should not be used.The census was designed to mark private repos
UNKNOWN(neverCLEAN) if therulesets 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 isgenuinely clean under the filters (its branch ruleset is
disabled; its otherruleset targets tags). So
CLEANhere means measured-and-clean, notcould-not-look.
Scope filters (and why)
Only rulesets with
target = branchandenforcement = activearecounted.
updateis legitimate on a tag ruleset, so counting it estate-widewould be a false positive.
disabledruleset has no teeth and cannot block anything.Results
Positive control.
hyperpolymath/rsr-template-repois known-affected and wascarried 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_scanningatalerts_threshold: all.A. Retired rule types — 7 repos
These carry one or more of
code_quality,code_coverage,required_deployments,updateon an active branch ruleset. These are the fourtypes
scripts/plan-ruleset-constraint-repair.rblists asRETIRED.hyperpolymath/conative-gatingupdatehyperpolymath/-REPO-code_quality,code_coverage,required_deployments,code_scanning@allhyperpolymath/rsr-template-repocode_quality,code_coverage,code_scanning@allmetadatastician/burblecode_quality,code_coverage,code_scanning@all×2metadatastician/gossamercode_quality,code_coverage,required_deployments,code_scanning@all×2metadatastician/large-language-michelangelocode_quality,code_coverage,code_scanning@all×2metadatastician/_pathrootcode_quality,code_coverage,required_deployments,code_scanning@all×2(
×2means two separate active branch rulesets each contribute the flag.)Why
code_coverageandcode_qualitycannot be satisfied here. The bindingpipeline spec's coverage job uses no external coverage service — it appends a
markdown table to
$GITHUB_STEP_SUMMARY. Nothing is ever uploaded to GitHub, soa
minimum_coveragethreshold is unreachable by design. This is the vacuousgate's mirror image: a gate that can never say yes.
B.
code_scanningat thresholdall— 117 further reposalerts_threshold: allblocks a merge on any open alert of any severity,including
warningandnote. This is not retired and is not invalid — it is apolicy 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
allis the intendedseverity floor on 117 repos.
C. No rulesets at all — 2 repos
hyperpolymath/evil-weevilhyperpolymath/repo-guardianThese have no ruleset protection on any branch.
Method
Read-only script,
GETonly, one repo per iteration (noforloop — the shapeis denied by policy), carrying the positive control described above. Per repo:
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
what mechanism. Note that
scripts/plan-ruleset-constraint-repair.rbrefuses to plan a repair for a repo with no
pull_requestrule(
ArgumentError: Missing pull-request protection) — see rsr-template-repo: no ruleset requires pull requests on any branch #1003. That guardis correct; the cure is to add the missing protection, not bypass it.
code_scanningalerts_threshold: allis theintended severity floor across 117 repos, or should be trimmed.
evil-weevilandrepo-guardianshould havebranch protection at all.
PUTbodies that bypass the planner's precondition.🤖 Generated with Claude Code
https://claude.ai/code/session_01Ji1bq3TypfycfUPAR7hSxR