diff --git a/.github/workflows/agda-meta-checker.yml b/.github/workflows/agda-meta-checker.yml
index 6a08010b..c90a2345 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@df4cb1c069e1874edd31b4311f1884172cec0e10  # v6.0.3
diff --git a/.github/workflows/boj-build.yml b/.github/workflows/boj-build.yml
index d2d42cc1..57956f7a 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: 10
     steps:
       - name: Checkout
         uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
diff --git a/.github/workflows/cargo-audit.yml b/.github/workflows/cargo-audit.yml
index a928f0f9..255082ad 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 d3328203..bee45207 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@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
 
@@ -110,6 +111,7 @@ jobs:
   zig-ffi:
     name: Build & Test Zig FFI Bridge
     runs-on: ubuntu-22.04
+    timeout-minutes: 30
     steps:
       - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
 
@@ -138,6 +140,7 @@ jobs:
   rust-chapel-feature:
     name: Rust Build with Chapel Feature
     runs-on: ubuntu-22.04
+    timeout-minutes: 30
     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/container-ci.yml b/.github/workflows/container-ci.yml
index 910b7089..99266c31 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 5d655e0a..4439161a 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: 10
 
     steps:
       - name: Checkout repository
@@ -72,6 +73,7 @@ jobs:
   k9-validate:
     name: Validate K9 contracts
     runs-on: ubuntu-latest
+    timeout-minutes: 10
 
     steps:
       - name: Checkout repository
@@ -121,6 +123,7 @@ jobs:
   empty-lint:
     name: Empty-linter (invisible characters)
     runs-on: ubuntu-latest
+    timeout-minutes: 10
 
     steps:
       - name: Checkout repository
@@ -185,6 +188,7 @@ jobs:
   groove-check:
     name: Groove manifest check
     runs-on: ubuntu-latest
+    timeout-minutes: 10
 
     steps:
       - name: Checkout repository
@@ -243,6 +247,7 @@ jobs:
   eclexiaiser-validate:
     name: Validate eclexiaiser manifest
     runs-on: ubuntu-latest
+    timeout-minutes: 10
 
     steps:
       - name: Checkout repository
@@ -312,6 +317,7 @@ jobs:
   dogfood-summary:
     name: Dogfooding compliance summary
     runs-on: ubuntu-latest
+    timeout-minutes: 10
     needs: [a2ml-validate, k9-validate, empty-lint, groove-check, eclexiaiser-validate]
     if: always()
 
diff --git a/.github/workflows/dogfood-proofs-ci.yml b/.github/workflows/dogfood-proofs-ci.yml
index 47627ae3..a8be759c 100644
--- a/.github/workflows/dogfood-proofs-ci.yml
+++ b/.github/workflows/dogfood-proofs-ci.yml
@@ -39,6 +39,7 @@ jobs:
   coq:
     name: Coq
     runs-on: ubuntu-latest
+    timeout-minutes: 20
     steps:
       - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
 
@@ -65,6 +66,7 @@ jobs:
   lean:
     name: Lean 4
     runs-on: ubuntu-latest
+    timeout-minutes: 20
     steps:
       - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
 
@@ -116,6 +118,7 @@ jobs:
   agda:
     name: Agda
     runs-on: ubuntu-latest
+    timeout-minutes: 20
     steps:
       - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
 
diff --git a/.github/workflows/formal-verification.yml b/.github/workflows/formal-verification.yml
index 9edf46ee..cb70b6c1 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 427a3260..6b296302 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 }}
 
diff --git a/.github/workflows/ghcr-publish.yml b/.github/workflows/ghcr-publish.yml
index 11fbc698..849fdf92 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: 15
     permissions:
       contents: read
       packages: write
diff --git a/.github/workflows/idris2-abi-ci.yml b/.github/workflows/idris2-abi-ci.yml
index d6015caf..7d5bd362 100644
--- a/.github/workflows/idris2-abi-ci.yml
+++ b/.github/workflows/idris2-abi-ci.yml
@@ -25,6 +25,7 @@ jobs:
   idris2-typecheck:
     name: Type-check Idris2 ABI definitions
     runs-on: ubuntu-latest
+    timeout-minutes: 30
     steps:
       - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
 
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 18622704..7b764ecf 100644
--- a/.github/workflows/live-provers.yml
+++ b/.github/workflows/live-provers.yml
@@ -58,6 +58,7 @@ jobs:
     name: T1 / ${{ matrix.backend }}
     if: github.event_name != 'schedule' || github.event.schedule == '0 3 * * *'
     runs-on: ubuntu-latest
+    timeout-minutes: 20
     strategy:
       fail-fast: false
       matrix:
@@ -128,6 +129,7 @@ jobs:
     name: T1 Guix manifest check
     if: github.event_name != 'schedule'
     runs-on: ubuntu-latest
+    timeout-minutes: 20
     continue-on-error: true
     steps:
       - name: Checkout
@@ -149,6 +151,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: 20
     strategy:
       fail-fast: false
       matrix:
@@ -296,6 +299,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: 20
     continue-on-error: true
     strategy:
       fail-fast: false
@@ -410,6 +414,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: 20
     continue-on-error: true
     steps:
       - name: Checkout
@@ -429,6 +434,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: 20
     continue-on-error: true
     strategy:
       fail-fast: false
diff --git a/.github/workflows/mvp-smoke.yml b/.github/workflows/mvp-smoke.yml
index 397f0f5c..ed094b0e 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/scorecard-enforcer.yml b/.github/workflows/scorecard-enforcer.yml
index bc71a0aa..f499682c 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@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
 
diff --git a/.github/workflows/workflow-linter.yml b/.github/workflows/workflow-linter.yml
index 1e594b48..08a10589 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@df4cb1c069e1874edd31b4311f1884172cec0e10 # v4
 
