R3 — refuse a merge onto a failing base, and one place to claim a repair - #89
Merged
Conversation
Two merges landing a minute apart shared a ref, so cancel-in-progress had the second cancel the first and GitHub recorded the cancelled run as a red check against the commit it superseded. 1622ed7 (the F5 merge) still carries an X for a run cancelled 17s in, mid-typecheck, which is a false record of a chunk shipping broken. PR runs still supersede each other -- the sha they abandon is one nobody will merge. Push runs on main are the record of what a merge shipped, so they are grouped per sha and never cancelled.
…m a repair main has broken four times in three days, never through a git conflict: two changes that did not overlap textually, merged, broken only in the combination neither branch was tested against. CI already runs against the merge result -- that is how the F4 case was caught. Nothing here adds a check. It changes what an existing check result is allowed to mean. - base-branch-gate.yml republishes main's own last CI result as the base-branch-green status on every open PR. Branch protection requires it, so a merge onto a failing base is refused rather than argued about. It gates the merge, not the build: the check re-posts itself when main's CI finishes, so a blocked PR clears without pushing anything. - A repair-labelled PR is exempt, because a repair is how a red branch becomes green. A cancelled base run is not read as a failure. - REPAIRS.md is the one place a repair is claimed, before it is written, so the second session to find a defect rebases onto the first fix instead of writing its own. F5 and R2 both fixed F4's caller sweep, git found no conflict, took both copies, and #87 had to delete the duplicates. - AGENTS.md now says to run the checks at your base commit and report the sha, not to inherit an earlier session's failing-check list, and to stop rather than repair a red base inside a feature chunk.
The job succeeds whenever it manages to publish -- including when what it publishes is a failure. Sharing a name with the commit status meant branch protection could require the job instead, which is green either way.
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Base commit
6f0076d36d3db5b27a8878a048e4751c0fc0046anpm run lint,npm run typecheck,npm test -- --run(103 files / 1324 tests),npm run buildall pass, afternpx --yes npm@10.9.7 ci.What & why
R3, merge order.
mainhas broken four times in three days and never oncethrough a git conflict: two changes that did not overlap textually were merged,
and the breakage existed only in the combination neither branch had been tested
against. F4 renamed a field S7's fixtures still passed the old shape. F5 and R2
repaired the same three files independently and git took both copies, so #87
had to delete the duplicates.
CI already runs against the merge result — that is how the F4 case was caught.
Nothing here adds a check. No lint rule, no test, no product code. It
changes what an existing check result is allowed to mean, and where a repair is
claimed.
Changes
.github/workflows/base-branch-gate.ymlreads the CI result
mainalready produced for its own tip and republishes itas the
base-branch-greenstatus on every open PR. Branch protection requiresthat context, so this is not a warning and not a reviewer's judgement.
merge when the base is green.
main's CI finishes, the gate re-runs and rewritesthe status on every open PR, so a blocked PR clears itself without a push.
repairis exempt, because a repair is how a red branchbecomes green. The label is a claim in
REPAIRS.md, not a bypass.ci.yml'sconcurrency group was
ci-CI-<ref>, so two merges a minute apart shared agroup and the second cancelled the first.
1622ed7, the F5 merge, stillcarries a red X for a run cancelled 17 seconds in, mid-typecheck — a false
record of a chunk shipping broken. Push runs now get a group per sha and are
never cancelled; PR runs still supersede each other, where the abandoned sha
is one nobody will merge. The gate also reads a cancelled base run as "not a
failure" rather than as red.
REPAIRS.mdis the one place a repair is claimed, before it is written.Named in
AGENTS.md, read with two commands, seeded with the F4/F5/R2history that made it necessary — and with one open, unclaimed defect (below).
AGENTS.mdnow says, in the words a session will follow: run the checksat your base commit and report the sha before building; do not inherit an
earlier session's failing-check list; if the base is red, say so and stop; do
not repair a red base inside a feature chunk; claim a repair first and keep it
in its own commit. The PR template asks for the base sha;
CONTRIBUTING.mdpoints at both.
Verification
npm run lintpasses (at base6f0076d)npm run typecheckpassesnpm test -- --runpassesnpm run buildpassesDRY_RUN=1 .github/scripts/base-branch-gate.sh <branch>:green base →
success,728eb6c(failed run) →failure,1622ed7(cancelled run) →success, "last run was cancelled, not afailure".
pipeline is failing cannot be merged (see the comment below).
Notes
DECISIONS.mdonmaincontains literal unresolvedconflict markers (lines 3–13), committed in
aeeca8band shipped greenbecause no check reads markdown. It is logged as the open row in
REPAIRS.mdrather than repaired here — repairing shared breakage inside another chunk's
diff is the thing this PR exists to stop. It is one paragraph and the ledger
row says which side is true.
context stays absent and the merge is refused rather than waved through.
Chunk sessions push branches to this repo.