fix(governance-reusable): pin standards self-checkout to main (workflow_sha was caller-SHA)#219
Merged
Conversation
…ow_sha resolves to caller, not standards)
The `Check out standards repo for shared scripts` step in governance-reusable.yml
used `ref: ${{ github.workflow_sha }}`, on the (incorrect) assumption that
`github.workflow_sha` would resolve to the SHA of the reusable workflow YAML
itself. In a reusable-workflow context it actually resolves to the *caller
repo's* commit SHA — so every governance run was issuing:
git fetch origin <caller-SHA>
inside a clone of hyperpolymath/standards, where that SHA does not exist.
After three retries the checkout fails with exit code 128, and downstream
governance jobs (Language / package anti-pattern policy, etc.) never run.
Symptom across the estate: gossamer#59 governance / Language / package anti-pattern
policy "Failing after ~40s" on every PR, with the underlying log line:
The process '/usr/bin/git' failed with exit code 128
verified for SHA 67241f8b650db4feb70b5f2d23342c20bae4b0c4 (a gossamer PR-merge
commit, not present in standards). Probing the same SHA in standards directly:
$ gh api repos/hyperpolymath/standards/commits/67241f8b6...
No commit found for SHA (HTTP 422)
Fix: pin `ref: main`. Caller repos already pin the reusable workflow YAML by
SHA, so script-version drift is bounded to "whatever's on standards/main when
the reusable resolves" — acceptable since these are read-only governance
checks and standards/main is protected.
Refs: hypatia rule-additions will follow in a separate PR so this can land fast.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
🔍 Hypatia Security ScanFindings: 123 issues detected
View findings[
{
"reason": "Action hyperpolymath/standards/.github/workflows/changelog-reusable.yml@main needs attention",
"type": "unpinned_action",
"file": "changelog-reusable.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"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/elixir-ci-reusable.yml@main needs attention",
"type": "unpinned_action",
"file": "elixir-ci-reusable.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Action hyperpolymath/standards/.github/workflows/elixir-ci-reusable.yml@main needs attention",
"type": "unpinned_action",
"file": "elixir-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": "Action hyperpolymath/standards/.github/workflows/rust-ci-reusable.yml@main needs attention",
"type": "unpinned_action",
"file": "rust-ci-reusable.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Action hyperpolymath/standards/.github/workflows/rust-ci-reusable.yml@main needs attention",
"type": "unpinned_action",
"file": "rust-ci-reusable.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"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
This was referenced May 27, 2026
hyperpolymath
added a commit
to hyperpolymath/absolute-zero
that referenced
this pull request
May 27, 2026
## Root cause `.github/workflows/governance.yml:34` pins `governance-reusable.yml@3ec2e85` (2026-05-25) — predates [standards#219](hyperpolymath/standards#219) (`ad366b6`, 2026-05-27) which fixes `workflow_sha` resolution. Without this fix, `governance / Language / package anti-pattern policy` fails with exit 128 on the inner self-checkout. ## Pins changed | File | Before | After | |---|---|---| | `.github/workflows/governance.yml:34` | `3ec2e85` (pre-#219) | `5eb28d7` (standards/main, post-#219) | | `.github/workflows/hypatia-scan.yml:28` | `97df762` (orphan PR-branch SHA) | `5eb28d7` (canonical main; file unchanged since #193) | ## Auto-merge SQUASH. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath
added a commit
to hyperpolymath/hypatia
that referenced
this pull request
May 27, 2026
## Root-cause summary `governance / Language / package anti-pattern policy` has been failing on hypatia/main (and on every open PR) because: - `.github/workflows/governance.yml:34` pinned `governance-reusable.yml@66271d3` (2026-05-22) — predates [hyperpolymath/standards#219](hyperpolymath/standards#219) (merged `ad366b6`, 2026-05-27). - standards#219 fixes a `workflow_sha` resolution bug: in a reusable workflow, `github.workflow_sha` resolves to the **caller's** SHA, not the reusable's SHA. The inner self-checkout of `hyperpolymath/standards` therefore asked the standards repo for a SHA that only exists in hypatia → `exit 128` after 3 retries. This PR bumps both standards-reusable pins past that fix. ## Pins changed | File | Before | After | |---|---|---| | `.github/workflows/governance.yml:34` | `66271d3...` (2026-05-22) | `5eb28d7d8790d5389b7b6a5233fe6265a775e3d0` (standards/main, 2026-05-27) | | `.github/workflows/hypatia-scan.yml:28` | `97df762...` (orphan SHA on PR-branch for #193) | `5eb28d7d8790d5389b7b6a5233fe6265a775e3d0` (canonical main) | ## Delta picked up (governance side) 7 commits, all fixes / hardening: - `ad366b6` `fix(governance-reusable): pin standards self-checkout to main` (#219) **— the load-bearing fix** - `481c496` `feat(governance): add check-trusted-base CI enforcement` (#211) - `0ec0b83` `fix(governance): eradicate inline Python from governance-reusable.yml` (#189) - `3285ac1` `fix(baseline): file_pattern glob matching + jq scoping bugs` (#180) - `431adbb` `refactor(governance): subsume language-policy.yml + add deno-ci-reusable` (#168) - `91d8b88` `feat: consume .hypatia-baseline.json in governance gate` (#166) - `43b6563` `fix: checkout caller's repo in governance-reusable workflow` Delta on hypatia-scan side: **none** (reusable file unchanged since #193 squash-merge). ## Estate implication This same stale-pin pattern affects every repo whose `governance.yml` wrapper points to a pre-`ad366b6` SHA of `governance-reusable.yml`. An estate-wide fan-out bump-PR sweep is the comprehensive remedy (cf. session memory on the doomed-CI pilot). This PR is the per-repo first cut for hypatia. ## Auto-merge SQUASH (per estate policy). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath
added a commit
to hyperpolymath/echidna
that referenced
this pull request
May 27, 2026
## Root cause `.github/workflows/governance.yml:34` pins `governance-reusable.yml@128a854` (2026-05-20) — predates [standards#219](hyperpolymath/standards#219) (`ad366b6`, 2026-05-27) which fixes `workflow_sha` resolution. Without this fix, `governance / Language / package anti-pattern policy` fails with exit 128 on the inner self-checkout. ## Pin changed | File | Before | After | |---|---|---| | `.github/workflows/governance.yml:34` | `128a854` (pre-#219) | `5eb28d7` (standards/main, post-#219) | ## Auto-merge SQUASH. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath
added a commit
to hyperpolymath/hypatia
that referenced
this pull request
May 27, 2026
…ti-pattern (#348) ## Summary Two specific, sensitive checks in \`Hypatia.Rules.WorkflowAudit\`: | Rule | When it fires | Severity | |---|---|---| | \`:workflow_sha_as_foreign_ref\` | \`actions/checkout\` uses \`ref: \${{ github.workflow_sha }}\` against a \`repository:\` value that is not \`\${{ github.repository }}\` | :critical | | \`:reusable_caller_context_self_checkout\` | In a reusable workflow (\`on: workflow_call\`), \`actions/checkout\` of a literal foreign repo at \`ref:\` = any caller-context variable (\`github.ref\` / \`head_ref\` / \`sha\` / \`workflow_sha\`) | :critical | ## Why this rule pair \`github.workflow_sha\` (and \`github.ref\`, \`head_ref\`, \`sha\`) all resolve to the **caller repo's** value, never to the SHA of the reusable workflow itself. Passing them as \`ref:\` to \`actions/checkout\` of a *foreign* repository asks that repo for a SHA / branch that doesn't exist — \`git fetch\` exits with code 128, three retries, then the step (and downstream jobs) fail. This is the exact bug shipped in \`hyperpolymath/standards#219\`'s pre-fix \`governance-reusable.yml:155\`, which cascaded into governance failures across hundreds of stuck PRs estate-wide on 2026-05-26 — symptom \"governance / Language / package anti-pattern policy — Failing after 40s\" on every PR. ## Design notes ### Sensitivity (catches the bug) - Both rules use a YAML step-splitter (line-walker that respects indent) instead of a multi-line regex, so they handle both \`actions/checkout\` step shapes: - \`- uses: actions/checkout@…\` (uses-first) - \`- name: … / uses: actions/checkout@…\` (name-first) - Verified against the verbatim pre-fix \`governance-reusable.yml\` body — both rules fire. ### Specificity (low false-positive rate) - Rule 1 does **not** fire when \`repository: \${{ github.repository }}\` (the safe caller-self pattern shipped in many workflows). - Rule 2 does **not** fire on non-reusable workflows (no \`workflow_call:\`) or when \`ref:\` is pinned to a literal value (\`main\`, \`v1.2.0\`, or an explicit SHA). - Verified against the post-fix \`governance-reusable.yml\` (\`ref: main\`) — both rules stay quiet. ### Why two rules, not one - Rule 1 is the narrowest cut against the specific \`workflow_sha\` mistake — high signal, zero false positives expected. - Rule 2 is the broader anti-pattern: a reusable that puts ANY caller-context ref against a foreign \`repository:\`. Catches the cousin bugs (\`github.ref\` or \`github.sha\` used the same wrong way) that the standards PR fix did not need to address but Hypatia should still warn on. ## Test plan - [x] \`mix test test/workflow_audit_test.exs\` — 12 new test cases (4 + 5 + 3) covering positive firing, negative firing, and the two checkout step shapes. - [x] Standalone smoke (10 assertions) covering both pre-fix and post-fix \`governance-reusable.yml\` shapes — see PR body of standards#219 for source. - [ ] After merge: re-run Hypatia scan against \`hyperpolymath/standards\` post-PR-219 and confirm neither rule fires (it shouldn't — \`ref: main\` is the safe shape). - [ ] Estate sweep: run Hypatia against the rest of \`hyperpolymath/standards/.github/workflows/*-reusable.yml\` to confirm no other reusables carry the same anti-pattern. (I scanned manually and found only \`governance-reusable.yml\` — no false positives expected, but worth confirming through the production scanner path.) ## Related - \`hyperpolymath/standards#219\` — source-of-truth fix that unblocks the stuck-PR cascade. - The orthogonal CodeQL js-ts failure on \`.git-private-farm#24\` is a GitHub Actions billing/spending-limit block — not a Hypatia-detectable anti-pattern, just owner-action in Settings → Billing & plans. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath
added a commit
to hyperpolymath/hypatia
that referenced
this pull request
May 27, 2026
…5-27 audit (#350) ## Summary The 2026-05-27 estate doomed-CI audit produced deletion PRs for 5 pilot repos (`road-skate`, `vext`, `quandledb`, `absolute-zero`, `Axiom.jl`). Three of the underlying anti-patterns had no Hypatia coverage, or had coverage too weak to drive action. This PR closes those gaps in \`Hypatia.Rules.CicdRules\`. | Track | Before | After | |---|---|---| | A1 — Jekyll on non-Pages | \`:irrelevant_jekyll\` at \`:low\` (ignored) | bumped to \`:medium\` (acted on) | | C — Subsumed standalone beside \`governance.yml\` | none (just a comment) | new \`:redundant_subsumed_standalone\` at \`:medium\` | | D — \`rust-ci.yml\` on no-Rust repo | only the inverse (\`:missing_rust_ci\`) | new \`:irrelevant_rust_ci\` at \`:high\` | ## Why (1) **Severity bump for \`:irrelevant_jekyll\`** — the existing detection (no \`_config.yml\` AND no \`Gemfile\`) is accurate, but \`:low\` meant it never made it onto any actionable backlog. Estate language policy bans Jekyll outright in favour of \`hyperpolymath/casket-ssg\`, so when the rule fires the finding is unambiguously a delete candidate. 21 of 25 Jekyll-workflow repos in the estate fire this rule. (2) **\`:redundant_subsumed_standalone\`** — fires for any of the 9 standalone workflow names whose logic is provided by \`hyperpolymath/standards/.github/workflows/governance-reusable.yml\` when \`governance.yml\` is also present: \`\`\` workflow-linter.yml, language-policy.yml, quality.yml, security-policy.yml, guix-nix-policy.yml, npm-bun-blocker.yml, ts-blocker.yml, rsr-antipattern.yml, wellknown-enforcement.yml \`\`\` Authoritative subsumption list per the reusable's own header. Audit found 107 instances across 88 repos. \`workflow-linter.yml\` alone is in 80 repos. (3) **\`:irrelevant_rust_ci\`** — fires when \`rust-ci.yml\` exists but the repo has no \`Cargo.toml\` at root AND no \`*.rs\` files anywhere (workspace check via \`rs_file_count\` or extension scan). Cousin of \`:missing_rust_ci\` (which catches the inverse). Audit found 11 doomed cases. ## Validation 8/8 standalone smoke assertions pass: - \`:redundant_subsumed_standalone\` fires on \`workflow-linter.yml + governance.yml\` - \`:redundant_subsumed_standalone\` fires on \`quality.yml + governance.yml\` - \`:redundant_subsumed_standalone\` count matches subsumed names present - silent without \`governance.yml\` (so vintage repos still on standalones don't get pinged) - \`:irrelevant_rust_ci\` fires when no \`Cargo.toml\` + no \`.rs\` - silent when \`Cargo.toml\` present - silent on workspace layouts (\`rs_file_count > 0\`) - \`:irrelevant_jekyll\` severity is now \`:medium\` ## Related - \`hyperpolymath/standards#219\` — the root-cause fix for the governance-reusable \`workflow_sha\` bug that triggered the audit. - \`#348\` — sibling rules for the \`workflow_sha\` / caller-context-\`ref\` anti-patterns (one PR over from this one in time). - Pilot deletion PRs validated against the existing rules: road-skate#1 (MERGED), vext#11, quandledb#16, absolute-zero#57, Axiom.jl#29. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
governance-reusable.yml:155usedref: ${{ github.workflow_sha }}for the inneractions/checkoutofhyperpolymath/standardsinto.standards-checkout/.github.workflow_sharesolves to the caller repo's commit SHA, not the SHA of the reusable workflow file in this repo. The fetch therefore asks the standards repo for a SHA that lives in the caller —exit code 128after three retries.governance / Language / package anti-pattern policy(and any other job in the same workflow that depends on.standards-checkout/) fails on every governance run across the estate.ref: maininstead. Caller repos already pin the reusable's YAML by SHA, so script-version drift is bounded to standards/main between the YAML pin and the script pin — acceptable because these scripts are read-only governance checks and standards/main is protected.Evidence
From gossamer#59 governance run (https://github.com/hyperpolymath/gossamer/actions/runs/26459402802):
gh api repos/hyperpolymath/standards/commits/67241f8b6...→ 422 No commit found for SHA.gh api repos/hyperpolymath/gossamer/commits/67241f8b6...→ exists; it is the PR-merge commit for gossamer#59 (Merge 5b35d61f... into dd3a50a...).This is exactly the symptom the estate has been observing as "Governance / governance / Language / package anti-pattern policy — Failing after 40s" across every open PR.
Why this is the right fix
github.workflow_shais documented as the trigger commit of the caller, and nogithub.action_*context applies to reusable workflows.inputs.standards_refwas considered but rejected: every wrapper across the estate would need to thread it through, and the default would bemainanyway.mainis protected and rebases are not part of normal flow here, so the failure mode "standards/main is gone" is not realistic.Test plan
governance / Language / package anti-pattern policyresolves to SUCCESS.github.workflow_shaasref:foractions/checkoutof a non-caller repo) will follow in a separate PR.Related
.git-private-farm) also has a GitHub Actions spending-limit block that owner needs to clear in Settings → Billing & plans — out of scope for this PR.🤖 Generated with Claude Code