Skip to content

fix(ci): resync actions.lock after PR #66 and clear the SPDX gate - #70

Merged
hyperpolymath merged 1 commit into
mainfrom
fix/actions-lock-resync-20260922
Sep 22, 2026
Merged

hyperpolymath merged 1 commit into
mainfrom
fix/actions-lock-resync-20260922

Conversation

@hyperpolymath

@hyperpolymath hyperpolymath commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

What this fixes

main is red, and the CI half of it traces to a single commit: PR #66, a
dependabot actions-group bump that changed uses: in six workflows without
touching .github/workflows/actions.lock.

That produced two distinct failure classes:

Symptom Mechanism
4 × startup_failure (quality, codeql, coverage, oikosbot) — jobs=0, no logs the bumped ref has no lock entry at all, so the workflow is rejected at load
3 × failure in "Set up job" (Rust CI, Cross-platform build, Fuzz Smoke) dtolnay/rust-toolchain@stable has an entry, but its pin became unreachable after an upstream force-push
Workflow Security Linter, 33 of 35 files gh actions-lock prepends its managed-by banner to line 1, pushing a correct SPDX header to line 2; the gate was head -1-strict

Changes

1. actions.lock regenerated — six bumped refs onboarded plus one transitive:

github/codeql-action                         v4.37.7  -> v4.38.0
taiki-e/install-action                       v2.86.3  -> v2.87.13
codecov/codecov-action                       v7.0.0   -> v7.1.0
actions/deploy-pages                         v5.0.0   -> v5.0.1
editorconfig-checker/action-...              v2.2.0   -> v3.0.0
softprops/action-gh-release                  v3.0.2   -> v3.0.3
transitive: actions/github-script@ed59741 (via codecov-action v7.1.0)

plus dtolnay/rust-toolchain@stable re-pinned to the live stable commit.

2. SPDX gate relaxed head -1 → head -5 in workflow-linter.yml.
Moving the header back to line 1 was considered and rejected: the tool
re-prepends its banner on every fix run, so that arm is re-broken by the
next lock regeneration. Relaxing the gate is the stable arm.

3. Badge 8509 removed from README.adoc. bestpractices.dev/projects/8509
resolves to "PA-updated-Weapon-Master", an unrelated MS-PL RPG game at
github.com/Isaiah0521/PA-updated-Weapon-Master. It was a false public
provenance claim, corroborated by the open CIIBestPracticesID Scorecard alert.

Verification (matched pair, identical binary)

gh actions-lock --verify
before valid=false, rc=1, 16 errors (8 ref-changed + 8 unreachable-pin)
after valid=true, rc=0, 0 errors

--verify-local (the pre-commit path) is also valid=true, rc=0.
The 3 remaining findings are ref-moved warnings on @main refs
(a2ml-ecosystem, k9-ecosystem, oikosbot) — deliberately left alone;
re-pinning a moving @main is a separate decision.

Workflow bytes were proven unchanged across the lock regeneration by
sha256 over git ls-files -s .github/workflows/ excluding the lock itself,
so the only workflow edit in this PR is the linter predicate.

SPDX gate checked against a mutant control: old predicate fails 33/35,
new predicate passes 35/35, and a header-less file and a file with its
header at line 6 are both still rejected — the relaxed gate is not vacuous.

Deliberately NOT in this PR

Surfaced during recon, recorded, not actioned here: no required_status_checks
rule exists on main (so every gate here is advisory, and RepositoryRole:always
sits in the bypass list); the Coverage/CodeQL workflow badges and the
SOC 3 / ISO 27001 / CIAQ self-assertions; dependabot's npm entry hard-failing on a
missing /package.json and cargo pointed at a root Cargo.toml that does not
exist; tests/e2e.sh:121 calling an undefined fail (hiding the real Zig error);
Hypatia logging 198 findings as ##[error][hypatia] null; the Well-Known gate
looking at .well-known/ while content lives at www/.well-known/.

Expect the remaining red on main after this lands to be exactly that set —
no new failures.

🤖 Generated with Claude Code

https://claude.ai/code/session_01YSq3UodR3CjsuAK5yoTzHF

Summary by CodeRabbit

  • Bug Fixes
    • Improved workflow validation to recognize SPDX license headers within the first five lines, accommodating automatically added banners.
    • Updated validation guidance to reflect the accepted header placement.

@hyperpolymath

Copy link
Copy Markdown
Contributor Author

Measured CI result on this head

The acceptance criterion is met: startup_failure count is 0 (was 4).

