Skip to content

fix(ci): install Zig from a pinned, verified tarball — replaces non-allow-listed mlugg/setup-zig (#103) - #104

Merged
hyperpolymath merged 1 commit into
mainfrom
fix/zig-setup-allowlisted
Sep 30, 2026
Merged

hyperpolymath merged 1 commit into
mainfrom
fix/zig-setup-allowlisted

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Summary

Owner ruling 2026-09-30: swap the Zig setup action instead of changing the allow-list. Part of #103, item 1.

ABI Contract and Cross-Platform Build & Test ended in startup_failure on main and on every PR. Their run pages (35609965294, 35609970129) give this cause:

The action mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 is not allowed in hyperpolymath/game-server-admin because all actions must be from a repository owned by hyperpolymath, created by GitHub, or verified in the GitHub Marketplace.

Repo Actions policy: allowed_actions=selected, github_owned_allowed=true, verified_allowed=true, patterns_allowed=[], sha_pinning_required=true. None of the Zig installers is GitHub-owned or from a verified creator (mlugg/setup-zig, goto-bus-stop/setup-zig, korandoru/setup-zig), so no allow-listed action can do this.

Change

  • New scripts/install-zig.sh (MPL-2.0, mode 100755). It downloads zig-x86_64-linux-0.15.2.tar.xz from ziglang.org over HTTPS.
    • It checks the download against the pinned sha256 02aa270f…f93239, then puts Zig on PATH via $GITHUB_PATH.
    • It checks that zig version prints 0.15.2.
    • It fails loudly on any platform other than x86_64-linux.
    • At pin time, the tarball's minisign signature was verified against the ZSF key RWSGOq2NVecA2UPN…. Both the file signature and the trusted-comment signature passed, and a tampered digest was rejected.
  • abi-contract.yml (2 sites) and cross-platform.yml (1 site): uses: mlugg/setup-zig → run: bash scripts/install-zig.sh. The idris2-pack container job now also installs curl ca-certificates.
  • actions.lock, edited by hand; the gh actions-lock rewrite mode was not used. Three mlugg/setup-zig@v2.2.1 entries were removed: two workflow lists and one dependency. gh actions-lock --no-fix reports valid: true.
  • docs/maintainer/CI-CD-GUIDE.adoc: updated to describe how Zig is now installed.

Validation

  • actionlint on both workflows: clean. shellcheck and bash -n on the script: clean.
  • The script ran locally: sha256 OK, and zig 0.15.2 was installed.
  • Mutant check: with a one-character change to the pinned sha256, the script exits 1 and does not write GITHUB_PATH.

Not in this PR

These #103 items are left for follow-up: the Governance, Pages and Mirror startup failures, the K9 pedigree name error, and the SonarCloud and Hypatia reds.

🤖 Generated with Claude Code

https://claude.ai/code/session_0136eszqrQ53Kj7aBH1D4rXK

…f mlugg/setup-zig

mlugg/setup-zig is not on this repo's Actions allow-list (GitHub-owned +
verified creators only), so `ABI Contract` and `Cross-Platform Build & Test`
ended in startup_failure on main and every PR with:

  The action mlugg/setup-zig@d1434d0 is not
  allowed in hyperpolymath/game-server-admin because all actions must be from
  a repository owned by hyperpolymath, created by GitHub, or verified in the
  GitHub Marketplace.

No verified-creator Zig installer exists, so replace the action with
scripts/install-zig.sh: it downloads the official Zig 0.15.2 x86_64-linux
tarball from ziglang.org, checks it against a pinned sha256 (whose minisign
signature was verified against the ZSF release key at pin time), and puts
it on PATH. The Idris2 container job also installs curl + ca-certificates.

actions.lock: hand-removed the three mlugg/setup-zig@v2.2.1 entries (two
workflow lists, one dependency). `gh actions-lock --no-fix` reports valid.

Refs #103

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0136eszqrQ53Kj7aBH1D4rXK
@coderabbitai

coderabbitai Bot commented Sep 30, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 33 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 405ac4d7-47d4-4c2e-a366-23c2b0737b25

📥 Commits

Reviewing files that changed from the base of the PR and between 070529e and fbd8151.

