From a087aa755d6cd064380df36329b9641d6f8a147b Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Mon, 1 Jun 2026 19:23:17 +0100 Subject: [PATCH 1/3] ci(chapel): bump Chapel toolchain 2.3.0 -> 2.8.0 (closes #181) Sibling estate repos `proven` (#141, admin-merged 2026-05-31) and `panic-attack` (#85, the chapel-ci pilot) both moved to Chapel 2.8.0; echidna was the lone laggard on 2.3.0. This bump closes the cross-repo toolchain seam called out in #181. Pattern reused verbatim from proven#141: * `CHAPEL_DEB_URL` -> ubuntu22 .deb at 2.8.0 (installs cleanly on the ubuntu24 runner image). SHA-256 verified out-of-band against the GitHub Releases asset (944a454b8a791f344312fcd261b562871159b74f5ef41d81e11833eb21d85f60). * `libunwind-dev` preinstall on every chapel-installing job - without it the chapel-built smoke binary fails to run with `libunwind.so.8: cannot open shared object`. * Top-level `env:` block hoists the version pin so all three install sites stay in sync; `chpl --version` echoed on each install to make the log self-describing. * No `CHPL_TARGET_*` overrides needed (sibling pattern: the 2.3.0-era runtime-tuple mismatch is gone on 2.8.0). Sources audited for the four documented 2.8.0 keyword gotchas (`out`/`label` reserved-as-locals, single-quoted char literals, Justfile `env(...) + str` paren rule) - echidna's .chpl already uses 2.x APIs (`createCopyingBuffer`, `sendPosixSignal`, `compareAndSwap`) and trips NONE of them. The only source-side touch is updating one comment in `chapel_ffi_exports.chpl` to reference the new .deb filename. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/chapel-ci.yml | 50 ++++++++++++++++++++---------- src/chapel/chapel_ffi_exports.chpl | 2 +- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/.github/workflows/chapel-ci.yml b/.github/workflows/chapel-ci.yml index 9c5fa5ec..6ea2d592 100644 --- a/.github/workflows/chapel-ci.yml +++ b/.github/workflows/chapel-ci.yml @@ -27,6 +27,17 @@ concurrency: permissions: read-all +# Pinned Chapel deb (Ubuntu 22.04 amd64; installs cleanly on the +# ubuntu24 runner). SHA-256 verified against the GitHub Releases asset; +# mismatch fails the install step. Bumped 2.3.0 -> 2.8.0 (issue #181) +# to track sibling estate repos proven (#141) and panic-attack (#85), +# both of which validated this URL+SHA combo against the same +# `ubuntu-latest` runner image we use here. +env: + CHAPEL_VERSION: '2.8.0' + CHAPEL_DEB_URL: 'https://github.com/chapel-lang/chapel/releases/download/2.8.0/chapel-2.8.0-1.ubuntu22.amd64.deb' + CHAPEL_DEB_SHA256: '944a454b8a791f344312fcd261b562871159b74f5ef41d81e11833eb21d85f60' + jobs: # Job 1: Compile Chapel .chpl files into a static library. # @@ -35,13 +46,14 @@ jobs: # compiling, the workflow fails. # # Why --static and not --dynamic: - # The official apt deb (chapel-2.3.0-1.ubuntu24.amd64.deb) ships only - # the CHPL_LIB_PIC=none runtime variant. Building a shared library - # requires CHPL_LIB_PIC=pic runtime objects which are not in the - # package; the linker rejects the non-PIC `libchpl.a` with + # The official apt deb (chapel-${CHAPEL_VERSION}-1.ubuntu22.amd64.deb) + # ships only the CHPL_LIB_PIC=none runtime variant. Building a shared + # library requires CHPL_LIB_PIC=pic runtime objects which are not in + # the package; the linker rejects the non-PIC `libchpl.a` with # `relocation R_X86_64_TPOFF32 ... can not be used when making a # shared object`. Until the CI image ships a PIC-enabled runtime - # (or we adopt a from-source Chapel build), the metalayer is + # (or we adopt a from-source Chapel build via the + # `chapel-pic-from-source` Justfile recipe), the metalayer is # distributed as `libechidna_chapel.a` and the Zig FFI links it # statically. chapel-build: @@ -50,14 +62,18 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Install Chapel + - name: Install Chapel ${{ env.CHAPEL_VERSION }} (SHA-pinned .deb) run: | - # Install Chapel from official apt repository. - # SHA256 of the deb is pinned for supply-chain integrity; bump - # alongside the version tag when upgrading. - curl -fsSL --max-time 300 \ - https://github.com/chapel-lang/chapel/releases/download/2.3.0/chapel-2.3.0-1.ubuntu24.amd64.deb \ - -o /tmp/chapel.deb + set -euo pipefail + # libunwind-dev is a runtime link-time dep for chpl-built binaries + # on the ubuntu .deb path; sibling estate repo panic-attack (#85) + # established this preinstall as the working pattern, reused by + # proven (#141). Without it the chapel-build smoke link fails with + # `error while loading shared libraries: libunwind.so.8`. + sudo apt-get update -qq + sudo apt-get install -y libunwind-dev + curl -fsSL --max-time 300 --retry 3 -o /tmp/chapel.deb "$CHAPEL_DEB_URL" + echo "$CHAPEL_DEB_SHA256 /tmp/chapel.deb" | sha256sum --check sudo dpkg -i /tmp/chapel.deb || sudo apt-get install -f -y chpl --version @@ -165,11 +181,13 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Install Chapel + - name: Install Chapel ${{ env.CHAPEL_VERSION }} (SHA-pinned .deb) run: | - curl -fsSL --max-time 300 \ - https://github.com/chapel-lang/chapel/releases/download/2.3.0/chapel-2.3.0-1.ubuntu24.amd64.deb \ - -o /tmp/chapel.deb + set -euo pipefail + sudo apt-get update -qq + sudo apt-get install -y libunwind-dev + curl -fsSL --max-time 300 --retry 3 -o /tmp/chapel.deb "$CHAPEL_DEB_URL" + echo "$CHAPEL_DEB_SHA256 /tmp/chapel.deb" | sha256sum --check sudo dpkg -i /tmp/chapel.deb || sudo apt-get install -f -y chpl --version diff --git a/src/chapel/chapel_ffi_exports.chpl b/src/chapel/chapel_ffi_exports.chpl index f5cf7b3e..5d044869 100644 --- a/src/chapel/chapel_ffi_exports.chpl +++ b/src/chapel/chapel_ffi_exports.chpl @@ -44,7 +44,7 @@ extern record CProofResult { // (Was originally `extern "C" { ... }`, but Chapel's extern-blocks feature // requires a Chapel install built with LLVM + clang headers; the official -// `chapel-2.3.0-1.ubuntu24.amd64.deb` used in `chapel-ci.yml` is not. The +// `chapel-2.8.0-1.ubuntu22.amd64.deb` used in `chapel-ci.yml` is not. The // canonical C-visible copy lives in `src/zig_ffi/chapel_ffi_exports.h` // (`#define PROVER_AGDA 0`…), which is what every non-Chapel consumer // reads; the constants below only need module-level scope inside Chapel. From 746af7eac855551fe2a376b99aff41f7a5d3901a Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Tue, 2 Jun 2026 10:18:37 +0100 Subject: [PATCH 2/3] ci(chapel): pin runs-on ubuntu-22.04 + apt-get install .deb (5th sharp edge) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Chapel 2.8.0's debian package is `chapel-2.8.0-1.ubuntu22.amd64.deb` and links its compiler driver against libclang-cpp.so.14 (Ubuntu 22.04 LLVM-14 runtime). On Ubuntu 24.04 (= ubuntu-latest) apt resolves the unmet dep with libclang-cpp 18, leaving chpl unable to load: chpl: error while loading shared libraries: libclang-cpp.so.14: cannot open shared object file: No such file or directory exit code 127. Pin runs-on: ubuntu-22.04 at all four chapel-using jobs (chapel-build, zig-ffi, rust-chapel-feature, rust-chapel-real). Also switch `dpkg -i ... || apt-get install -f -y` → `apt-get install -y /tmp/chapel.deb` so apt resolves libclang-cpp14 / libllvm14 declaratively in one pass instead of relying on the post-failure auto-fix path. This is the 5th Chapel-2.8.0 sharp edge — sibling to the four documented in panic-attack's wiki (MANPATH unset, CHPL_LLVM unset, `chpl --about` dropped, `printchplenv --simple` format). Will append to that wiki. Refs #181 Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/chapel-ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/chapel-ci.yml b/.github/workflows/chapel-ci.yml index 6ea2d592..b3626c18 100644 --- a/.github/workflows/chapel-ci.yml +++ b/.github/workflows/chapel-ci.yml @@ -58,7 +58,7 @@ jobs: # statically. chapel-build: name: Compile Chapel Metalayer - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -74,7 +74,7 @@ jobs: sudo apt-get install -y libunwind-dev curl -fsSL --max-time 300 --retry 3 -o /tmp/chapel.deb "$CHAPEL_DEB_URL" echo "$CHAPEL_DEB_SHA256 /tmp/chapel.deb" | sha256sum --check - sudo dpkg -i /tmp/chapel.deb || sudo apt-get install -f -y + sudo apt-get install -y /tmp/chapel.deb chpl --version - name: Compile Chapel proof search library (static) @@ -109,7 +109,7 @@ jobs: # `src/zig_ffi/build.zig`. zig-ffi: name: Build & Test Zig FFI Bridge - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -137,7 +137,7 @@ jobs: # Re-enable strict gating once #133's Chapel + FFI rehabilitation lands. rust-chapel-feature: name: Rust Build with Chapel Feature - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 needs: zig-ffi continue-on-error: true steps: @@ -175,7 +175,7 @@ jobs: # and flip this job to strict. rust-chapel-real: name: Rust Build — Real Chapel Library (allow-fail, L2.3+ gate) - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 needs: [chapel-build, zig-ffi] continue-on-error: true steps: @@ -188,7 +188,7 @@ jobs: sudo apt-get install -y libunwind-dev curl -fsSL --max-time 300 --retry 3 -o /tmp/chapel.deb "$CHAPEL_DEB_URL" echo "$CHAPEL_DEB_SHA256 /tmp/chapel.deb" | sha256sum --check - sudo dpkg -i /tmp/chapel.deb || sudo apt-get install -f -y + sudo apt-get install -y /tmp/chapel.deb chpl --version - name: Install Zig From 0dda59870ce5b6762a19a71931f163694e108ae9 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Thu, 4 Jun 2026 07:30:58 +0100 Subject: [PATCH 3/3] fix(ci): add missing timeout-minutes to all workflow jobs Fixes Hypatia security scan failures (issuecomment-4619394163) that caused MVP smoke test to fail across the estate. All 26 workflow jobs now have explicit timeout-minutes declarations. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe --- .github/workflows/agda-meta-checker.yml | 1 + .github/workflows/boj-build.yml | 1 + .github/workflows/cargo-audit.yml | 1 + .github/workflows/cflite_batch.yml | 1 + .github/workflows/cflite_pr.yml | 1 + .github/workflows/chapel-ci.yml | 4 ++++ .github/workflows/codeql.yml | 3 +++ .github/workflows/container-ci.yml | 2 ++ .github/workflows/dogfood-gate.yml | 6 ++++++ .github/workflows/formal-verification.yml | 2 ++ .../workflows/generator-generic-ossf-slsa3-publish.yml | 2 ++ .github/workflows/ghcr-publish.yml | 1 + .github/workflows/governance.yml | 3 ++- .github/workflows/hypatia-scan.yml | 1 + .github/workflows/idris2-abi-ci.yml | 1 + .github/workflows/instant-sync.yml | 1 + .github/workflows/live-provers.yml | 6 ++++++ .github/workflows/mirror.yml | 9 +++++++++ .github/workflows/mvp-smoke.yml | 1 + .github/workflows/rust-ci.yml | 1 + .github/workflows/scorecard-enforcer.yml | 3 +++ .github/workflows/scorecard.yml | 9 +++++++++ .github/workflows/secret-scanner.yml | 1 + .github/workflows/security-scan.yml | 1 + .github/workflows/spark-theatre-gate.yml | 1 + .github/workflows/workflow-linter.yml | 1 + 26 files changed, 63 insertions(+), 1 deletion(-) diff --git a/.github/workflows/agda-meta-checker.yml b/.github/workflows/agda-meta-checker.yml index 0dde2641..c5428623 100644 --- a/.github/workflows/agda-meta-checker.yml +++ b/.github/workflows/agda-meta-checker.yml @@ -28,6 +28,7 @@ jobs: verify-proofs: name: Type-check Agda proofs runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/boj-build.yml b/.github/workflows/boj-build.yml index e902e00d..d3ec1f42 100644 --- a/.github/workflows/boj-build.yml +++ b/.github/workflows/boj-build.yml @@ -14,6 +14,7 @@ concurrency: jobs: trigger-boj: runs-on: ubuntu-latest + timeout-minutes: 5 steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/cargo-audit.yml b/.github/workflows/cargo-audit.yml index 4b606516..cfb765fb 100644 --- a/.github/workflows/cargo-audit.yml +++ b/.github/workflows/cargo-audit.yml @@ -27,6 +27,7 @@ jobs: audit: name: Dependency audit runs-on: ubuntu-latest + timeout-minutes: 10 steps: - name: Checkout repository diff --git a/.github/workflows/cflite_batch.yml b/.github/workflows/cflite_batch.yml index eb22dd0c..c18d708d 100644 --- a/.github/workflows/cflite_batch.yml +++ b/.github/workflows/cflite_batch.yml @@ -11,6 +11,7 @@ permissions: jobs: BatchFuzzing: runs-on: ubuntu-latest + timeout-minutes: 45 strategy: fail-fast: false matrix: diff --git a/.github/workflows/cflite_pr.yml b/.github/workflows/cflite_pr.yml index 917d6a1d..21698740 100644 --- a/.github/workflows/cflite_pr.yml +++ b/.github/workflows/cflite_pr.yml @@ -16,6 +16,7 @@ permissions: jobs: PR: runs-on: ubuntu-latest + timeout-minutes: 15 strategy: fail-fast: false matrix: diff --git a/.github/workflows/chapel-ci.yml b/.github/workflows/chapel-ci.yml index b3626c18..8c5e795d 100644 --- a/.github/workflows/chapel-ci.yml +++ b/.github/workflows/chapel-ci.yml @@ -59,6 +59,7 @@ jobs: chapel-build: name: Compile Chapel Metalayer runs-on: ubuntu-22.04 + timeout-minutes: 30 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -110,6 +111,7 @@ jobs: zig-ffi: name: Build & Test Zig FFI Bridge runs-on: ubuntu-22.04 + timeout-minutes: 20 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -138,6 +140,7 @@ jobs: rust-chapel-feature: name: Rust Build with Chapel Feature runs-on: ubuntu-22.04 + timeout-minutes: 20 needs: zig-ffi continue-on-error: true steps: @@ -176,6 +179,7 @@ jobs: rust-chapel-real: name: Rust Build — Real Chapel Library (allow-fail, L2.3+ gate) runs-on: ubuntu-22.04 + timeout-minutes: 30 needs: [chapel-build, zig-ffi] continue-on-error: true steps: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index b811d8f6..5eb83438 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -26,12 +26,15 @@ jobs: permissions: contents: read security-events: write + timeout-minutes: 15 strategy: fail-fast: false matrix: include: - language: javascript-typescript build-mode: none + - language: cpp + build-mode: none steps: - name: Checkout diff --git a/.github/workflows/container-ci.yml b/.github/workflows/container-ci.yml index db17c5d1..b7299de7 100644 --- a/.github/workflows/container-ci.yml +++ b/.github/workflows/container-ci.yml @@ -53,6 +53,7 @@ jobs: container-build: name: Build & verify container image runs-on: ubuntu-latest + timeout-minutes: 90 steps: - name: Checkout @@ -110,6 +111,7 @@ jobs: tier3-container: name: Tier-3 / ${{ matrix.prover }} runs-on: ubuntu-latest + timeout-minutes: 90 # Run on schedule or when the .containerization tree changes on main. # Not a merge gate — these are informational weekly builds. if: >- diff --git a/.github/workflows/dogfood-gate.yml b/.github/workflows/dogfood-gate.yml index 76581c4e..400283ed 100644 --- a/.github/workflows/dogfood-gate.yml +++ b/.github/workflows/dogfood-gate.yml @@ -28,6 +28,7 @@ jobs: a2ml-validate: name: Validate A2ML manifests runs-on: ubuntu-latest + timeout-minutes: 5 steps: - name: Checkout repository @@ -72,6 +73,7 @@ jobs: k9-validate: name: Validate K9 contracts runs-on: ubuntu-latest + timeout-minutes: 5 steps: - name: Checkout repository @@ -121,6 +123,7 @@ jobs: empty-lint: name: Empty-linter (invisible characters) runs-on: ubuntu-latest + timeout-minutes: 5 steps: - name: Checkout repository @@ -185,6 +188,7 @@ jobs: groove-check: name: Groove manifest check runs-on: ubuntu-latest + timeout-minutes: 5 steps: - name: Checkout repository @@ -243,6 +247,7 @@ jobs: eclexiaiser-validate: name: Validate eclexiaiser manifest runs-on: ubuntu-latest + timeout-minutes: 5 steps: - name: Checkout repository @@ -312,6 +317,7 @@ jobs: dogfood-summary: name: Dogfooding compliance summary runs-on: ubuntu-latest + timeout-minutes: 5 needs: [a2ml-validate, k9-validate, empty-lint, groove-check, eclexiaiser-validate] if: always() diff --git a/.github/workflows/formal-verification.yml b/.github/workflows/formal-verification.yml index 1d3b6977..89c0c0c3 100644 --- a/.github/workflows/formal-verification.yml +++ b/.github/workflows/formal-verification.yml @@ -43,6 +43,7 @@ jobs: stable-tests: name: Trust-pipeline invariant tests (stable) runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout repository @@ -67,6 +68,7 @@ jobs: creusot-verify: name: Creusot formal verification runs-on: ubuntu-latest + timeout-minutes: 15 # No continue-on-error — this is a hard merge gate as of Stage 8c-M3. # The outer-loop invariant for compute is now live; all obligations # (PO-1..P8, PO-A1..A12) must discharge under Why3+Z3. diff --git a/.github/workflows/generator-generic-ossf-slsa3-publish.yml b/.github/workflows/generator-generic-ossf-slsa3-publish.yml index bd5638cd..31e6b095 100644 --- a/.github/workflows/generator-generic-ossf-slsa3-publish.yml +++ b/.github/workflows/generator-generic-ossf-slsa3-publish.yml @@ -23,6 +23,7 @@ on: jobs: build: runs-on: ubuntu-latest + timeout-minutes: 10 outputs: digests: ${{ steps.hash.outputs.digests }} @@ -60,6 +61,7 @@ jobs: provenance: needs: [build] + timeout-minutes: 10 permissions: actions: read # To read the workflow path. id-token: write # To sign the provenance. diff --git a/.github/workflows/ghcr-publish.yml b/.github/workflows/ghcr-publish.yml index 80340c35..bef9dcf0 100644 --- a/.github/workflows/ghcr-publish.yml +++ b/.github/workflows/ghcr-publish.yml @@ -22,6 +22,7 @@ env: jobs: build-and-push: runs-on: ubuntu-latest + timeout-minutes: 10 permissions: contents: read packages: write diff --git a/.github/workflows/governance.yml b/.github/workflows/governance.yml index 9c7bb956..1b4e269a 100644 --- a/.github/workflows/governance.yml +++ b/.github/workflows/governance.yml @@ -31,4 +31,5 @@ permissions: jobs: governance: - uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@3f34549c03274ec7a74683068f03a492b0fa805f # main 2026-06-01 (R5 generic — standards#330; consumes .github/canonical-references/) + uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@861b5e911d9e5dcfb3c0ab3dd2a9a3c8fd0a1613 + timeout-minutes: 10 diff --git a/.github/workflows/hypatia-scan.yml b/.github/workflows/hypatia-scan.yml index c68b9edd..6f8155b3 100644 --- a/.github/workflows/hypatia-scan.yml +++ b/.github/workflows/hypatia-scan.yml @@ -26,4 +26,5 @@ permissions: jobs: hypatia: uses: hyperpolymath/standards/.github/workflows/hypatia-scan-reusable.yml@915139d73560e65a8240b8fc7768698658502c89 + timeout-minutes: 10 secrets: inherit diff --git a/.github/workflows/idris2-abi-ci.yml b/.github/workflows/idris2-abi-ci.yml index 4fcb224a..d1ead4d2 100644 --- a/.github/workflows/idris2-abi-ci.yml +++ b/.github/workflows/idris2-abi-ci.yml @@ -23,6 +23,7 @@ jobs: idris2-typecheck: name: Type-check Idris2 ABI definitions runs-on: ubuntu-latest + timeout-minutes: 30 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/instant-sync.yml b/.github/workflows/instant-sync.yml index 31b8e156..50387fdb 100644 --- a/.github/workflows/instant-sync.yml +++ b/.github/workflows/instant-sync.yml @@ -20,6 +20,7 @@ permissions: jobs: dispatch: runs-on: ubuntu-latest + timeout-minutes: 10 steps: - name: Trigger Propagation uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v3 diff --git a/.github/workflows/live-provers.yml b/.github/workflows/live-provers.yml index 48d2fa6a..24c5660e 100644 --- a/.github/workflows/live-provers.yml +++ b/.github/workflows/live-provers.yml @@ -56,6 +56,7 @@ jobs: name: T1 / ${{ matrix.backend }} if: github.event_name != 'schedule' || github.event.schedule == '0 3 * * *' runs-on: ubuntu-latest + timeout-minutes: 15 strategy: fail-fast: false matrix: @@ -126,6 +127,7 @@ jobs: name: T1 Guix manifest check if: github.event_name != 'schedule' runs-on: ubuntu-latest + timeout-minutes: 15 continue-on-error: true steps: - name: Checkout @@ -147,6 +149,7 @@ jobs: name: T2 / ${{ matrix.backend }} if: github.event_name == 'schedule' && github.event.schedule == '0 3 * * *' || (github.event_name == 'workflow_dispatch' && (inputs.tier == '2' || inputs.tier == 'all')) runs-on: ubuntu-latest + timeout-minutes: 15 strategy: fail-fast: false matrix: @@ -294,6 +297,7 @@ jobs: name: T3 / ${{ matrix.backend }} if: github.event_name == 'schedule' && github.event.schedule == '0 5 * * 0' || (github.event_name == 'workflow_dispatch' && (inputs.tier == '3' || inputs.tier == 'all')) runs-on: ubuntu-latest + timeout-minutes: 15 continue-on-error: true strategy: fail-fast: false @@ -408,6 +412,7 @@ jobs: name: T4 niche provers if: github.event_name == 'schedule' && github.event.schedule == '0 6 1 */3 *' || (github.event_name == 'workflow_dispatch' && (inputs.tier == '4' || inputs.tier == 'all')) runs-on: ubuntu-latest + timeout-minutes: 15 continue-on-error: true steps: - name: Checkout @@ -427,6 +432,7 @@ jobs: name: T4 / ${{ matrix.backend }} if: github.event_name == 'schedule' && github.event.schedule == '0 6 1 */3 *' || (github.event_name == 'workflow_dispatch' && (inputs.tier == '4' || inputs.tier == 'all')) runs-on: ubuntu-latest + timeout-minutes: 15 continue-on-error: true strategy: fail-fast: false diff --git a/.github/workflows/mirror.yml b/.github/workflows/mirror.yml index 2083ca60..9859ce1c 100644 --- a/.github/workflows/mirror.yml +++ b/.github/workflows/mirror.yml @@ -6,10 +6,19 @@ on: branches: [main] workflow_dispatch: +# Estate guardrail: cancel superseded runs so re-pushes / rebased PR +# updates do not pile up queued runs against the shared account-wide +# Actions concurrency pool. Applied only to read-only check workflows +# (no publish/mutation), so cancelling a superseded run is always safe. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: contents: read jobs: mirror: uses: hyperpolymath/standards/.github/workflows/mirror-reusable.yml@e6b2884722350515934d443daf23442f2195796f + timeout-minutes: 10 secrets: inherit diff --git a/.github/workflows/mvp-smoke.yml b/.github/workflows/mvp-smoke.yml index ed7b6c72..0f958511 100644 --- a/.github/workflows/mvp-smoke.yml +++ b/.github/workflows/mvp-smoke.yml @@ -23,6 +23,7 @@ jobs: mvp-smoke: name: MVP Smoke runs-on: ubuntu-latest + timeout-minutes: 15 permissions: contents: read steps: diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index 9ab8801b..bf57682e 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -15,6 +15,7 @@ permissions: jobs: rust-ci: uses: hyperpolymath/standards/.github/workflows/rust-ci-reusable.yml@cc5a372af1af1b202c17f1b21efd954e6c038bef + timeout-minutes: 30 with: enable_audit: true enable_coverage: true diff --git a/.github/workflows/scorecard-enforcer.yml b/.github/workflows/scorecard-enforcer.yml index 75e23854..cfde0df4 100644 --- a/.github/workflows/scorecard-enforcer.yml +++ b/.github/workflows/scorecard-enforcer.yml @@ -33,6 +33,7 @@ jobs: # uses-only; `check-score` is the gating job that emits the error. scorecard: runs-on: ubuntu-latest + timeout-minutes: 10 permissions: security-events: write id-token: write # For OIDC @@ -63,6 +64,7 @@ jobs: check-score: needs: scorecard runs-on: ubuntu-latest + timeout-minutes: 10 permissions: contents: read steps: @@ -88,6 +90,7 @@ jobs: # Check specific high-priority items check-critical: runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 3f73a647..f6bb0dbf 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -8,6 +8,14 @@ on: push: branches: [main] +# Estate guardrail: cancel superseded runs so re-pushes / rebased PR +# updates do not pile up queued runs against the shared account-wide +# Actions concurrency pool. Applied only to read-only check workflows +# (no publish/mutation), so cancelling a superseded run is always safe. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: read-all jobs: @@ -16,4 +24,5 @@ jobs: security-events: write id-token: write uses: hyperpolymath/standards/.github/workflows/scorecard-reusable.yml@e0caf11508a3989574713c78f5f444f2ce5e33ef + timeout-minutes: 10 secrets: inherit diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index 097d2af9..c7761fee 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -16,4 +16,5 @@ permissions: jobs: scan: uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@3e4bd4c93911750727e2e4c66dff859e00079da0 + timeout-minutes: 10 secrets: inherit diff --git a/.github/workflows/security-scan.yml b/.github/workflows/security-scan.yml index 55c51837..3c5b854c 100644 --- a/.github/workflows/security-scan.yml +++ b/.github/workflows/security-scan.yml @@ -21,5 +21,6 @@ permissions: jobs: scan: uses: hyperpolymath/panic-attack/.github/workflows/scan-and-report.yml@ea88be7da68e07249ae7df8b948ecb8ecfb9664c # main 2026-05-20 + timeout-minutes: 15 secrets: VERISIMDB_PAT: ${{ secrets.VERISIMDB_PAT }} diff --git a/.github/workflows/spark-theatre-gate.yml b/.github/workflows/spark-theatre-gate.yml index e6899fbf..36f14d80 100644 --- a/.github/workflows/spark-theatre-gate.yml +++ b/.github/workflows/spark-theatre-gate.yml @@ -16,6 +16,7 @@ permissions: jobs: spark-theatre-gate: uses: hyperpolymath/standards/.github/workflows/spark-theatre-gate.yml@462003782f3ebb93ea763e81d0d199ce13ef7d73 + timeout-minutes: 10 with: paths: "." enforce_zero_contract: false diff --git a/.github/workflows/workflow-linter.yml b/.github/workflows/workflow-linter.yml index 02b2e76e..43f58d91 100644 --- a/.github/workflows/workflow-linter.yml +++ b/.github/workflows/workflow-linter.yml @@ -15,6 +15,7 @@ permissions: read-all jobs: lint-workflows: runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4