main cannot return to green on its own once it has been red across a commit that any diff-scoped gate flags. The range that decides those gates is anchored to the last successful run, and a successful run is what the gate is blocking.
The cycle, from .github/workflows/ci.yml
last-gated-commit resolves the anchor:
sha="$(gh api \
"repos/$REPO/actions/workflows/ci.yml/runs?branch=$BRANCH&event=push&status=success&per_page=1" \
--jq '.workflow_runs[0].head_sha')"
documentation-checkpoint consumes it on a push to main:
base="${LAST_GREEN:-}"
[ -n "$base" ] || base="$PUSH_BASE"
head="$PUSH_HEAD"
python3 scripts/check-now-current.py --base "$base" --head "$head"
So: main goes red → no successful run → LAST_GREEN stays put → every later push widens LAST_GREEN..HEAD → the widening range keeps re-including the commit that is being flagged → the job fails again → still no successful run. The exit condition requires the thing it blocks.
Observed now: documentation-checkpoint on main flags dd8a3b0e1, 8daf58e77 and 38ec0da4a — three commits from 2026-08-18, five days old, each carrying the full protocol paragraph and all three trailers, each with a single parent (the shape of a squash merge, this repository's only landing mode). Two are from external contributors, whose row/<ID> branches live on their forks and can never appear on origin. They cannot be retroactively re-landed, so under the present anchor they will be flagged on every push forever.
Two defects, and the repository already documents both
scripts/main-baseline.py (issue #274, spec .agents/specs/main-verifiability.md) was written to answer exactly "what is the last SHA where main was fully green", and its own header records the two reasons a naive query cannot:
-
Runs do not finish. "Every expensive job in ci.yml carries a job-level concurrency group keyed on github.ref with cancel-in-progress: true. For a push to main that ref is the constant refs/heads/main, so consecutive pushes cancel each other's long jobs — 26 of the last 40 main runs were cancelled." A cancelled run is not success, so on a busy day the anchor drifts back by many commits even with nothing broken. Confirmed live today: the three newest ci runs on main (15298f033, aa67130cc, 6991b78d2) are all cancelled.
-
Run-level success is not per-job success. "sanitize-cpu is continue-on-error: true, so its failure does not fail the run... A tool that trusted the run conclusion would publish that SHA as the known-good baseline. The verdict is computed from PER-JOB conclusions, always."
last-gated-commit queries status=success at the run level — precisely what main-baseline.py says must not be trusted — and does not use main-baseline.py at all. The tool built to answer this question is not wired to the job that asks it.
Why this is worth fixing rather than clearing by hand
Clearing it once (landing something that makes a run succeed) resets the anchor and hides the mechanism until the next red. The cost is paid repeatedly and by everyone: a red main blocks every branch, and this week three separate lanes converged on #1731 because a blocking red creates pressure to act before checking ownership, producing a duplicate issue (#1733) and duplicate branches.
Candidate directions, not a prescription
- Anchor
last-gated-commit on scripts/main-baseline.py's per-job verdict rather than a run-level status=success query.
- Give the anchor a floor, so a range can never widen past a recorded baseline no matter how long
main has been red.
- Decide what a diff-scoped gate should do with a squash merge whose branch is on a fork — teach the checker, or record a bounded exception. Note that whatever is decided must not weaken the rule for work that can use an
origin branch.
Whoever takes this should confirm the cycle by construction (a red push, then a second push, and show the range widening) rather than only by reading, since the claim is about a feedback loop.
Refs #1764 (the three current reds), #274.
maincannot return to green on its own once it has been red across a commit that any diff-scoped gate flags. The range that decides those gates is anchored to the last successful run, and a successful run is what the gate is blocking.The cycle, from
.github/workflows/ci.ymllast-gated-commitresolves the anchor:documentation-checkpointconsumes it on a push tomain:So: main goes red → no successful run →
LAST_GREENstays put → every later push widensLAST_GREEN..HEAD→ the widening range keeps re-including the commit that is being flagged → the job fails again → still no successful run. The exit condition requires the thing it blocks.Observed now:
documentation-checkpointonmainflagsdd8a3b0e1,8daf58e77and38ec0da4a— three commits from 2026-08-18, five days old, each carrying the full protocol paragraph and all three trailers, each with a single parent (the shape of a squash merge, this repository's only landing mode). Two are from external contributors, whoserow/<ID>branches live on their forks and can never appear onorigin. They cannot be retroactively re-landed, so under the present anchor they will be flagged on every push forever.Two defects, and the repository already documents both
scripts/main-baseline.py(issue #274, spec.agents/specs/main-verifiability.md) was written to answer exactly "what is the last SHA wheremainwas fully green", and its own header records the two reasons a naive query cannot:Runs do not finish. "Every expensive job in ci.yml carries a job-level concurrency group keyed on
github.refwithcancel-in-progress: true. For a push tomainthat ref is the constantrefs/heads/main, so consecutive pushes cancel each other's long jobs — 26 of the last 40mainruns werecancelled." A cancelled run is notsuccess, so on a busy day the anchor drifts back by many commits even with nothing broken. Confirmed live today: the three newestciruns onmain(15298f033,aa67130cc,6991b78d2) are allcancelled.Run-level success is not per-job success. "
sanitize-cpuiscontinue-on-error: true, so its failure does not fail the run... A tool that trusted the run conclusion would publish that SHA as the known-good baseline. The verdict is computed from PER-JOB conclusions, always."last-gated-commitqueriesstatus=successat the run level — precisely whatmain-baseline.pysays must not be trusted — and does not usemain-baseline.pyat all. The tool built to answer this question is not wired to the job that asks it.Why this is worth fixing rather than clearing by hand
Clearing it once (landing something that makes a run succeed) resets the anchor and hides the mechanism until the next red. The cost is paid repeatedly and by everyone: a red
mainblocks every branch, and this week three separate lanes converged on #1731 because a blocking red creates pressure to act before checking ownership, producing a duplicate issue (#1733) and duplicate branches.Candidate directions, not a prescription
last-gated-commitonscripts/main-baseline.py's per-job verdict rather than a run-levelstatus=successquery.mainhas been red.originbranch.Whoever takes this should confirm the cycle by construction (a red push, then a second push, and show the range widening) rather than only by reading, since the claim is about a feedback loop.
Refs #1764 (the three current reds), #274.