⛔ Files ignored due to path filters (1)
  • .github/workflows/actions.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • .github/workflows/abi-contract.yml
  • .github/workflows/cross-platform.yml
  • docs/maintainer/CI-CD-GUIDE.adoc
  • scripts/install-zig.sh
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


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.

@github-actions

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 90 issues detected

Severity Count
🔴 Critical 0
🟠 High 1
🟡 Medium 89
View findings
[
  {
    "reason": "Job `triage` in label-triage.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
    "type": "missing_timeout_minutes",
    "file": "label-triage.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium",
    "recipe_id": "recipe-add-workflow-timeout-minutes",
    "job": "triage"
  },
  {
    "reason": "Job `sync` in labels.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
    "type": "missing_timeout_minutes",
    "file": "labels.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium",
    "recipe_id": "recipe-add-workflow-timeout-minutes",
    "job": "sync"
  },
  {
    "line": 39,
    "reason": "job in .github/workflows/labels.yml references `secrets.*` but does not install `step-security/harden-runner` — review outbound-egress monitoring",
    "type": "RE001",
    "file": ".github/workflows/labels.yml",
    "action": "report",
    "rule_module": "research_extensions",
    "severity": "warn"
  },
  {
    "line": 45,
    "reason": "job in .github/workflows/push-email-notify.yml references `secrets.*` but does not install `step-security/harden-runner` — review outbound-egress monitoring",
    "type": "RE001",
    "file": ".github/workflows/push-email-notify.yml",
    "action": "report",
    "rule_module": "research_extensions",
    "severity": "warn"
  },
  {
    "line": 120,
    "reason": "job in .github/workflows/release.yml references `secrets.*` but does not install `step-security/harden-runner` — review outbound-egress monitoring",
    "type": "RE001",
    "file": ".github/workflows/release.yml",
    "action": "report",
    "rule_module": "research_extensions",
    "severity": "warn"
  },
  {
    "line": 25,
    "reason": "job in .github/workflows/instant-sync.yml references `secrets.*` but does not install `step-security/harden-runner` — review outbound-egress monitoring",
    "type": "RE001",
    "file": ".github/workflows/instant-sync.yml",
    "action": "report",
    "rule_module": "research_extensions",
    "severity": "warn"
  },
  {
    "line": 84,
    "reason": "job in .github/workflows/hypatia-scan.yml references `secrets.*` but does not install `step-security/harden-runner` — review outbound-egress monitoring",
    "type": "RE001",
    "file": ".github/workflows/hypatia-scan.yml",
    "action": "report",
    "rule_module": "research_extensions",
    "severity": "warn"
  },
  {
    "line": 24,
    "reason": "job in .github/workflows/boj-build.yml references `secrets.*` but does not install `step-security/harden-runner` — review outbound-egress monitoring",
    "type": "RE001",
    "file": ".github/workflows/boj-build.yml",
    "action": "report",
    "rule_module": "research_extensions",
    "severity": "warn"
  },
  {
    "line": 53,
    "reason": "job in .github/workflows/label-triage.yml references `secrets.*` but does not install `step-security/harden-runner` — review outbound-egress monitoring",
    "type": "RE001",
    "file": ".github/workflows/label-triage.yml",
    "action": "report",
    "rule_module": "research_extensions",
    "severity": "warn"
  },
  {
    "line": 87,
    "reason": "workflow .github/workflows/static-analysis-gate.yml:87 step `Emit check annotations` swallows non-zero exit via `|| true` — failures will be masked",
    "type": "RE005",
    "file": ".github/workflows/static-analysis-gate.yml",
    "action": "report",
    "rule_module": "research_extensions",
    "severity": "warn"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@hyperpolymath
hyperpolymath merged commit ec5db2f into main Sep 30, 2026
25 of 26 checks passed
@hyperpolymath
hyperpolymath deleted the fix/zig-setup-allowlisted branch September 30, 2026 15:19
hyperpolymath added a commit that referenced this pull request Sep 30, 2026
…realign (#105)

## What

Restores `game-server-admin-launcher.sh`'s **AGPL-3.0-or-later** header,
which #102 (6152bda, merged 2026-09-30) replaced with two `MPL-2.0`
lines.

## Why

`docs/legal/LICENSE-POLICY.adoc` (#62, 309accc) puts code — including
`.sh` — under AGPL-3.0-or-later and keeps config under an MPL-2.0
carve-out. #102's realign used a launch-scaffolder generator that
hard-coded `MPL-2.0` and never read `[project].license`, so it
relicensed a shipped file without anyone deciding to. That generator
defect is fixed in **hyperpolymath/launch-scaffolder#64**.

## Change

- `game-server-admin.launcher.a2ml`: `[project].license =
"AGPL-3.0-or-later"` (the app's licence). The config file's own SPDX
header stays MPL-2.0 per the carve-out.
- `game-server-admin-launcher.sh`: re-realigned from
launch-scaffolder#64 at 1ddf146. The diff is the header only: one
`AGPL-3.0-or-later` script header, one matching `;;` deed header,
duplicate removed. `CONFIG_FILE` and the body are byte-identical.

`bash -n` ok; `shellcheck -S warning` clean. No CI here depends on
realign, so this can merge before or after launch-scaffolder#64. Until
#64 merges, a realign from the old generator would revert this header
again.

Not armed for automerge: armed PRs on this repo merge on the spot (#104,
#102), so this is left for your review.

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

https://claude.ai/code/session_0136eszqrQ53Kj7aBH1D4rXK

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request Oct 5, 2026
…ock gate, K9 pedigree (#108)

Closes #103.

## What was actually broken

Four independent faults on `main`, all masquerading as one red board.
Every one of them was diagnosed from the run pages' own error text, or
measured with a throwaway probe workflow, not guessed.

### 1. `actions.lock` drift — the one that killed the required checks

Dependabot #107 bumped 14 action tags and left
`.github/workflows/actions.lock` describing the old ones. An out-of-date
lockfile is not a soft failure: GitHub refuses to **start** every
workflow listed in it, with

```
The lockfile could not be validated. Regenerate it by running `gh actions-lock`.
```

so the run ends `startup_failure` with zero steps and **zero check
runs**. That is why `ABI Contract` and `Cross-Platform Build & Test` —
the producers of the four required contexts — went from green (#104) to
nothing at all in a single commit.

Two things about the fix are worth stating, because both were got wrong
first:

* **`--relock` is not "regenerate".** It means *bump moved
branch/version refs to their current upstream SHA*, so it re-resolved
everything to latest and wrote a lockfile keyed by **tag**
(`actions/checkout@v7.0.1`) while every workflow in this repo names a
**SHA** (`actions/checkout@3d3c42e5… # v7.0.1`). The estate's validator
keys on `owner/repo@<40-hex>` exactly as written, so that file
contradicted every workflow in the repo and took the failure count from
2 workflows to *all of them*. The canonical regeneration is plain fix
mode with `--no-migrate-local-actions --no-narrow`.
* **the lockfile must key on the ref the workflow names.** Measured
against `hyperpolymath/standards` `.githooks/validate-actions-lock.sh`:
the lockfile on `main` is missing **10 of the 14** required SHA keys.
The one here is missing none — 17 refs checked against 17 keys, 0
errors.

### 2. Estate Actions allow-list

`goto-bus-stop/setup-zig`,
`editorconfig-checker/action-editorconfig-checker`,
`webfactory/ssh-agent`, `dtolnay/rust-toolchain` and — measured on this
branch — **`haskell-actions/setup`** are all refused:

```
The action … is not allowed in hyperpolymath/game-server-admin because all
actions must be from a repository owned by hyperpolymath, created by GitHub,
or verified in the GitHub Marketplace.
```

Per the owner's ruling on #103 the allow-list is not widened; the
offending `uses:` are replaced. `setup-zig` → `scripts/install-zig.sh`
(#104's precedent). `haskell-actions/setup` → `scripts/setup-haskell.sh`
(GHC 9.8.2 + cabal 3.10.2.0 from `downloads.haskell.org`,
sha256-verified against `ghcup-0.0.7.yaml`).

`haskell-actions/setup` deserves a note: Pages' only error was the
lockfile, which **masks** action rejections behind it, so it was
reverted to the action on the assumption it was fine — then measured
with a two-step probe workflow pushed to this branch and deleted again,
which got both it and the `editorconfig-checker` control refused in one
message. The installer is back.

### 3. K9 pedigree

`container/deploy.k9.ncl` had no `pedigree` record. Rewritten with one
inline (name, version, `schema_version`, leash, security, target,
validation, recipes, warnings). `Validate K9 contracts` is green.

### 4. SonarCloud

`SonarCloud Code Analysis` is red on `main` on `new_security_rating = 3`
(grade C), driven by five `githubactions:S7637` MAJOR vulnerabilities —
*"Use full commit SHA hash for this dependency"* — on
`casket-pages.yml`, `hypatia-scan.yml`, `instant-sync.yml`,
`release.yml` and `static-analysis-gate.yml`. Those five are exactly
what SHA-pinning every `uses:` fixes: the PR head's own Sonar analysis
reports **zero** of them. The PR's gate was failing only on a
`githubactions:S8233` this PR introduced (workflow-level `pull-requests:
write`), now moved to the job that writes. `main` goes green on its
first analysis after this merges.

## The gate: `.github/workflows/actions-lock.yml`

Regenerating the lockfile fixes today; nothing stopped Dependabot
re-breaking it next week. New workflow:

* **`verify`** — `gh actions-lock --verify`. Fails when lockfile and
workflows disagree, so a bump cannot merge unrelocked. Exit 0 = in sync,
1 = drift, ≥2 = tool failure (a broken tool is not allowed to look like
a clean pass).
* **`relock`** — regenerates and delivers the file. A GitHub App cannot
write under `.github/workflows/` at all (`permissions:` has no
`workflows` key; the push is refused outright), so delivery is: push
with `ACTIONS_LOCK_TOKEN` if that PAT is configured, otherwise publish
the regenerated file as an artefact **and in full as a pull-request
comment** so it can be applied by hand.

## Acceptance criteria, one by one

| criterion | status |
| --- | --- |
| `Cross-Platform Build & Test` and `ABI Contract` start on a PR and on
`main`, no `startup_failure`; each required context is a real check run
| ✅ both `success` on the PR head |
| required-context set is SET-EQUAL to what an actual PR head produces |
✅ all 5 required contexts report — `Linux`, `Idris2 model type-checks`,
`Zig ↔ Idris tables in sync`, `AffineScript ↔ Zig FFI symbols in sync`,
`scan / gitleaks` — all `success` |
| `container/deploy.k9.ncl` carries a pedigree; `Validate K9 contracts`
green | ✅ |
| `SonarCloud Code Analysis` green on `main`, or removed with a stated
reason | ✅ green on this PR head; the five vulnerabilities that make
`main` red are removed by this PR's SHA-pinning and drop out on `main`'s
next analysis |
| `Governance` no longer `startup_failure` on `main` | ⚠️ **blocked
upstream** — see below |
| `Mirror to Git Forges` no longer `startup_failure` on `main` | ⚠️
**blocked upstream** — same cause |
| `GitHub Pages` no longer `startup_failure` on `main` | ✅
`haskell-actions/setup` removed; it only triggers on push to `main`, so
it cannot be exercised from a branch, but the rejected action is gone
and the lockfile now validates |

## What is still blocked, and why

`Governance` and `Mirror to Git Forges` are thin wrappers around
`hyperpolymath/standards` reusable workflows, and the refused actions
live **inside those reusable workflows**:

```
Governance            editorconfig-checker/action-editorconfig-checker@840e866d
Mirror to Git Forges  webfactory/ssh-agent@e8387483, dtolnay/rust-toolchain@6c977a6c
```

Both have been there since those reusable workflows were created, so
there is no earlier clean commit to re-pin to. The fix belongs upstream,
and it is written and verified: **hyperpolymath/standards#1147** carries
the complete patch (EditorConfig via pinned `go install` + Go checksum
database; ssh-agent via `ssh-agent`/`ssh-add` with no third-party code;
Rust toolchain via the runner's own stable Rust), validated with
standards' own `validate-actions-lock.sh` at 24 refs / 23 keys / 0
errors.

It is filed as an issue rather than a PR because the credential in this
sandbox is a GitHub App installation without `contents: write` on
`standards` — `git push` returns `Permission to
hyperpolymath/standards.git denied to hyperpolymath` and `POST
/git/refs` returns `Resource not accessible by integration`. The same
patch is in the workspace as `standards-fix.patch` for anyone who can
push it.

---------

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.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