Class Workflow before (main) now
1 — no lock entry Code Quality startup_failure ✅ success
1 Coverage startup_failure ✅ success
1 CodeQL Security Analysis startup_failure runs (fails in analysis)
1 OikosBot startup_failure runs (fails in analysis)
2 — unreachable pin Rust CI failure @ Set up job ✅ success
2 Cross-platform build failure @ Set up job ✅ success
2 Fuzz Smoke failure @ Set up job ✅ success

And the gate that was red on main:

Governance Check / Actions lockfile verify — Verify actions.lock … ✅ success.

Workflow Security Linter → Check SPDX Headers — ✅ success (was failing 33 of 35 files).

⚠ Correction to my description above: the remaining red is NOT "the same set"

I predicted no new failure names. That was wrong, and the mechanism is worth stating:
a job stops at its first failing step, so every later step's verdict was unknown, not
passing.
Fixing the SPDX step let later steps run for the first time. Two additions:

  1. Workflow Security Linter → Check SHA-Pinned Actions — 88 unpinned uses: lines.
    Pre-existing, proven: this branch changes zero uses: lines
    (git diff origin/main..HEAD -- .github/workflows/ | grep -E '^[+-]\s*uses:' is empty),
    and the step's own predicate returns 88 at origin/main and 88 at HEAD — identical.
    It had never executed, because SPDX (step 2) failed before it (step 4).

    🚨 Worth a decision: this gate demands inline 40-hex SHAs, while this repo pins through
    actions.lock — where a symbolic ref is a pin, bound to a commit. It can never go
    green under the lock regime, and gh actions-lock fix mode actively rewrites SHA pins
    back to tags. The two gates are mutually contradictory. Not touched here.

  2. CodeQL Security Analysis / OikosBot now fail visibly rather than being startup-dead.
    Their analysis failures were always there; a dead workflow reports as absent, not failing.

Governance → Parse every tracked workflow is likewise unchanged and not mine: exactly one
workflow fails to parse at both refs — vendored
third_party/gossamer/.github/workflows/dogfood-gate.yml (a python3 -c heredoc inside
run: | whose continuation lines sit at column 0, escaping the block scalar). The gate globs
**/.github/workflows/*.yml and so scans a vendored tree this repo does not own.

Everything else red is the out-of-scope set named in the description: missing
.machine_readable/STATE.a2ml (Verify Manifest Files, OpenSSF Compliance), Hypatia criticals
(Static Analysis Gate), and tests/e2e.sh:121 calling an undefined fail (Desktop shell e2e).

🤖 Generated with Claude Code

https://claude.ai/code/session_01YSq3UodR3CjsuAK5yoTzHF

PR #66 (dependabot actions-group) changed `uses:` in six workflows without
touching .github/workflows/actions.lock. Refs absent from the lock are
rejected at workflow load, so quality/codeql/coverage/oikosbot died with
startup_failure (jobs=0, no logs); separately the existing entry for
dtolnay/rust-toolchain@stable had gone unreachable after an upstream
force-push, killing Rust CI, Cross-platform build and Fuzz Smoke in
"Set up job".

Regenerated the lock for the six bumped refs plus one transitive
(actions/github-script via codecov-action) and re-pinned rust-toolchain.

Also relax the workflow-linter SPDX gate from `head -1` to `head -5`:
`gh actions-lock` prepends its own managed-by banner to line 1 on every
fix run, pushing a correct line-1 SPDX header to line 2. The old
predicate failed 33 of 35 workflow files for headers that are present
and correct; the new one passes 35 of 35 while still rejecting a
header-less file and a header below line 5.

Verified: `gh actions-lock --verify` valid=true rc=0, 0 errors
(was valid=false rc=1, 16 errors: 8 ref-changed + 8 unreachable-pin).
The 3 remaining ref-moved warnings are the @main refs, left alone
deliberately. Workflow bytes are unchanged apart from the linter.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSq3UodR3CjsuAK5yoTzHF
@hyperpolymath
hyperpolymath force-pushed the fix/actions-lock-resync-20260922 branch from 1ca3b7c to dade862 Compare September 22, 2026 12:39
@hyperpolymath

Copy link
Copy Markdown
Contributor Author

Badge removal split out of this PR.

The OpenSSF Best Practices badge removal that was commit 1ca3b7c here has landed separately
in #71, as part of an estate-wide fix: project 8509 was on 13 repositories and resolves
to Isaiah0521/PA-updated-Weapon-Master, an unrelated MS-PL game, at badge level passing.

This branch has been rebased onto main; git dropped 1ca3b7c as already-applied. This PR is
now purely the actions.lock resync plus the SPDX linter relaxation — one commit, two files:

  • .github/workflows/actions.lock
  • .github/workflows/workflow-linter.yml

README.adoc is no longer touched here. No reviews were dismissed (there were none).

🤖 Generated with Claude Code

https://claude.ai/code/session_01YSq3UodR3CjsuAK5yoTzHF

@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 561b9529-1435-4d39-87fc-85e96074e611

📥 Commits

Reviewing files that changed from the base of the PR and between b9c03a4 and dade862.

⛔ Files ignored due to path filters (1)
  • .github/workflows/actions.lock is excluded by !**/*.lock
