Skip to content

feat(governance): add mirror-reusable.yml — consolidate 289-repo mirror.yml drift#187

Merged
hyperpolymath merged 1 commit into
mainfrom
feat/mirror-reusable
May 26, 2026
Merged

feat(governance): add mirror-reusable.yml — consolidate 289-repo mirror.yml drift#187
hyperpolymath merged 1 commit into
mainfrom
feat/mirror-reusable

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

Summary

Extends the reusable-workflow pattern from #168 (governance-reusable + deno-ci-reusable) and #174 (rust-ci-reusable + elixir-ci-reusable) to the mirror.yml template.

Estate audit picked this as the highest-leverage next foundational reusable across 5 candidates (codeql, secret-scanner, hypatia-scan, mirror, scorecard).

Drift survey

gh api /search/code paginated against org:hyperpolymath, then blob-SHA grouped:

Template Deployments Sampled Unique SHAs Top-SHA share
mirror.yml 289 100 76 (76%) 16% — long tail
codeql.yml 263 100 70 (70%) 32%
secret-scanner.yml 281 100 55 (55%) 47%
scorecard.yml 258 258 (full) 46 (18%) 39%
hypatia-scan.yml 255 200 31 (15.5%) 50%

(scorecard + hypatia-scan are already mostly converged → low leverage now.)

mirror.yml ranks first on drift × deployments (76% × 289 ≈ 220) and was verified to have low feature variance: all 4 top-SHA variants sampled (covering 29/100 sampled repos: bgp-backbone-lab, ipfs-overlay, kaldor-iiot, vcs-ircd) carried the same 7 forge jobs (gitlab, bitbucket, codeberg, sourcehut, disroot, gitea, radicle). Drift is action-SHA / whitespace churn — not feature variance — exactly the shape that consolidates cleanly behind one workflow_call reusable.

Design

  • No per-call inputs other than runs-on — per-repo forge selection already externalised to Actions vars vars._MIRROR_ENABLED == 'true', so the reusable mirrors the gating pattern verbatim.
  • secrets: inherit required at the call site — the per-forge SSH keys (GITLAB_SSH_KEY, BITBUCKET_SSH_KEY, CODEBERG_SSH_KEY, SOURCEHUT_SSH_KEY, DISROOT_SSH_KEY, GITEA_SSH_KEY) and RADICLE_KEY flow through implicitly. Without secrets: inherit the inner secrets.X references evaluate to empty (silent push failure on each enabled forge).
  • vars.GITEA_HOST consumed verbatim from the caller repo's Actions vars — same as the canonical mirror.yml.
  • All actions SHA-pinned; SPDX header present; top-level permissions: contents: read; passes the workflow-lint job in governance-reusable.yml.

No filtering logic, so no regression-test file (cf. scripts/tests/apply-baseline-test.sh for the governance/baseline path that needs one).

Caller wrapper shape (post-merge)

```yaml

SPDX-License-Identifier: PMPL-1.0-or-later

name: Mirror to Git Forges
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
jobs:
mirror:
uses: hyperpolymath/standards/.github/workflows/mirror-reusable.yml@
secrets: inherit
```

~10 lines per repo, replacing ~145 lines.

Rollout plan (downstream wrapper sweep)

NOT started in this PR — owner-gated, same as #174's rust-ci sweep (which capped at 82 PRs).

Numbers (from the 100-repo SHA-sample, extrapolated to 289):

  • 289 repos total deployments to convert
  • ~85% trivially convertible (forge set matches canonical 7-forge list; SHA-pinned actions only differ in pin SHA / whitespace). One mechanical wrapper PR per repo, same shape as the refactor(governance): subsume language-policy.yml + add deno-ci-reusable (semantics-level fix for estate-template drift) #168 wrappers (absolute-zero#41, tma-mark2#41).
  • ~10-15% need careful review — long-tail SHAs may include legitimate custom forges or local additions. Surface a per-repo diff during sweep; defer non-canonical variants to a follow-up.
  • Sweep order: pin wrappers to this PR's HEAD SHA while owner-gated; rebase to merged-main SHA in the wave's final batch (same protocol as the rust-ci sweep).

Pattern hardening (no per-PR action required)

🤖 Generated with Claude Code

…or.yml drift

Extends the #168/#174 reusable-workflow pattern. Estate audit (gh code
search + sampled blob hashes) found 289 deployments of mirror.yml with
76% SHA drift across a 100-repo sample; top SHA covers only 16% of
sampled repos. All four top variants carried the same 7 forge jobs —
the drift is action-SHA / whitespace churn, not feature variance — so
the workflow consolidates cleanly behind one `workflow_call` reusable.

Each forge job remains gated on the existing per-repo Actions variable
`vars.<FORGE>_MIRROR_ENABLED == 'true'`, so per-repo selection still
works without any per-call inputs. Callers use `secrets: inherit` so
the per-forge SSH keys (and RADICLE_KEY) flow through.

After merge, a downstream wrapper sweep can collapse each ~145-line
per-repo `mirror.yml` to a ~10-line wrapper that calls this reusable
— estimated reduction: ~145 LOC × 289 repos ≈ 42k lines, plus erases
the SHA-pin drift surface.
@github-actions
Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 118 issues detected

