fix(ci): green the two failing governance jobs (SPDX, action pins, reusable staleness)#292
Merged
Conversation
…cer.yml Two of the governance gate's failures, both surfaced only after the repository's Actions policy was fixed (the workflows previously startup_failure'd before any job could run). Workflow security linter ERROR: .github/workflows/pages.yml missing SPDX header pages.yml is the active Ddraig SSG docs deploy added in #288; it was the only workflow of 26 without the header. Added, matching the form used by proofs.yml. Not deleted — it is live, and pages-deploy.yml is a different thing (Cloudflare Workers, not GitHub Pages). Check Workflow Staleness ERROR: scorecard-enforcer.yml is retired. Use scorecard.yml -> standards scorecard-reusable.yml instead. Removed. The replacement scorecard.yml is present. This also clears the separate `OpenSSF Scorecard Enforcer` run failure. Confirmed safe to delete: the Base ruleset (14285163) requires only `Dependabot`, `Hypatia Neurosymbolic Analysis` and `Hypatia`, so removing this workflow cannot strand a PR on a permanently-"Expected" required check. Deliberately NOT addressed here — the staleness gate's two remaining complaints both concern shared CI fate and want coordination, not a drive-by fix: - governance-reusable.yml / scorecard-reusable.yml pin d135b05bfc64 is 75 commits / 26d behind standards HEAD (refresh toward 8813ecf2a841). Re-pinning consumers changes behaviour estate-wide, and at least one reusable (secret-scanner) is known not to inherit its config to callers. - OSSF Scorecard uploading SARIF to Code Scanning while not running for every PR head commit. Verified locally by replicating the linter's own check across all 25 remaining workflows: every one carries an SPDX header and a top-level `permissions:`. pages.yml still parses as valid YAML. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
| @@ -1,3 +1,8 @@ | |||
| # SPDX-License-Identifier: MPL-2.0 | |||
| @@ -1,3 +1,8 @@ | |||
| # SPDX-License-Identifier: MPL-2.0 | |||
| @@ -1,3 +1,8 @@ | |||
| # SPDX-License-Identifier: MPL-2.0 | |||
| @@ -1,3 +1,8 @@ | |||
| # SPDX-License-Identifier: MPL-2.0 | |||
🔍 Hypatia Security ScanFindings: 226 issues detected
View findings[
{
"reason": "Action actions/checkout@v4 needs attention",
"type": "unpinned_action",
"file": "pages-deploy.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action actions/checkout@v4 needs attention",
"type": "unpinned_action",
"file": "pages.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action actions/checkout@v4 needs attention",
"type": "unpinned_action",
"file": "pages.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action actions/upload-pages-artifact@v3 needs attention",
"type": "unpinned_action",
"file": "pages.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action actions/deploy-pages@v4 needs attention",
"type": "unpinned_action",
"file": "pages.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in build.yml",
"type": "missing_timeout_minutes",
"file": "build.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in pages-deploy.yml",
"type": "missing_timeout_minutes",
"file": "pages-deploy.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in push-email-notify.yml",
"type": "missing_timeout_minutes",
"file": "push-email-notify.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in instant-sync.yml",
"type": "secret_action_without_presence_gate",
"file": "instant-sync.yml",
"action": "peter-evans/repository-dispatch",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in codeql.yml",
"type": "codeql_missing_actions_language",
"file": "codeql.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
hyperpolymath
marked this pull request as ready for review
July 21, 2026 12:33
🔍 Hypatia Security ScanFindings: 226 issues detected
View findings[
{
"reason": "Action actions/checkout@v4 needs attention",
"type": "unpinned_action",
"file": "pages-deploy.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action actions/checkout@v4 needs attention",
"type": "unpinned_action",
"file": "pages.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action actions/checkout@v4 needs attention",
"type": "unpinned_action",
"file": "pages.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action actions/upload-pages-artifact@v3 needs attention",
"type": "unpinned_action",
"file": "pages.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action actions/deploy-pages@v4 needs attention",
"type": "unpinned_action",
"file": "pages.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in build.yml",
"type": "missing_timeout_minutes",
"file": "build.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in pages-deploy.yml",
"type": "missing_timeout_minutes",
"file": "pages-deploy.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in push-email-notify.yml",
"type": "missing_timeout_minutes",
"file": "push-email-notify.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in instant-sync.yml",
"type": "secret_action_without_presence_gate",
"file": "instant-sync.yml",
"action": "peter-evans/repository-dispatch",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in codeql.yml",
"type": "codeql_missing_actions_language",
"file": "codeql.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
hyperpolymath
added a commit
that referenced
this pull request
Jul 21, 2026
…le pins (#293) Clears the **last two red `governance` jobs**. Follow-up to #292 — opened as a new PR off `main` per this repo's squash-merge convention (`.claude/CLAUDE.md`), not as extra commits on the merged branch. Every fix was replicated locally against the **real** gate script before pushing. ## Why these only surfaced now `governance` has 10 jobs. BROKEN-M1 (`allowed_actions: selected` + empty `patterns_allowed`) made the whole workflow `startup_failure` with **zero jobs**, so all 10 were invisible. With the policy set to `all`, 8 report green and these 2 report honestly. #292 then cleared the SPDX arm and the retired-workflow rule, revealing what sat behind them. ## 1 · `Workflow security linter` — action pinning `pages.yml` held the only **4 tag-ref `uses:`** in the repo (out of 66). It had **never actually run** — its one and only run was the BROKEN-M1 `startup_failure` — so no linter had ever inspected it. | Action | Pinned to | Change | |---|---|---| | `actions/checkout` | `de0fac2e` (v6.0.2) | v4 → v6.0.2, matching the pin **41 other workflows here already use** | | `actions/upload-pages-artifact` | `56afc609` (v3.0.1) | pin-only — exactly what `@v3` resolves to today | | `actions/deploy-pages` | `d6db9016` (v4.0.5) | pin-only — exactly what `@v4` resolves to today | Two are pure pins with no behaviour change. `checkout` moves for repo consistency; worth flagging that `pages.yml` is the **only container job** here, so this is the first time that pin runs inside `idris2-pack`. Preconditions verified before pinning a never-run workflow green: `hyperpolymath/ddraig-ssg` is public with `Ddraig.idr` at root, and Pages is `build_type=workflow` on `boj-server.net`. ## 2 · `Check Workflow Staleness` — reusable pin recency The gate allows *≤50 commits behind standards HEAD **OR** ≤14 days old*. `d135b05` was **75 commits / 26 days** behind — outside on both arms. Refreshed to `8813ecf`. Scoped to exactly the two reusables the gate names. `check-workflow-staleness.sh` inspects only `governance-reusable`, `hypatia-scan-reusable` and `scorecard-reusable` — which is why **`mirror.yml` sits at the same `d135b05` and was not flagged**. It is left alone deliberately rather than swept along. ### Evidence, not assumption **`governance-reusable`** — identical 10 jobs before and after, so no new required check appears. The three gates whose behaviour changes were each run locally against this tree: | Gate | Result | |---|---| | Guix primary / Nix fallback | **PASS** — `guix.scm` present, so the Nix fallback (and the absent `flake.nix`) is moot | | Code quality + docs | **PASS** — README + LICENSE + CONTRIBUTING all present | | banned languages (+ new Groovy) | **0** tracked `.groovy`/`.gradle` files | Both gates fetch their scripts from `standards@main` rather than from the pin, so these are the scripts CI will actually run. **`scorecard-reusable`** — the entire `d135b05..8813ecf` diff is an SPDX correction (`PMPL-1.0-or-later` → `MPL-2.0`) plus `timeout-minutes: 15`. Called out explicitly because `scorecard.yml` has **no `pull_request` trigger**, so this PR's checks do *not* exercise it. The diff is the evidence; its first real run is the next push to `main`. ## Local verification - `check-workflow-staleness.sh` → **exit 0** - 66/66 `uses:` SHA-pinned - 25/25 workflows carry SPDX + top-level `permissions:` - all 25 parse as YAML ## Not in scope `SonarQube` and `Hypatia` fail independently of these changes; triaged separately. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
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.
Turns
governancefrom 2-of-10-red to green. Each fix was replicated locally against the real gate script before pushing — no speculative pushes.What was failing, and why it was invisible until now
governancehas 10 jobs; onlyWorkflow security linterandCheck Workflow Stalenesswere red. Both had been masked by BROKEN-M1 (allowed_actions: selected+ emptypatterns_allowed), which made the whole workflowstartup_failurewith zero jobs. Once the policy was set toall, the jobs ran and reported honestly.Three commits, each clearing a gate that revealed the next
d3f61c70Workflow security linter— SPDXpages.ymlhad no SPDX header. Added. Also deleted the retiredscorecard-enforcer.yml, whichCheck Workflow Stalenessfails on by name.9bb4f99eWorkflow security linter— action pinningpages.ymlheld the only 4 tag-refuses:in the repo. SHA-pinned all four.c32bc07bCheck Workflow Stalenessgovernance-reusable+scorecard-reusablepins were 75 commits / 26 days behind — outside the recency window on both arms. Refreshedd135b05→8813ecf.Why
pages.ymlwas unpinned in the first placeIt has never successfully run. Its one and only run, from #288, was the BROKEN-M1
startup_failure— so no linter had ever seen it. Preconditions were checked before pinning it green:hyperpolymath/ddraig-ssgis public withDdraig.idrat root, and Pages isbuild_type=workflowonboj-server.net.Evidence for the re-pin
Scoped to exactly the two reusables the gate names.
check-workflow-staleness.shinspects onlygovernance-reusable,hypatia-scan-reusableandscorecard-reusable— which is whymirror.ymlsits at the samed135b05and was not flagged. It is deliberately left alone.guix.scmis present, so the Nix fallback and the absentflake.nixare moot), docs PASS (README + LICENSE + CONTRIBUTING), banned-languages 0 tracked.groovy/.gradlefiles. Both gates fetch their scripts fromstandards@mainrather than from the pin, so these are the scripts CI actually runs.PMPL-1.0-or-later→MPL-2.0) plustimeout-minutes: 15. Stated explicitly becausescorecard.ymlhas nopull_requesttrigger, so this PR's checks do not exercise it; the diff is the evidence, not a green tick. Its first real run is the next push tomain.Local verification
check-workflow-staleness.sh→ exit 0uses:SHA-pinned; 25/25 workflows carry SPDX + top-levelpermissions:; all 25 parse as YAMLNot in scope
SonarQubeandHypatiafail independently of these changes and are triaged separately.🤖 Generated with Claude Code