Skip to content

The main-branch diff-scoped gates are a ratchet: their base is the last GREEN run, so an unfixable commit freezes it and the walk grows forever #1809

Description

@localai-bot

commit-protocol-tag and documentation-checkpoint have been red on main
since 2026-08-13 and cannot recover on their own. Each new merge makes
the failure strictly worse. This is a deadlock in how the walk base is chosen,
not a backlog of work.

The loop

Both jobs base their walk on needs.last-gated-commit.outputs.sha — the head of
the most recent successful push run (.github/workflows/ci.yml:627-671),
falling back to github.event.before.

main is red  ->  no successful run  ->  LAST_GREEN stays frozen
             ->  next push walks frozen..HEAD, one commit longer
             ->  re-hits the same violations  ->  still red

Measured 2026-08-23 at 6e73bdee3: LAST_GREEN = fafa16f0f, dated
2026-08-13. The walk covers 498 first-parent non-merge commits and grows
by one per merge.

Why it cannot clear itself

20 of those 498 commits lack the FOLLOWING_AGENTS_PROTOCOL trailer, plus
roughly five with repository changes that reached main without a task branch.
They are already on main and immutable. Adding a trailer to them requires
rewriting main, which AGENTS.md forbids without exception.

So the gate demands a remedy that does not exist. A gate with no available
remedy is not a gate; it is a permanent red. Its practical effect is the #1722
effect — it trains every reader to skip the job, and once skipped the job
protects nothing.

Dated 2026-08-13 through 2026-08-23, so violations are still arriving:
175733000 landed on the morning this issue was filed without the trailer. The
gate was correct about every one of them. Nobody read it.

The base logic is right about the thing it was designed for

The LAST_GREEN design exists for a real reason, recorded at ci.yml:632-636:
github.event.before skips a cancelled run's commits and nothing re-covers
them
(#822, #863). Basing on the last green commit makes a cancelled run
lossless, because the next run simply walks wider. That property must survive
any fix — cancelled runs are common here (#1285), and losing it reintroduces the
gap #822 closed.

What the design did not anticipate is a violation that can never be repaired.
Self-healing assumes a green run is eventually reachable; an immutable
violation makes it unreachable, and the widening walk becomes a ratchet.

Suggested shape, not a mandate

Introduce a recorded enforcement floor — a commit the walk never goes
behind — and take the base as the newer of LAST_GREEN and that floor. Set the
floor past the 20 violations. That keeps self-healing inside the window,
breaks the deadlock, and makes advancing the floor a deliberate reviewed act
rather than a side effect.

Whatever shape is chosen, it must satisfy:

  1. A new violation on a new commit still reds the gate. Verify with a red-first
    mutation, not by reading the diff.
  2. A cancelled run stays lossless: its commits are still covered by the next
    run.
  3. The 20 forgiven commits are recorded, not silently dropped. They are real
    protocol violations that landed unread, and the record is the only place that
    can now say so.
  4. No assertion is deleted and no scope is widened to make a red green.
    AGENTS.md ## Changing the rules or a checker applies: spec, red-before
    test or mutation, green-after evidence.

Scope note

main itself is otherwise healthy. The first readable baseline since 13 August
(run on 6354755ba, 2026-08-23) returned 11 success, 3 failure, 4 skipped
with zero code failures: every build green including cuda-fat-build, both
sanitizers green. The three reds were these two ratcheted gates plus
agent-record's missing hugo (#1722, fix in flight as #1726). So this is
bookkeeping, and fixing it makes the other verdicts readable again.

The two windows-msvc lanes are PR-only and never run on main, so they can
never be classified from a baseline; they are #584's problem, not this one.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions