diff --git a/.github/workflows/budget-snapshot-cadence.yml b/.github/workflows/budget-snapshot-cadence.yml index 296c2e13..147ce486 100644 --- a/.github/workflows/budget-snapshot-cadence.yml +++ b/.github/workflows/budget-snapshot-cadence.yml @@ -82,7 +82,7 @@ concurrency: jobs: snapshot: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 5 steps: diff --git a/.github/workflows/gate.yml b/.github/workflows/gate.yml index 560b6a7f..016aa3c4 100644 --- a/.github/workflows/gate.yml +++ b/.github/workflows/gate.yml @@ -13,8 +13,11 @@ # — too slow for per-PR gating; runs on every push to main + # nightly schedule (in practice every merge, since direct # pushes are blocked by branch protection). -# Lint jobs pinned to ubuntu-22.04 (short-lived, OS-independent -# work). Windows legs deferred to peer-harness milestone. +# Lint jobs pinned to ubuntu-24.04 (short-lived, OS-independent +# work; bumped from 22.04 on 2026-04-28 per Aaron's "we better +# not be using that old version of ubuntu" + Otto-247 version- +# currency WebSearch — ubuntu-latest = 24.04 since Jan 2025). +# Windows legs deferred to peer-harness milestone. # - Third-party actions SHA-pinned by full 40-char commit SHA; # trailing `# vX.Y.Z` comments for humans. # - permissions: contents: read at the workflow level; no job @@ -219,7 +222,7 @@ jobs: # elevation design (docs/research/threat-model-elevation.md). name: lint (semgrep) timeout-minutes: 10 - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout @@ -250,20 +253,64 @@ jobs: # See openspec/specs/static-analysis/profiles/shell.md. name: lint (shellcheck) timeout-minutes: 5 - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Cache install.sh outputs (mise runtimes + dotnet tools + verifier jars) + # Comprehensive cache of everything `tools/setup/install.sh` + # writes — keeps dev laptops and CI runners as close to the + # same state as possible per Aaron's 2026-04-28 directive: + # "we want to make sure dev seutp and build machine setup + # are as close to the same a possible" + # "why not cache the whole install/setup" + # Without comprehensive caching every CI run hits CDNs cold + # (mise.run + GitHub releases for bun/shellcheck/actionlint + + # NuGet + Lean toolchain). Transient 502s become avoidable + # failures rather than first-run-only cost. + # Cache key hashes BOTH .mise.toml (runtime versions) AND + # tools/setup/** (install logic itself) so changes to either + # invalidate cache → vanilla install path gets re-tested + # whenever the install discipline changes. + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: | + ~/.local/bin/mise + ~/.local/share/mise + ~/.cache/mise + ~/.dotnet/tools + ~/.elan + ~/.config/zeta + tools/tla + tools/alloy + key: install-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('.mise.toml', 'tools/setup/**', 'global.json') }} + - name: Install toolchain via three-way-parity script (GOVERNANCE §24) # Installs shellcheck via mise (pinned in .mise.toml). Single # source of truth — the same version on dev laptops + CI # runners. Prior step relied on shellcheck shipping pre- - # installed on ubuntu-22.04, which broke parity (dev machines + # installed on ubuntu (any version), which broke parity (dev machines # may have a different version) and wouldn't survive newer # runner images like ubuntu-slim that don't ship shellcheck. - run: ./tools/setup/install.sh + # Note: install.sh is idempotent (detect-first-install-else-update); + # safe to run on every CI invocation including cache-hit (it + # short-circuits when tools are already present). + # CI-level retry per Aaron 2026-04-28: PR #23 failed because + # mise's internal 3-attempt retry exhausted on a github + # releases CDN 502 for bun-1.3.13. CI runs are non-interactive + # so retry is safe; dev runs stay interactive (user decides). + # Backoff: 10s, 30s — matches the typical CDN-blip duration. + run: | + set -euo pipefail + for attempt in 1 2 3; do + if ./tools/setup/install.sh; then exit 0; fi + [ "$attempt" = "3" ] && { echo "install.sh failed after 3 attempts"; exit 1; } + backoff=$((attempt * 20 - 10)) + echo "install.sh attempt $attempt failed; retrying in ${backoff}s..." >&2 + sleep "$backoff" + done - name: Run shellcheck # Scope: Zeta's own scripts under `tools/setup/` only — @@ -295,19 +342,41 @@ jobs: # github-actions.md. name: lint (actionlint) timeout-minutes: 5 - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Cache install.sh outputs (mise runtimes + dotnet tools + verifier jars) + # Comprehensive cache — see lint-shell job above for the + # rationale (Aaron 2026-04-28 dev-CI parity directive + + # transient 502 prevention). Same cache key shape so all + # lint jobs share the cache when toolchain unchanged. + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: | + ~/.local/bin/mise + ~/.local/share/mise + ~/.cache/mise + ~/.dotnet/tools + ~/.elan + ~/.config/zeta + tools/tla + tools/alloy + key: install-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('.mise.toml', 'tools/setup/**', 'global.json') }} + - name: Install toolchain via three-way-parity script (GOVERNANCE §24) - # Installs actionlint via mise (pinned in .mise.toml). Single - # source of truth — the same version flows to dev laptops and - # CI. Replaces a prior inline `Download actionlint (pinned)` - # step whose version was maintained separately from the - # declarative pin. - run: ./tools/setup/install.sh + # See lint-shell job above for retry rationale (Aaron 2026-04-28). + run: | + set -euo pipefail + for attempt in 1 2 3; do + if ./tools/setup/install.sh; then exit 0; fi + [ "$attempt" = "3" ] && { echo "install.sh failed after 3 attempts"; exit 1; } + backoff=$((attempt * 20 - 10)) + echo "install.sh attempt $attempt failed; retrying in ${backoff}s..." >&2 + sleep "$backoff" + done - name: Run actionlint # -ignore 'unknown permission scope "administration"' is a @@ -338,7 +407,7 @@ jobs: # layer. name: lint (tick-history order) timeout-minutes: 2 - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout @@ -362,7 +431,7 @@ jobs: # merge-conflict resolution. name: lint (no conflict markers) timeout-minutes: 2 - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout @@ -390,7 +459,7 @@ jobs: # backfilled all pre-existing violations to 0. name: lint (archive header §33) timeout-minutes: 2 - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout @@ -411,7 +480,7 @@ jobs: # No untrusted input used in run: — only a fixed repo path. name: lint (no empty dirs) timeout-minutes: 3 - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout @@ -427,21 +496,43 @@ jobs: # See openspec/specs/static-analysis/profiles/markdown.md. name: lint (markdownlint) timeout-minutes: 5 - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Cache install.sh outputs (mise runtimes + dotnet tools + verifier jars) + # Comprehensive cache — see lint-shell job above for the + # rationale. PR #23 2026-04-28 root-cause was a transient + # 502 on bun-1.3.13 download from GitHub releases CDN + # (bun is what mise's npm: backend uses to run + # markdownlint-cli2); cache hit avoids the CDN entirely. + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: | + ~/.local/bin/mise + ~/.local/share/mise + ~/.cache/mise + ~/.dotnet/tools + ~/.elan + ~/.config/zeta + tools/tla + tools/alloy + key: install-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('.mise.toml', 'tools/setup/**', 'global.json') }} + - name: Install toolchain via three-way-parity script (GOVERNANCE §24) - # Installs markdownlint-cli2 via mise (pinned in .mise.toml as - # `npm:markdownlint-cli2`). Single source of truth — same - # version on dev laptops + CI runners. Prior step hardcoded - # the version in this workflow (0.18.1) which drifted - # behind the pin discipline the rest of the lints use and - # violated the human maintainer's "update declaratively - # everywhere" ask (2026-04-24). - run: ./tools/setup/install.sh + # See lint-shell job above for retry rationale (Aaron 2026-04-28 + # PR #23 mise+bun-1.3.13 502). + run: | + set -euo pipefail + for attempt in 1 2 3; do + if ./tools/setup/install.sh; then exit 0; fi + [ "$attempt" = "3" ] && { echo "install.sh failed after 3 attempts"; exit 1; } + backoff=$((attempt * 20 - 10)) + echo "install.sh attempt $attempt failed; retrying in ${backoff}s..." >&2 + sleep "$backoff" + done - name: Run markdownlint run: mise exec -- markdownlint-cli2 "**/*.md" diff --git a/.github/workflows/memory-index-duplicate-lint.yml b/.github/workflows/memory-index-duplicate-lint.yml index 29d8c32a..c4c94b1e 100644 --- a/.github/workflows/memory-index-duplicate-lint.yml +++ b/.github/workflows/memory-index-duplicate-lint.yml @@ -17,7 +17,7 @@ name: memory-index-duplicate-lint # - Explicit minimum `permissions: contents: read` # - No user-authored context referenced # - Concurrency group + cancel-in-progress: false -# - runs-on: ubuntu-22.04 pinned +# - runs-on: ubuntu-24.04 pinned # # See: # - tools/hygiene/audit-memory-index-duplicates.sh (the tool) @@ -48,7 +48,7 @@ concurrency: jobs: lint: name: lint memory/MEMORY.md for duplicate link targets - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/resume-diff.yml b/.github/workflows/resume-diff.yml index acbbff61..3812193d 100644 --- a/.github/workflows/resume-diff.yml +++ b/.github/workflows/resume-diff.yml @@ -34,7 +34,7 @@ # the comment. # - concurrency: workflow-scoped; cancel-in-progress for PR # events. -# - Runner digest-pinned (ubuntu-22.04). +# - Runner digest-pinned (ubuntu-24.04). # - Graceful no-change handling: if the diff has no claim- # bearing lines, posts a clarifying message and passes. # Does not fail the PR. @@ -58,7 +58,7 @@ concurrency: jobs: resume-diff: name: claim-level diff - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 5 permissions: contents: read diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index a19dbed7..0563cfc5 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -52,7 +52,7 @@ concurrency: jobs: analysis: name: scorecard analysis - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 timeout-minutes: 10 permissions: