ci: 4-runner PR-gate matrix + delete redundant nightly (Otto-210..213)#359
ci: 4-runner PR-gate matrix + delete redundant nightly (Otto-210..213)#359
Conversation
…undant nightly (Otto-210..212) Multi-correction landing per maintainer Otto-210 / 211 / 212 sequence. Three distinct wrongs corrected: 1. Otto-210 macOS pricing: my Otto-164 verification was WRONG. macOS IS free on public repos for standard runners. Authoritative source: https://docs.github.com/en/actions/how-tos/write-workflows/choose-where-workflows-run/choose-the-runner-for-a-job#standard-github-hosted-runners-for-public-repositories exact quote: "Use of the standard GitHub-hosted runners is free and unlimited on public repositories." 2. Otto-211 Linux-arm + mac-M1 coverage: added Linux arm64 alongside x64, and ensured macOS target is Apple Silicon (NOT Intel). Matrix: [ubuntu-latest, ubuntu-24.04-arm, macos-latest]. Windows deferred ("windows will come later on both zeta and acehack"). 3. Otto-212 no-pinned-tags discipline: use -latest tags where available instead of pinning to a version. Avoids upgrade debt. `ubuntu-24.04-arm` exception because no rolling arm alias exists yet. Changes: - gate.yml matrix: [ubuntu-22.04] (canonical) / [ubuntu-22.04, macos-14] (forks) fromJSON → static [ubuntu-latest, ubuntu-24.04-arm, macos-latest]. All legs run on canonical repo AND forks (all free). - gate.yml comment block rewritten: remove stale "Mac is very expensive" history, cite Otto-210 URL + quote, note Otto-211 M1-not-Intel + Windows-deferred, document Otto-212 -latest discipline + ubuntu-arm exception. - gate.yml runs-on: ubuntu-22.04 → ubuntu-latest for non-matrix jobs (Semgrep, shellcheck, actionlint, markdownlint). - Header comment "Runners digest-pinned (ubuntu-22.04, macos-14), not -latest" → "-latest per Otto-212". - nightly-cross-platform.yml DELETED — redundant now that gate covers mac + linux per-PR. The workflow shipped Otto-209 with cost-capping framing that was based on the wrong Otto-164 verification; with correct Otto-210 pricing, per-PR is simpler + free. Not changed this PR (separate scope): - Other workflows still pin ubuntu-22.04 (memory-index-integrity, memory-reference-existence- lint, github-settings-drift, codeql). Systematic unpin across the repo is a separate PR to keep this diff focused. - lucent-ksk parallel still queued (cross-repo, needs separate coordination + verification per Otto-140). actionlint clean on gate.yml + cleared nightly-file. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Updates CI gating to run a unified cross-platform runner matrix on PRs/pushes, and removes the now-redundant nightly cross-platform workflow.
Changes:
- Expand
gate.ymlbuild/test job to a 4-runner matrix (Linux x64 slim/LTS, Linux arm64, macOS arm64) and update accompanying rationale comments. - Move non-matrix lint jobs from
ubuntu-22.04toubuntu-24.04. - Delete
.github/workflows/nightly-cross-platform.ymlas redundant with the new per-PR gate coverage.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| .github/workflows/gate.yml | Switches to a 4-runner matrix and updates runner selection rationale; bumps lint job runner to ubuntu-24.04. |
| .github/workflows/nightly-cross-platform.yml | Removes nightly cross-platform workflow now that gate covers the intended OS matrix. |
| # Discipline (design doc: docs/research/ci-workflow-design.md, Aaron- | ||
| # reviewed 2026-04-18; parity-swap landed round 32): | ||
| # - Runners digest-pinned (ubuntu-22.04, macos-14), not -latest. | ||
| # - Runners use -latest tags (maintainer Otto-212 discipline). |
There was a problem hiding this comment.
The header comment says runners use -latest tags, but the matrix below is pinned to specific versions (e.g., ubuntu-24.04, macos-26). Please update the discipline comment (or the matrix) so the documentation matches the actual runner-tag policy.
| # - Runners use -latest tags (maintainer Otto-212 discipline). | |
| # - Runners are pinned to explicit GitHub-hosted image tags in the | |
| # matrix (for example `ubuntu-24.04` and `macos-26`). |
| # repo-specific variable, no second workflow file — with runtime | ||
| # differentiation driven by the built-in `github.repository` | ||
| # context. | ||
| # Matrix covers three standard GitHub-hosted runners |
There was a problem hiding this comment.
This comment says the matrix covers "three" standard runners, but the matrix/list includes four (ubuntu-slim, ubuntu-24.04, ubuntu-24.04-arm, macos-26). Update the count to avoid confusion.
| # Matrix covers three standard GitHub-hosted runners | |
| # Matrix covers four standard GitHub-hosted runners |
| # including macOS. See feedback_macos_is_free_on_ | ||
| # public_repos_otto_164_verification_was_wrong_* | ||
| # memory for the correction trail. |
There was a problem hiding this comment.
The comment references a memory entry feedback_macos_is_free_on_public_repos_otto_164_verification_was_wrong_*, but that file doesn’t exist under memory/ in this repo. Please update this reference to the correct existing memory filename or remove it so cross-references stay valid.
| # including macOS. See feedback_macos_is_free_on_ | |
| # public_repos_otto_164_verification_was_wrong_* | |
| # memory for the correction trail. | |
| # including macOS. |
| # Discipline (design doc: docs/research/ci-workflow-design.md, Aaron- | ||
| # reviewed 2026-04-18; parity-swap landed round 32): | ||
| # - Runners digest-pinned (ubuntu-22.04, macos-14), not -latest. | ||
| # - Runners use -latest tags (maintainer Otto-212 discipline). |
There was a problem hiding this comment.
This comment block includes a direct contributor name ("Aaron-") in a workflow comment. Repo guidance is to avoid name attribution in code/docs (see docs/AGENT-BEST-PRACTICES.md around the "No name attribution in code, docs, or skills" section). Consider switching this to a role reference (e.g., "human maintainer") and removing the stray trailing hyphen.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cdaa1e700f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| fail-fast: false | ||
| matrix: | ||
| os: ${{ fromJSON(github.repository == 'Lucent-Financial-Group/Zeta' && '["ubuntu-22.04"]' || '["ubuntu-22.04","macos-14"]') }} | ||
| os: [ubuntu-slim, ubuntu-24.04, ubuntu-24.04-arm, macos-26] |
There was a problem hiding this comment.
Preserve required check context when renaming matrix legs
This matrix rename drops the build-and-test (ubuntu-22.04) status context that main branch protection currently requires; the checked-in protection snapshot still lists that exact context (tools/hygiene/github-settings.expected.json line 134), and the latest branch-protection audit in docs/HUMAN-BACKLOG.md (2026-04-23 entry) also records it as required. If branch protection is not updated atomically with this workflow change, PRs will be blocked by a permanently missing required check.
Useful? React with 👍 / 👎.
| fail-fast: false | ||
| matrix: | ||
| os: ${{ fromJSON(github.repository == 'Lucent-Financial-Group/Zeta' && '["ubuntu-22.04"]' || '["ubuntu-22.04","macos-14"]') }} | ||
| os: [ubuntu-slim, ubuntu-24.04, ubuntu-24.04-arm, macos-26] |
There was a problem hiding this comment.
Add architecture to cache partitioning for Linux matrix
Adding ubuntu-24.04-arm to this matrix introduces mixed Linux architectures, but cache keys in this job are still partitioned only by runner.os (Linux), so x64 and arm64 legs will collide on the same cache entries. Because cached paths include architecture-specific tool binaries (for example mise/elan/.dotnet payloads), one architecture can restore incompatible artifacts produced by the other, causing flaky setup/build behavior; include runner.arch in the keys when running both Linux architectures.
Useful? React with 👍 / 👎.
…Otto-213 durable lesson Otto-214 implementation of the tooling-level enforcement I proposed Otto-213. Memory-alone was not sufficient to stop the "write a stale version number" recurrence pattern; this script adds a CI-fail gate. Behavior: - Walks .github/workflows/*.yml files - Extracts runs-on: + os: matrix lines - Fails (exit 2) if any line references a STALE runner version (ubuntu-22.04, macos-14, macos-15, windows-2022, ubuntu-20.04, macos-13, macos-15-intel, etc.) - Warns (exit 3) if the allow-list itself is stale (>30 days since LAST_VERIFIED) - Prints the canonical list of ALLOWED labels on failure + the authoritative GitHub docs URL for re-verification Allow-list verified 2026-04-24 via https://docs.github.com/en/actions/how-tos/write-workflows/choose-where-workflows-run/choose-the-runner-for-a-job#standard-github-hosted-runners-for-public-repositories exact quote "Use of the standard GitHub-hosted runners is free and unlimited on public repositories." First-run detects 13 stale-label hits across codeql.yml, gate.yml, github-settings-drift.yml (plus stale comment- block references in gate.yml from the pre-correction history). These will be cleaned up by PR #359 for gate.yml; codeql.yml + github-settings-drift.yml need separate follow-up PRs. Does NOT wire into gate.yml automatically — separate step to add the lint check after the baseline is green. Premature enforcement would block every current PR. Sequencing: (1) this PR ships the tool; (2) follow-up PRs clean up existing stale refs (gate.yml already covered by #359; others queued); (3) once baseline is clean, add to gate.yml lint job. Composes with: - Otto-213 version-numbers-require-websearch memory - Otto-212 use-latest-tags + security-hygiene directive - Otto-210/211 macOS-is-free + M1-not-Intel corrections - FACTORY-HYGIENE row #43 safe-pattern compliance - Analogous pattern to audit-cross-platform-parity.sh (detect-only-first, enforce-when-baseline-green) Test plan: - Runs clean when no stale labels present - Exits 2 with clear message when stale labels present - Warns when allow-list >30 days old - Shellcheck clean (SC2001 note acknowledged; the non-bash-4 sed-style substitution is intentional for macOS default-bash-3.x compatibility per FACTORY- HYGIENE row #51 cross-platform parity) - Portable: no mapfile (bash 4+ only); uses while-read loop pattern that works in bash 3.x Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…Otto-213 stale-version lesson (#360) * tools: lint/runner-version-freshness.sh — structural enforcement for Otto-213 durable lesson Otto-214 implementation of the tooling-level enforcement I proposed Otto-213. Memory-alone was not sufficient to stop the "write a stale version number" recurrence pattern; this script adds a CI-fail gate. Behavior: - Walks .github/workflows/*.yml files - Extracts runs-on: + os: matrix lines - Fails (exit 2) if any line references a STALE runner version (ubuntu-22.04, macos-14, macos-15, windows-2022, ubuntu-20.04, macos-13, macos-15-intel, etc.) - Warns (exit 3) if the allow-list itself is stale (>30 days since LAST_VERIFIED) - Prints the canonical list of ALLOWED labels on failure + the authoritative GitHub docs URL for re-verification Allow-list verified 2026-04-24 via https://docs.github.com/en/actions/how-tos/write-workflows/choose-where-workflows-run/choose-the-runner-for-a-job#standard-github-hosted-runners-for-public-repositories exact quote "Use of the standard GitHub-hosted runners is free and unlimited on public repositories." First-run detects 13 stale-label hits across codeql.yml, gate.yml, github-settings-drift.yml (plus stale comment- block references in gate.yml from the pre-correction history). These will be cleaned up by PR #359 for gate.yml; codeql.yml + github-settings-drift.yml need separate follow-up PRs. Does NOT wire into gate.yml automatically — separate step to add the lint check after the baseline is green. Premature enforcement would block every current PR. Sequencing: (1) this PR ships the tool; (2) follow-up PRs clean up existing stale refs (gate.yml already covered by #359; others queued); (3) once baseline is clean, add to gate.yml lint job. Composes with: - Otto-213 version-numbers-require-websearch memory - Otto-212 use-latest-tags + security-hygiene directive - Otto-210/211 macOS-is-free + M1-not-Intel corrections - FACTORY-HYGIENE row #43 safe-pattern compliance - Analogous pattern to audit-cross-platform-parity.sh (detect-only-first, enforce-when-baseline-green) Test plan: - Runs clean when no stale labels present - Exits 2 with clear message when stale labels present - Warns when allow-list >30 days old - Shellcheck clean (SC2001 note acknowledged; the non-bash-4 sed-style substitution is intentional for macOS default-bash-3.x compatibility per FACTORY- HYGIENE row #51 cross-platform parity) - Portable: no mapfile (bash 4+ only); uses while-read loop pattern that works in bash 3.x Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * drain(#360 P0×2 + P1+P2+P1+P1 Codex): regex-escape + BSD-grep portable + comment-strip + rolling-alias forbidden + warn-only exit Six Codex findings on tools/lint/runner-version-freshness.sh: P0 (line 133) — regex-metachar escape: `stale_pattern` was built from raw label strings; `.` in ubuntu-22.04 was a regex wildcard, producing false matches/ misses. Added `escape_for_regex` helper that escapes . + * ? ( ) [ ] { } | \ / before alternation. P0 (line 149) — BSD-grep portability: `\b` word-boundary doesn't work in BSD grep (macOS default; treated as backspace per POSIX ERE). Replaced with explicit non-word boundaries: `([^A-Za-z0-9_]|^)` start + `([^A-Za-z0-9_]|$)` end, expressed without backrefs so it works in both GNU and BSD grep. P1 (line 149-1) — exclude comments: Stale-label-in-comment was triggering false positives. Added a comment-stripping pre-filter (`grep -vE '^[[:space:]]*#'`) so YAML comments are excluded from the scan. P1 (line 149-2) — explicit-file-not-found masking: `grep ... 2>/dev/null || true` silently swallowed missing- file errors and reported 'ok' for nothing-actually-linted. Added an explicit `[ ! -r "$file" ]` precheck that fails loud (exit 2) rather than passing silent. P1 (line 73) — rolling-aliases forbidden by convention: ALLOWED_LABELS included ubuntu-latest / windows-latest / macos-latest, contradicting the repo convention of pinned major-OS-version labels. Removed from ALLOWED_LABELS, added a separate ROLLING_ALIASES forbidden list, added a distinct error-class scan ('ROLLING-ALIAS RUNNER LABEL') so contributors get a different error message than for stale-version pins. Same fail=1 flag, different operator message. P2 (line 179) — warn-only exit on stale freshness: Header documents this as warning-only; code exited 3 (which some CI configurations treat as failure). Updated to exit 0 on stale-freshness-only path; warning is still printed to stderr. Stale-version-detection still exit 2 (a real failure). Smoke-test note: the new script now flags ubuntu-22.04 in gate.yml as stale (real finding) — exit 2 with the expected output. gate.yml's own runner-pin upgrade is out of scope for this PR; will land separately. * drain(#360 P1+P2 Codex): quoted-matrix-entries + inline-comment stripping Two more substantive Codex findings: P1 (line 183) — quoted matrix entries missed: The matrix-entry prefilter was `^[[:space:]]*-[[:space:]]+` which only matched bare `- <label>`. Common YAML syntax `- "ubuntu-22.04"` or `- 'macos-15'` was being missed. Updated prefilter to `^[[:space:]]*-[[:space:]]+(['\"]?)` which optionally consumes a leading single or double quote. Smoke-tested with mixed quoting + matrix block: catches both forms now. P2 (line 179) — trailing inline comments not stripped: `runs-on: ubuntu-24.04 # was ubuntu-22.04` was falsely flagging `ubuntu-22.04` in the trailing comment. Added a second sed pass: `sed -E 's/[[:space:]]+#.*$//'` strips everything after the first ` #` (YAML-spec comment-start sentinel with required leading space). Conservative: doesn't handle `#` inside quoted strings (rare in workflow YAML). Smoke-tested: trailing comments correctly stripped. --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
|
Closing as superseded by current main state. The 4-runner PR-gate matrix INTENT (Otto-210..213) was delivered via subsequent CI iteration — current required-status-checks list includes:
The macos-m1-specific change is superseded by macos-26 promotion. The nightly-cross-platform deletion intent is partially preserved via current branch protection (slim variant lives but is non-required, per B-0008 which captures the macos+slim nightly-move investigation). If there's substantive content here that hasn't been absorbed into current state, please flag and I'll reopen + cherry-pick. Per Otto-321 force-push discipline + Otto-322 self-direction: closing-as-superseded is a reversible Edge runner judgment call. Reopen if disagreed. 🤖 Edge runner triage by Claude Opus 4.7 |
Pull request was closed
Summary
Four related maintainer corrections landed in one commit to avoid further queue pressure. Each correction sourced from the primary GitHub docs page (standard runners for public repos).
Corrections
Otto-210 — macOS IS free on public repos. My earlier Otto-164 verification was WRONG. Primary-source quote: "Use of the standard GitHub-hosted runners is free and unlimited on public repositories." Standard runners (including
macos-*arm64) qualify.Otto-211 — M1 not Intel; Linux arm alongside x64.
macos-*-intelis the Intel family. We want Apple Silicon (arm64). Plus Linux ARM coverage.Otto-212 — latest actual version, not stale pin. My initial fix used
macos-14. Training data is stale; I had the correct data from an earlier WebFetch and still wrotemacos-14out of habit.Otto-213 — pinned version = security hygiene + latest-actual = good practice. Pin to a specific current version, not a rolling
-latesttag AND not a stale version number. Every version-number decision requires a WebSearch per the durable lesson now captured in memory.Matrix — 4 runners, all verified on the standard-list table
ubuntu-slim— minimal Linux x64, standard runnerubuntu-24.04— Linux x64, latest GA Ubuntu LTSubuntu-24.04-arm— Linux arm64 (no -latest-arm tag yet)macos-26— macOS 26 Tahoe on Apple Silicon, GA'd 2026-02-26Windows deferred per Otto-211 ("windows will come later on both zeta and acehack"). When it lands, add
windows-2025orwindows-latestper the standard-list table.Changes
gate.ymlmatrix: wasfromJSONcanonical-vs-forks split with[ubuntu-22.04]/[ubuntu-22.04, macos-14]; now static[ubuntu-slim, ubuntu-24.04, ubuntu-24.04-arm, macos-26]everywhere.gate.ymlcomment block rewritten to cite Otto-210 URL + exact quote + Otto-211/212/213 lineage.gate.ymlnon-matrix jobs (Semgrep, shellcheck, actionlint, markdownlint):ubuntu-22.04→ubuntu-24.04.nightly-cross-platform.ymlDELETED — redundant now that gate covers mac + linux (both variants) + slim per-PR. The nightly workflow had a cost-capping narrative based on the wrong Otto-164 pricing verification; with correct Otto-210 free-for-public, per-PR is simpler.Out of scope (follow-ups)
ubuntu-22.04(memory-*, codeql, github-settings-drift). Systematic unpin across the repo is a separate PR.lucent-kskparallel landing (cross-repo, needs separate push + verification per Otto-140).Test plan
Compounding memories saved
feedback_macos_is_free_on_public_repos_otto_164_verification_was_wrong_*feedback_version_numbers_always_websearch_training_data_stale_by_definition_*🤖 Generated with Claude Code