diff --git a/config/README.adoc b/config/README.adoc index 98ed848c2..ff4110314 100644 --- a/config/README.adoc +++ b/config/README.adoc @@ -175,8 +175,17 @@ REST API. standing push right. | Integration ids 56611 (codacy), 827041 (gitar-bot), 254 (codecov), 2740 (renovate), 57789 (advanced-security), 1561, 85455, 946600 -| R1/R4 removals, advanced-security needs no bypass, the last three are - unresolved (owner decision O5). +| R1/R4 removals, advanced-security needs no bypass. Re-swept 2026-09-20 across + all 453 repos: no active ruleset grants bypass to any uninstalled app. 1561 and + 85455 have no matching app in either estate; both survive only on ONE disabled + repo ruleset (`anvomidaviser/Optimus-Branch`), which also still grants `always` + bypass to RepositoryRole 2 (maintain) and keeps `code_coverage` / + `required_deployments` / `copilot_code_review` — the exact set §7.3 retired, so + that stale ruleset should be deleted rather than re-enabled. 946600 = Codex MCP + (GitHub), on 67 repo rulesets (17 hyperpolymath, 50 metadatastician); owner + decision O5 stays open. + Note `123` (codecov PR gate) was never a bypass actor — it only ever appears as + a jtv-lang required-check context, which is the §11.3 hand-typed-context bug. |=== Kept: `deletion`, `non_fast_forward`, `required_signatures`, `pull_request` @@ -279,3 +288,23 @@ because 300 repos carrying a harmless `PROV-` is not worth 300 API writes. . tag ruleset . verifier: identity rule, phantom contexts = 0, live ≡ canonical . allowlist — *tail of the sweep only* + +== Tailscale and GitHub + +There is no Tailscale GitHub App: `GET https://api.github.com/apps/tailscale` returns +404, and Tailscale's own integration for GitHub is the +`tailscale/github-action` Action plus a Tailscale OAuth client. So "install Tailscale +as an app on the org" is not an action that exists; the estate equivalent is: + +1. `tailscale/github-action@*` is on the Actions allowlist (both + `config/settings/actions-allowlist.json` and + `rhodium-standard-repositories/actions-allowlist/allowed-actions.json`). +2. `.github/workflows/tailscale-connect-reusable.yml` in this repo provides the + connect job; `metadatastician/.github` carries the org-level copy so repos can + `uses: metadatastician/.github/.github/workflows/...@main`. +3. Secrets `TS_OAUTH_CLIENT_ID` / `TS_OAUTH_SECRET` are created by the owner: org-level + for metadatastician (Settings → Secrets and variables → Actions), per-repository for + the `hyperpolymath` account, which has no org-level secrets on the free plan. +4. Repos that need tailnet reachability opt in per workflow. Nothing here changes CI + for repos that do not call it, which is deliberate: a connect step without the + secrets fails the job. diff --git a/rhodium-standard-repositories/satellites/rsr-certifier/engine/src/compliance/gold.rs b/rhodium-standard-repositories/satellites/rsr-certifier/engine/src/compliance/gold.rs index c7072116c..613ddbee7 100644 --- a/rhodium-standard-repositories/satellites/rsr-certifier/engine/src/compliance/gold.rs +++ b/rhodium-standard-repositories/satellites/rsr-certifier/engine/src/compliance/gold.rs @@ -145,8 +145,6 @@ impl ComplianceCheck for TestCoverageCheck { // Check for coverage configuration let coverage_configs = [ - "codecov.yml", - ".codecov.yml", "coveralls.yml", ".coveragerc", "coverage.json", @@ -177,7 +175,7 @@ impl ComplianceCheck for TestCoverageCheck { if let Ok(entries) = std::fs::read_dir(full_path) { for entry in entries.flatten() { if let Ok(content) = std::fs::read_to_string(entry.path()) { - if content.contains("coverage") || content.contains("codecov") { + if content.contains("coverage") { has_coverage = true; break; } @@ -210,7 +208,7 @@ impl ComplianceCheck for TestCoverageCheck { tier: self.tier(), passed: false, message: "Tests found but no coverage configuration".to_string(), - details: Some("Add coverage reporting (codecov, coveralls, etc.)".to_string()), + details: Some("Add coverage reporting (tarpaulin, llvm-cov, coverage.py, etc.)".to_string()), }) } else { Ok(CheckResult { @@ -226,7 +224,7 @@ impl ComplianceCheck for TestCoverageCheck { async fn check_remote(&self, contents: &RepoContents) -> Result { let test_patterns = ["test", "tests", "spec", "__tests__"]; - let coverage_patterns = ["codecov", "coverage", "coveralls"]; + let coverage_patterns = ["coverage", "coveralls"]; let has_tests = contents.files.iter().any(|f| { let path_lower = f.path.to_lowercase();