📒 Files selected for processing (1)
  • .github/workflows/workflow-linter.yml

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The workflow linter now scans the first five lines of each workflow file for the SPDX header. Its failure message reflects the accepted header position.

Changes

Workflow SPDX validation

Layer / File(s) Summary
SPDX header position check
.github/workflows/workflow-linter.yml
The check scans the first five lines instead of only the first line. Comments explain the gh actions-lock banner, and the error message states the new position requirement.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~8 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to dade8

The workflow linter now accepts valid SPDX headers after the actions-lock banner while retaining placement validation. The change is mergeable.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly identifies the two main changes: resynchronizing actions.lock and updating the SPDX workflow gate. It is concise and related to the pull request objectives.
Description check ✅ Passed The description gives detailed scope, rationale, changes, verification results, and out-of-scope findings. It does not use the template headings exactly and omits the RSR Quality Checklist and Screens…
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)

❌ Error committing Unit Tests locally.

  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@hyperpolymath hyperpolymath changed the title fix(ci): resync actions.lock after PR #66, clear SPDX gate, drop false badge fix(ci): resync actions.lock after PR #66 and clear the SPDX gate Sep 22, 2026
@coderabbitai

coderabbitai Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Note

Unit test generation is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.


Generating unit tests... This may take up to 20 minutes.

@hyperpolymath
hyperpolymath merged commit eb6c7c0 into main Sep 22, 2026
46 of 57 checks passed
@coderabbitai

coderabbitai Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

🤖 Coding Agent task started for unit test generation.

@hyperpolymath
hyperpolymath deleted the fix/actions-lock-resync-20260922 branch September 22, 2026 12:52
@coderabbitai

coderabbitai Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Note

Unit test generation is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.


Generating unit tests... This may take up to 20 minutes.

@coderabbitai

coderabbitai Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Failed to create Coding Agent finishing-touch task.

hyperpolymath added a commit that referenced this pull request Sep 22, 2026
…80)

The `Check SHA-Pinned Actions` step in `workflow-linter.yml` demanded an
inline
40-hex SHA on every action reference. This repo pins through
`.github/workflows/actions.lock`, which binds a symbolic ref to a
commit. The two
regimes contradict each other, so that step could never go green.

## Measured, not assumed

| | |
|---|---|
| action references on `main` | **93** |
| violating the 40-hex predicate | **88** |
| actually 40-hex pinned | **4** |
| this workflow's own lock entry | `actions/checkout@v7.0.1` — a
**tag**, which its own step would reject |

## Why deleted rather than softened

A replacement predicate that reads the lockfile would be a third lock
parser beside
`gh actions-lock` and `scripts/check-lock-sync.sh`. A body that `exit
0`s would be a
vacuous gate. The question is already owned and **green** elsewhere: the
governance
bundle's `Actions lockfile verify` job, whose step is literally named
*"Verify
actions.lock (or SHA pins during the grace window)"*. Retiring this step
therefore
leaves **no coverage gap**.

## The unmasking was pre-measured

A job halts at its first failing step, so the four steps after this one
have been
`skipped` — **unknown, not passing** — on every run. Fixing an early
step unmasks every
later one, which is exactly what bit #70. Each was executed against the
tree under a
clean `bash -e` before this change:

```
rc=0   Check for Duplicate Workflows
rc=0   Check CodeQL Language Matrix
rc=0   Check Secrets Guards
rc=0   Summary
```

`codeql-analysis.yml` and `rust-ci.yml` are both **absent**, so the only
`exit 1` path
among those four cannot fire.

## Scope

- **No `uses:` line changes**, so `.github/workflows/actions.lock` needs
no edit — this
  does not touch the file owned by #73, and does not conflict with it.
- Net **−18/+6**: one step removed, a comment left in its place naming
where the pinning
  question now lives.
- `yq` parses the result; all seven surviving step bodies parse under
`bash -n`.

⚠ For the later "require the checks" work: this workflow is
**path-filtered** on
`.github/workflows/**`, so its context can never be a required status
check — it would
block every PR that does not touch `.github/`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01YSq3UodR3CjsuAK5yoTzHF

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Updated workflow validation to rely on the centralized actions
lockfile verification.
* Removed the previous SHA-format validation step that conflicted with
the lock-based verification approach.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request Sep 22, 2026
…ush (#84)

Retires the a2ml-keyed manifest gates per owner ruling **D-B**, stops
CodeQL firing on PR/push, and fixes one unambiguous defect that the
retirement exposed.

This is **PR 6a** — the first of a three-way split of the original PR 6.
It contains only the parts that could be **fully pre-measured locally**;
the hypatia gate (6b) and the Governance parse failure (6c) follow
separately, because a five-part PR has five ways to be red and the
standing ruling is to land only fully-green PRs.

## What changed, and why each

**1. `verify-manifests.yml` — retire STATE / ECOSYSTEM / META (D-B).**
Job *Verify Machine-Readable Manifest Currency* halted at step 3 on
`.machine_readable/STATE.a2ml`, leaving steps 4–7 `skipped` — **unknown,
not passing**. All three a2ml files are **absent**, so there is no
content to move and nothing to preserve: only steps to remove. The
requirement survives as issue #81 (re-express as `.deed`). Nothing new
connects to a2ml.

**2. `verify-manifests.yml` — repair a step that had never once
executed.**
Unmasking step 6 exposed a real defect in *Check
TEMPLATE-STANDARDS-AUDIT.adoc currency*:

```
first line of the file : v1.2, 2026-07-26
old: sed 's/v//'       → "1.2, 2026-07-26"   compared against literal "1.2"  → FAIL
new: sed 's/^v//' | cut -d, -f1 | tr -d '[:space:]' → "1.2"                  → PASS
```

The document **is** v1.2, **is** dated 2026-07-26, and **does**
reference DEP-09. The gate's own extraction was wrong, not the content —
so this is an unambiguous defect fixed directly, per the 09-22 ruling.
Both arms were measured against the real file; the old code is a working
mutant control.

**3. `openssf-compliance.yml` — same STATE.a2ml demand, three steps
masked.**
Step retired. The three a2ml filenames are also dropped from the
placeholder-token list, where each was already guarded by `[ -f "$f" ]`
and therefore inert.

**4. `codeql.yml` — `workflow_dispatch:` only.**
Org code-scanning config 256896 sets `allow_advanced: false`, so this
workflow's SARIF is refused outright (*"analyses from advanced
configurations cannot be processed when the default setup is enabled"*).
Default-setup CodeQL runs separately, is **green**, and already
satisfies the `code_scanning` ruleset rule. **The file is not deleted**
— `actions.lock` keys an entry to it, and deleting it would orphan that
entry and red the bidirectional `check-lock-sync.sh` arriving in #73.
The rationale is recorded in-file so a later reader does not "restore"
the trigger.

## Pre-measured, not predicted

Deleting a failing step promotes whatever sat behind it to its **first
real measurement**. All five newly-unmasked predicates were run locally
against the real tree *before* pushing:

| unmasked predicate | result |
|---|---|
| `Check TEMPLATE-STANDARDS-AUDIT.adoc currency` | ❌ → **fixed in this
PR** (item 2) |
| `Check reusable workflow pins` | ✅ both 40-hex and identical |
| `Check CHANGELOG exists` | ✅ `CHANGELOG.md` present |
| `Check no unfilled placeholder tokens` | ✅ 0 across 7 present files |
| `Summary` | ✅ |

## ⚠ Scope — what this PR does *not* claim

**This does not turn the `Verify Manifest Files` *workflow* green.** Its
other job, *Verify AI-MANIFEST and README.adoc files*, fails
**independently** on two missing `README.adoc` files whose cure lives on
**PR #73's** branch. The assertion here is the job-level check-run
**`Verify Machine-Readable Manifest Currency`**, not the workflow
conclusion. Reading job 1's red as "D-B failed" would be a misreading.

## 🚨 Finding for #82 — a fourth settings.yml divergence

`.github/settings.yml` declares `analyze (javascript-typescript, none)`
as a required status check. That is the CodeQL **advanced** job's matrix
name, which item 4 makes permanently unemittable. It is inert today only
because the live ruleset carries **no `required_status_checks` rule at
all** — which is precisely the drift #82 already tracks. Adding it there
rather than silently working around it.

## Verification

- `yq` parses all three files; `actionlint` clean.
- SPDX header still within `head -5` on `codeql.yml` (the gate PR #70
relaxed).
- `yq e '.on | keys'` on `codeql.yml` returns exactly
`[workflow_dispatch]`.
- Commit signed (`%G? = G`), satisfying `required_signatures`.
- Assertion is **per step, not per job**.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01YSq3UodR3CjsuAK5yoTzHF

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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