Skip to content

ci(ArcGate): let the base-branch lane permit the single integration branch — 7 PRs are red for addressing, not quality - #216

Merged
heydryft merged 1 commit into
masterfrom
ci/allow-integration-branch-base
Aug 21, 2026
Merged

heydryft merged 1 commit into
masterfrom
ci/allow-integration-branch-base

Conversation

@heydryft

Copy link
Copy Markdown
Contributor

The problem

Seven open PRs are red for their addressing, not their quality.

The base-branch lane in .github/workflows/ci.yml hard-fails any PR whose base is not literally master. The queue is being restructured so that agents branch off a single integration branch — release/openrouter-ready — and PR back into it, leaving exactly one PR pointed at master (#194). Under the current rule every one of those retargeted PRs is red on arrival, no matter how good the work is.

Why widening it does not reopen the incident it was built to close

The lane's comment explains its intent, and that intent is preserved here.

It was never really asking "is the base literally master". It was asking "is the base a stable branch that will itself land on master through a PR this lane has gated". master satisfies that. Exactly one other branch does, by construction:

Master's protection is unchanged. CI complete is still the single required status check, it still lists base-branch in its needs, and the job name (Base branch) is untouched so branch protection keeps matching it.

The original defect was PRs based on another PR's transient branch — #109, #113, #114, #116, #121 — a base that can be rebased, force-pushed or abandoned underneath them, so their green described a tree that might never exist. An integration branch is the opposite: long-lived, the tree that will exist, and re-proven against master by #194 before any of it ships.

The change

case "${BASE_REF}" in
  master|release/openrouter-ready) ;;
  *) echo "::error::..."; exit 1 ;;
esac
  • Exact-match allowlist, not a release/* glob. A prefix match would let any newly pushed release/anything declare itself a landing branch — the same unproven-base hole under a new name. The comment says to keep the list at two entries, and that if a second integration branch is ever wanted the honest change is to retire the first, not to append.
  • BASE_REF still arrives via env:, never interpolated into the run: script — a branch name is attacker-controlled text.
  • Still a hard failure, not a warning. The class of defect is "an absence that reads as a pass"; a warning is another absence.
  • The error message now tells the author where to retarget instead of only what is wrong.

Verification

The allowlist accepts master and release/openrouter-ready, and refuses main, release/something-else, release/openrouter-ready-evil, xrelease/openrouter-ready, MASTER, master*, master; echo pwned, the empty base, and every branch currently serving as a base in the open queue (perf/port-vllm-swiglu-clamp, feat/qtip-k8v4l12-format, arctarget/multiarch-specialization, feat/turboquant-hd512-v4).

ci.yml parses, and ci-complete.needs still contains base-branch.

…hould permit

Seven open PRs are red for their ADDRESSING, not their quality. The
`base-branch` lane hard-fails any PR whose base is not literally `master`,
and the PR queue is being restructured so that agents branch off a single
integration branch, `release/openrouter-ready`, and PR back into it.

The lane's intent is kept intact. It was never really asking "is the base
literally master" — it was asking "is the base a stable branch that will
itself land on master through a PR this lane has gated". `master` satisfies
that. So does exactly one other branch, by construction:
`release/openrouter-ready` reaches master through exactly one pull request
(#194), whose own base IS `master`, so it takes the `master` arm of this
same check and must be green on a tree whose parent is proven master.

Master's protection is therefore unchanged: nothing enters master without a
full run whose base is master, and `CI complete` still aggregates this lane.

The original incident was PRs based on another PR's TRANSIENT branch — a base
that can be rebased, force-pushed or abandoned underneath them, so their green
described a tree that might never exist. An integration branch is the opposite:
long-lived, the tree that will exist, and re-proven against master by #194
before any of it ships.

Implementation notes:
- Exact-match allowlist via `case`, not a `release/*` glob. A prefix match
  would let any newly pushed `release/anything` declare itself a landing
  branch, which is the same unproven-base hole under a new name.
- `BASE_REF` still arrives via `env:`, never interpolated into the script.
- The job name (`Base branch`) is unchanged, so branch protection and the
  `ci-complete` needs list keep matching.

Verified: the allowlist accepts `master` and `release/openrouter-ready` and
refuses `main`, `release/something-else`, `release/openrouter-ready-evil`,
`xrelease/openrouter-ready`, `MASTER`, `master*`, `master; echo pwned`, the
empty base, and every current PR base branch in the queue.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UMmjFy8TvsgypxVWNVhhC7
@github-actions

Copy link
Copy Markdown
Code Metrics Report
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 Language              Files        Lines         Code     Comments       Blanks
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 C Header                  5          305          210           52           43
 CSS                       2         1181         1036           34          111
 CUDA                     81        29464        20161         6264         3039
 Dockerfile                1           39           22            8            9
 JavaScript               16         3546         2676          482          388
 Jinja2                    7          694          656            5           33
 JSON                     75         4896         4893            0            3
 Makefile                  1            6            5            0            1
 Metal Shading Lan|       33        12224         9431         1142         1651
 PowerShell                1          300          227           30           43
 Python                  147        15371        12677          824         1870
 Shell                    42        10304         6858         2769          677
 Plain Text                4         3801            0         2479         1322
 TOML                     33         1498         1294           54          150
 YAML                      3           25           23            2            0
─────────────────────────────────────────────────────────────────────────────────
 HTML                      4         2687         2604           43           40
 |- CSS                    2          543          479           37           27
 |- JavaScript             1         1233         1215           12            6
 (Total)                             4463         4298           92           73
─────────────────────────────────────────────────────────────────────────────────
 Jupyter Notebooks         4          122           83           23           16
 |- Markdown               1           60           30           22            8
 |- Python                 1          122          113            1            8
 (Total)                              304          226           46           32
─────────────────────────────────────────────────────────────────────────────────
 Markdown                213        48932            0        38081        10851
 |- BASH                  72         1655         1203          331          121
 |- C                      4           19           19            0            0
 |- CUDA                   2           84           56           16           12
 |- JSON                  19          779          779            0            0
 |- PowerShell             1            1            1            0            0
 |- Python                23         1008          787          113          108
 |- Rust                  68         2063         1727           78          258
 |- TOML                   6          207          164            0           43
 |- YAML                   5           41           36            5            0
 (Total)                            54789         4772        38624        11393
─────────────────────────────────────────────────────────────────────────────────
 Rust                    681       340984       293252        18092        29640
 |- Markdown             504        32473          471        27989         4013
 (Total)                           373457       293723        46081        33653
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 Total                  1353       516667       363188        98988        54491
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

@heydryft
heydryft merged commit 8ae2090 into master Aug 21, 2026
15 checks passed
This was referenced Aug 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant