Skip to content

Commit f39440c

Browse files
claudehyperpolymath
authored andcommitted
ci(bridge-gate): wire the merge-orchestration CVE/bump gate
Gates dependency-bump PRs on B3 (nix) + B1 (reachable unmitigable CVE, via panic-attack's OSV-backed Patch-Bridge). SHA-pinned checkout; env-only github context; timeout set. META change -> owner-reviewed, not auto-merged. Verdict logic tested in hypatia#459. https://claude.ai/code/session_011GXPoh6pB6rm3jfeLHWMtc
1 parent 861102d commit f39440c

1 file changed

Lines changed: 60 additions & 0 deletions

File tree

.github/workflows/bridge-gate.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# SPDX-License-Identifier: MPL-2.0
2+
# Copyright (c) 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
3+
#
4+
# bridge-gate.yml -- merge-orchestration CVE/bump gate.
5+
# Wired from hyperpolymath/hypatia docs/design/merge-orchestration (artifact 4, PR #459).
6+
#
7+
# Gates dependency-bump PRs on:
8+
# B3 nix bump -> fail (Nix removed estate-wide; close, do not merge)
9+
# B1 reachable unmitigable CVE -> fail (via panic-attack's OSV-backed Patch-Bridge)
10+
# A clean patch/minor CVE-clear bump passes. A failing gate is a red check; to actually
11+
# BLOCK auto-merge, add "bridge-gate" to this repo's required status checks (owner action).
12+
#
13+
# Notes for review:
14+
# - B2 (major -> review) is left to the existing human-review path; it can be added
15+
# later via dependabot/fetch-metadata.
16+
# - panic-attack is built from source (public clone). Production hardening: a released
17+
# binary, or -- to match estate convention -- a hyperpolymath/standards reusable
18+
# workflow. Offered as a follow-up.
19+
# - github context is passed via env: only (no ${{ }} in run lines) per estate rules.
20+
name: bridge-gate
21+
on:
22+
pull_request:
23+
types: [opened, synchronize, reopened]
24+
permissions:
25+
contents: read
26+
jobs:
27+
bridge-gate:
28+
if: ${{ startsWith(github.head_ref, 'dependabot/') || startsWith(github.head_ref, 'renovate/') }}
29+
runs-on: ubuntu-latest
30+
timeout-minutes: 25
31+
steps:
32+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
33+
34+
- name: B3 gate -- nix bumps (no network)
35+
env:
36+
HEAD_REF: ${{ github.head_ref }}
37+
run: |
38+
if [[ "$HEAD_REF" == dependabot/nix/* ]]; then
39+
echo "::error::B3: nix bump -- Nix removed estate-wide; close, do not merge."
40+
exit 1
41+
fi
42+
43+
- name: Build panic-attack (Patch-Bridge)
44+
run: |
45+
git clone --depth 1 https://github.com/hyperpolymath/panic-attack /tmp/pa
46+
cargo build --release --features http --manifest-path /tmp/pa/Cargo.toml
47+
echo "/tmp/pa/target/release" >> "$GITHUB_PATH"
48+
49+
- name: Bridge triage (queries OSV) -> BridgeReport
50+
run: panic-attack bridge triage . --output bridge-report.json
51+
52+
- name: Apply B1 verdict -- reachable unmitigable CVE -> flag
53+
run: |
54+
blockers=$(jq '[.cves[]? | select(.classification=="Unmitigable" and .reachability.status=="Reachable")] | length' bridge-report.json)
55+
if [ "$blockers" -gt 0 ]; then
56+
echo "::error::B1: $blockers reachable unmitigable CVE(s) -> safety=flag (auto-merge blocked)"
57+
jq -r '.cves[]? | select(.classification=="Unmitigable" and .reachability.status=="Reachable") | " - \(.vulnerability.cve // .vulnerability.id): \(.rationale)"' bridge-report.json
58+
exit 1
59+
fi
60+
echo "B1 PASS: no reachable unmitigable CVEs -> arm-eligible (pool-gated)."

0 commit comments

Comments
 (0)