Severity Count
🔴 Critical 64
🟠 High 43
🟡 Medium 11

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Action hyperpolymath/standards/.github/workflows/deno-ci-reusable.yml@main needs attention",
    "type": "unpinned_action",
    "file": "deno-ci-reusable.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
    "type": "unpinned_action",
    "file": "governance-reusable.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
    "type": "unpinned_action",
    "file": "governance.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Python file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/standards/standards/a2ml-templates/state-scm-to-v2.py",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/standards/standards/a2ml/bindings/deno/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/standards/standards/lol/test/vitest.config.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/standards/standards/k9-svc/bindings/deno/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "Agda postulate assumes without proof -- potential soundness hole (4 occurrences, CWE-704)",
    "type": "agda_postulate",
    "file": "/home/runner/work/standards/standards/lol/proofs/theories/information_theory.agda",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "critical"
  },
  {
    "reason": "believe_me undermines formal verification (1 occurrences, CWE-704)",
    "type": "believe_me",
    "file": "/home/runner/work/standards/standards/lol/src/abi/Locale.idr",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "critical"
  },
  {
    "reason": "Wildcard CORS -- restrict to specific origins or use env var (1 occurrences, CWE-942)",
    "type": "js_wildcard_cors",
    "file": "/home/runner/work/standards/standards/consent-aware-http/examples/reference-implementations/deno/aibdp_middleware.js",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "high"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@hyperpolymath hyperpolymath enabled auto-merge (squash) May 26, 2026 10:04
@hyperpolymath hyperpolymath merged commit e6b2884 into main May 26, 2026
18 checks passed
@hyperpolymath hyperpolymath deleted the feat/mirror-reusable branch May 26, 2026 14:41
hyperpolymath added a commit that referenced this pull request May 26, 2026
…ecrets to 281 repos (#190)

## Summary

Extends the reusable-workflow pattern from #168 / #174 / #187 to
**secret-scanner.yml**. Same shape as #187 (no per-call inputs except
`runs-on`; caller uses `secrets: inherit`).

### Why secret-scanner is the next foundational reusable

Estate drift survey (`gh api /search/code` paginated against
`org:hyperpolymath`, blob-SHA grouped over **all 281 deployments**):

| Metric | Value |
|---|---|
| Total deployments | **281** |
| Unique blob SHAs | **54** |
| Structural drift | **19%** (top 4 SHAs cover 69%, top 6 cover 79%) |
| Feature variance | **near-zero** — all sampled variants carry the same
3 jobs (trufflehog + gitleaks + rust-secrets) at 75-81 lines |
| True drift source | action-SHA pin churn + whitespace |

The 100-sample drift estimate (55%) initially ranked secret-scanner
third behind mirror; the full pagination reveals the actual figure is
19%. The variance was a sampling artefact.

### Security debt this PR force-fixes

The `shell-secrets` job was added to the canonical 2026-05-21 (commit
`080c394`) in direct response to the **live Cloudflare API token leak**
via `avow-protocol/deploy-repos.sh` (commit `5f2f8b2`) — a leak that
both `trufflehog --only-verified` and default `gitleaks` missed.

Of 16 estate `secret-scanner.yml` blobs sampled across the top +
long-tail SHAs, **0 carry the `shell-secrets` job**.

The post-incident guardrail intended to catch the *next* such leak has
propagated to nothing. Consolidating the workflow behind this reusable
means the wrapper sweep that follows this PR force-promotes
`shell-secrets` to all 281 repos in one batch.

### Design

- **No per-call inputs other than `runs-on`** — each job self-conditions
internally:
  - `rust-secrets` exits early on no `Cargo.toml` (safe on every repo)
  - `shell-secrets` no-ops without `.sh`/`.bash` files
  - `trufflehog` + `gitleaks` always-on (intended)
- **`secrets: inherit` required at the call site** — so the inner
`secrets.GITHUB_TOKEN` reference in the `gitleaks-action` step resolves.
Without `inherit` it falls back to anonymous mode (rate-limited; misses
some PRs).
- **Caller keeps `on:` + `concurrency:`** — so the read-only
cancel-superseded guardrail stays in the wrapper.
- SPDX header, top-level `permissions: contents: read`, all actions
SHA-pinned — passes the `workflow-lint` job in
`governance-reusable.yml`.

### Caller wrapper shape (post-merge)

```yaml
# SPDX-License-Identifier: PMPL-1.0-or-later
name: Secret Scanner
on:
  pull_request:
  push:
    branches: [main]
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
permissions:
  contents: read
jobs:
  scan:
    uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@<sha>
    secrets: inherit
```

~12 lines per repo, replacing ~75-116 lines.

### Rollout plan

**NOT started in this PR — owner-gated, same as #187 / #174 sweeps.**

| Wave | Repos | Action |
|---|---|---|
| 1: bulk-mechanical | ~275 | Canonical 3-job match. Fan-out
single-commit wrapper PR per repo, pinned to this PR HEAD; rebase to
merged-main SHA before batch firing. |
| 2: slim variants | ~6 | Repos with 2-job (missing `rust-secrets`) or
1-job (`trufflehog` only) older copies. Standardize-up safely since the
missing job self-skips on non-applicable repos. |

Total expected sweep: ~281 PRs (well above the 82-PR rust-ci precedent —
recommend batching by wave; user gates each wave start).

### Pattern hardening

- Same `workflow_call` shape as #168 / #174 / #187 — no new
infrastructure.
- Independent of #174 (`rust-ci-reusable.yml`), #180
(`apply-baseline.sh` glob fix), and #187 (`mirror-reusable.yml`) — no
file conflicts; lands in any order.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant