From faea5fbac22dabb8d1f710a38cc3eb5c4ef6ec74 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Sun, 23 Aug 2026 20:06:59 +0000 Subject: [PATCH 01/11] spec(GATE-CI-ENFORCEMENT-FLOOR): the diff-scoped gates need a floor, because 41 commits on main can never be repaired (#1809) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `commit-protocol-tag` and `documentation-checkpoint` base their walk on the head of the last SUCCESSFUL push run. That base is what makes a cancelled run lossless (#822, #863), and it is also what turns one unrepairable commit into a permanent red: no green run means the base never advances, so every later push re-walks the same violations over a range one commit wider. Re-measured at `bacb71109`: `LAST_GREEN` is `fafa16f0f` of 2026-08-13, the range is 499 first-parent commits with no merges, and 41 distinct commits in it fail a gate with no available remedy — 35 fail the strict trailer contract, 6 disjoint ones fail role discipline. They are on `main`, and the only repair is a rewrite `AGENTS.md` forbids. The spec lands first and alone so the design can be read before the code implements it. It chooses a recorded enforcement floor over a per-commit exemption list, enumerates all 41 forgiven commits, and argues the narrowing explicitly: enforcing on an immutable landed commit is a permanent red rather than a gate, and a permanent red is read by nobody. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code] --- .agents/issue-index.md | 1 + .agents/specs/ci-enforcement-floor.md | 359 ++++++++++++++++++++++++++ 2 files changed, 360 insertions(+) create mode 100644 .agents/specs/ci-enforcement-floor.md diff --git a/.agents/issue-index.md b/.agents/issue-index.md index 242d8cc26..ebac6c518 100644 --- a/.agents/issue-index.md +++ b/.agents/issue-index.md @@ -664,3 +664,4 @@ rather than merged. `scripts/check-agent-record.py` gates both. | [#1777](https://github.com/mudler/vllm.cpp/issues/1777) | `GATE-FP8-NUMERIC-BOUND` | **Layer 2 of [#1189](https://github.com/mudler/vllm.cpp/issues/1189)'s `## Gate design` had no implementation, and nothing in the tree could see a per-tensor scale collapse.** Layer 1 passed on 2026-08-23 (`rc` job `2911ed39`, `TOKEN_VERDICT=PASS`), and the header of `tests/parity/test_qwen27n_fp8_tower_paged_engine.cpp` records why that is not enough: a x1.02 AND a x1.10 perturbation of every FP8 weight scale were demonstrably REACHED on the dgx production build and both still produced 16/16 IDENTICAL tokens, with only x2.00 failing. So a wrong-but-close scale and a silent dequant -- which is numerically BETTER than the quantized path -- are invisible to every token comparison here. The audit corrects the brief in one place rather than re-implementing what exists: the SHAPE ASSERTION at the GEMM boundary is already DONE in two places, `src/vt/ops.cpp::MatmulFp8BlockScaled` asserting `b_scale == [cdiv(N,block_n), cdiv(K,block_k)]` (pinned by `test_ops_matmul_fp8_block_cpu.cpp` G5) and `Fp8BlockScaledRefusalFor` refusing `N % 128` / `K % 128` BY NAME before CUTLASS can answer `Invalid status` (#1453, pinned by G4/G6), and the CUDA TU's own comment at the refusal site says so. FIXED IN FLOW: `tests/vllm/model_executor/models/test_fp8_block_numeric_bound.cpp` bounds every projection against the fixture's independent `double` reference through the production `Fp8BlockLinearMethod::Apply`, TWO-SIDED in the same case -- clean UNDER the bound and x1.10 OVER it, per shape per dtype, plus a 4x margin over the grid -- because a one-directional bound stops biting the moment somebody widens it and nothing would say so. Measured over six shapes: bf16 clean 3.82e-3 against x1.10 1.034e-1 at `kBoundBf16 = 2e-2` (5.2x each way), f32 clean 6.20e-6 against 1.000e-1 at `kBoundF32 = 1e-4`. The statistic floors its denominator at 1% of the projection's own maximum, and that was MEASURED rather than assumed: unfloored, the clean f32 reading moves 835x on one shape because a single output element cancels to near zero, which is a number that cannot carry a bound. `dense_fp8_block::Fp8BlockScaleSpread` is the scale-variance probe #1189 asks for, a max/min RATIO because the issue pins the degenerate reading at exactly 1.0 where a variance reads 0.0, carried with the GEMM counter in one `Fp8BlockStats` snapshot; single-cell grids are counted APART from collapsed ones because 11 of the model fixture's 13 grids hold one cell and a probe that reads 11 on a healthy model is one nobody believes. The split arm also gained the two GEMM-boundary operand assertions the merged arm has carried since M6 -- without the packed one, a short buffer is read PAST ITS END by the first GEMM and the call returns a value. Seven mutations in both directions, tar-snapshotted and `sha256sum -c` verified after each: x1.10 RED 14 assertions, x1.02 RED 14, the same 14 (not predicted: the bf16 readings come in at 2.32e-2 to 2.39e-2 against the 2e-2 bound because the truncating store compounds ON TOP of the scale error, so the bf16 half is caught by only 1.16x and the f32 half by 200x), the bound widened to 1.0 RED 6, a collapsing load path RED 14 across 2 cases, the probe's accounting RED 2, and each new operand assertion RED when defanged. CPU tier throughout, so `build-test-cpu` and `sanitize-cpu` run all of it on every pull request; `cuda-fat-build` runs no `ctest` and nothing here rests on it. **#1189 is NOT closed**: its gate design is now covered but its six milestones' `## Owed` sections are live, and no closing keyword appears in this change. Spec [`gate-fp8-numeric-bound.md`](specs/gate-fp8-numeric-bound.md) | gap | | [#1779](https://github.com/mudler/vllm.cpp/issues/1779) | `GATE-PREPUSH-FAIL-LOUD` | **`.githooks/pre-push` named six checkers and three of them had no file, and its file-test guard skipped each missing one in silence while the hook still exited 0** -- so it presented as six gates and ran three, and `core.hooksPath` is set to `.githooks` here, so it runs on every push. `check-policy.py` and `check-state-record.py` went with `0f3e44eee`, `check-public-doc-tables.py` with #1714; all three are deleted, not renamed. PART 1 FIXED IN FLOW: the loop now refuses a name it cannot find, the three dead names are pruned, the dead `--base` case arm goes with them, and `.githooks/README.md` stops listing the retired table gate. A red-first suite executes the hook against a scratch repository and pins both directions. PART 2 IS NOT FIXED AND STAYS OWED under `## Owed` in `.agents/specs/gate-prepush-fail-loud.md`: 65 specs still name a deleted checker, which needs its own row | bug | | [#1528](https://github.com/mudler/vllm.cpp/issues/1528) | `LTX25-GUIDED-VIDEO` | **Two comments in the LTX-2.5 guided denoiser named `RetakePipeline` as the one upstream caller that sets `force_uncond_pass`, and NO upstream caller sets it at `fd4ded7f`.** `include/vllm/model_executor/models/ltx2_denoisers.h:144-145` and `src/vllm/model_executor/models/ltx2_denoisers.cpp:111-113`, both from `daeff67f2` (row `LTX25-GUIDED-VIDEO`, [#1092](https://github.com/mudler/vllm.cpp/issues/1092), PR [#1102](https://github.com/mudler/vllm.cpp/pull/1102)). Re-derived at the local `Lightricks/LTX-2` checkout whose `git rev-parse HEAD` is `fd4ded7f2d88d3da713abcdd4ad41ecc4a9314ca`, the revision `.agents/specs/ltx25-guided-video.md:6` pins. `git grep -n force_uncond_pass` over the WHOLE tree, not only `*.py`, returns 11 LINES and not one is an assignment by a caller (the filing counted 10 because it restricted the grep to `*.py`; the two counts agree and name different populations): `utils/denoisers.py:74` declares the `_guided_denoise` keyword, `:102-103` are the two reads, `:267,273,297` are `GuidedDenoiser` storing and forwarding it, `:313,319,357` are `FactoryGuidedDenoiser` doing the same, `utils/samplers.py:692` is the substring `force_uncond_pass=True` inside a raised ERROR MESSAGE, and `packages/ltx-pipelines/CLAUDE.md:76` documents it. `git grep -n 'GuidedDenoiser('` finds SEVEN construction sites, three `GuidedDenoiser` and four `FactoryGuidedDenoiser`, which is a stronger statement than the filing's retake-only check: `a2vid_two_stage.py:230`, `keyframe_interpolation.py:232`, `retake.py:305`, `t2a_one_stage.py:155`, `ti2vid_one_stage.py:221`, `ti2vid_two_stages.py:248`, `ti2vid_two_stages_hq.py:271`. None passes the keyword, so all seven take the `force_uncond_pass: bool = False` default. The flag is a CFG++ affordance per `CLAUDE.md:76`: run the uncond pass even when `cfg_scale=1.0`, because CFG++ still needs the uncond prediction for the ordinary differential equation derivative. Upstream ships the plumbing and turns it on nowhere. TWO SMALLER ERRORS RIDE ALONG: the header cited the declaration as `:76`, which is the DOCSTRING and not the declaration at `:74`; and both comments cited `retake.py:305-311`, whose last line is BLANK, the construction being `:305-310`. THE CODE WAS ALREADY RIGHT and nothing about behavior changed: `Ltx2GuidedDenoiseInputs::force_uncond_pass` defaults to `false`, `grep -rn force_uncond_pass src/ include/ tests/` finds two reads and no assignment, and the condition at `ltx2_denoisers.cpp` mirrors `denoisers.py:102-103` operand for operand. This is a documentation defect ONLY, and no wider scope was taken. THE ANCHOR WAS LOAD-BEARING, which is why it is a bug and not a typo: a reader who trusts it concludes retake is missing a flag upstream sets and sets it, and `force_uncond_pass` adds an uncond pass per PRESENT modality, doubling retake's DiT forward count from 8 to 16 and changing its output. The comment invited the exact divergence it appeared to describe. A comment-only change CANNOT be red-first tested, and this row does not pretend otherwise: the evidence is the upstream re-derivation above, cited by `file:line` at the pin, and an independent reviewer re-derived it rather than reading it. FIXED IN FLOW, comment text only. Two specs were checked and deliberately NOT edited: `ltx25-retake.md` never mentions the field, and `ltx25-guided-video.md:198` states the CONDITION without claiming a caller, which is true at the pin | bug | +| [#1809](https://github.com/mudler/vllm.cpp/issues/1809) | `GATE-CI-ENFORCEMENT-FLOOR` | **`commit-protocol-tag` and `documentation-checkpoint` have been red on `main` since 2026-08-13 and cannot recover on their own: their walk bases on the head of the last SUCCESSFUL push run, so one unrepairable commit freezes the base and every later push re-walks the same violations over a range one commit wider.** Re-measured 2026-08-23 at `bacb71109`: `LAST_GREEN` is `fafa16f0f` of 2026-08-13T01:53, the range is **499** first-parent commits with **0** merges, and **41 distinct commits** in it can never be repaired because they are on `main` and adding a trailer or a task-branch arrival needs a rewrite `AGENTS.md` forbids — **35** fail `check-commit-trailers.py --range` (of which **20** carry no `FOLLOWING_AGENTS_PROTOCOL` marker at all and the other **15** carry it 1 to 9 times in a form the strict contract rejects, so the two counts describe the same population under different contracts, not different walks) and **6** disjoint ones fail `check-role-discipline.py` for a repository change that reached `main` with no task branch; `check-now-current.py` passes over the whole range and forgives nothing. The `LAST_GREEN` base is RIGHT about what it was built for and is not reverted: `github.event.before` skips a cancelled run's commits and nothing re-covers them, which is what lets the push lane be latest-only ([#822](https://github.com/mudler/vllm.cpp/issues/822), [#863](https://github.com/mudler/vllm.cpp/issues/863)), and cancelled runs are common here ([#1285](https://github.com/mudler/vllm.cpp/issues/1285)). FIXED IN FLOW with a recorded **enforcement floor** in `scripts/ci-enforcement-floor.txt` — one commit the walk never goes behind — taken as the newer of `LAST_GREEN` and the floor by ANCESTRY (`git merge-base --is-ancestor`, never by commit date, which is author-controlled and can go backwards). Losslessness survives because the floor is a lower clamp on an otherwise unchanged base: while the floor sits behind `LAST_GREEN`, which is the steady state, the resolved base is byte-identical to today's, and the only window that skips anything is `LAST_GREEN..floor` right after an advance — bounded, reviewed, and enumerated in the spec. The four byte-similar copies of the selection in `.github/workflows/ci.yml` collapse into `scripts/ci-walk-base.py`, which is the point of the extraction: **no test in the tree executed any of those four inline shell blocks**, and the property most likely to break silently now has one that replays a cancelled-run sequence against a real throwaway repository with the naive `before` base as its positive control. A per-commit exemption list was REJECTED — `AGENTS.md` has no waiver registry, the mechanism would have to be built three more times in checkers that have no exemption concept, and it never shrinks the walk, so the range grows by one per merge forever. This NARROWS enforcement by 41 commits and says so: enforcing on an immutable landed commit is a permanent red rather than a gate, because no contributor action can clear it, and a permanent red is read by nobody ([#1722](https://github.com/mudler/vllm.cpp/issues/1722)'s effect). No assertion is deleted and no checker is modified; only the base of the walk moves, and a new violation after the floor still reds, proved by a scratch-commit mutation rather than by reading the diff. Spec [ci-enforcement-floor.md](specs/ci-enforcement-floor.md) | bug | diff --git a/.agents/specs/ci-enforcement-floor.md b/.agents/specs/ci-enforcement-floor.md new file mode 100644 index 000000000..2f6bd2b6f --- /dev/null +++ b/.agents/specs/ci-enforcement-floor.md @@ -0,0 +1,359 @@ +# The diff-scoped gates get a floor, so an unrepairable commit cannot freeze them + +Issue: [#1809](https://github.com/mudler/vllm.cpp/issues/1809) +Row: `GATE-CI-ENFORCEMENT-FLOOR` + +The main-branch diff-scoped gates walk from the head of the last SUCCESSFUL push +run. That base is what makes a cancelled run lossless (#822, #863). It is also +what turns one unrepairable commit into a permanent red: no green run means the +base never advances, so every later push re-walks the same violations and adds +its own commit to the range. + +This row keeps the self-healing base and clamps it from below with a recorded +**enforcement floor** — one commit the walk never goes behind. It also moves the +base selection out of four copies of inline workflow shell and into one script +that has a test suite. + +## Why + +### Measured, 2026-08-23, at `bacb71109c8d63b5f862c9b121dd86e04e1a07ee` + +`gh api repos/mudler/vllm.cpp/actions/workflows/ci.yml/runs?branch=main&event=push&status=success&per_page=1` +returns `fafa16f0f32acc8255e113a2cbc35f8b99cf2072`, whose commit date is +2026-08-13T01:53:21+02:00. That is `LAST_GREEN`, and it is ten days stale. + +| Quantity | Value | +|---|---| +| First-parent commits in `fafa16f0f..bacb71109` | 499 | +| Of those, merge commits | 0 | +| `commit-protocol-tag` grep step: commits with no `FOLLOWING_AGENTS_PROTOCOL` | 20 | +| `commit-protocol-tag` strict step: commits failing `check-commit-trailers.py --range` | 35 | +| `documentation-checkpoint`: commits failing `check-role-discipline.py` | 6 | +| `documentation-checkpoint`: `check-now-current.py` | passes | + +The range is linear — `rev-list` and `rev-list --first-parent` both return the +same 499 commits — so the two trailer walks cover the same population and the +grep step's 20 are a strict subset of the strict step's 35. The difference is the +contract, not the walk: the grep asks whether the marker appears at all, and the +other 15 commits carry it (once to nine times, measured) in a form +`check-commit-trailers.py` rejects. Presence is not parseability. The 6 +role-discipline commits are disjoint from the 35. **41 distinct commits.** + +### Why no remedy exists + +Every one of the 41 is on `main`. A trailer or a task-branch arrival can only be +added to a commit by rewriting it, and `AGENTS.md` forbids rewriting `main` +without exception. So the gate asks for a repair that cannot be performed, and +the loop closes: + +``` +main is red -> no successful push run -> LAST_GREEN frozen + -> next push walks a range one commit wider + -> re-hits the same 41 -> still red +``` + +The practical effect is #1722's effect: a job that is always red trains every +reader to skip it, and a skipped job protects nothing. Violations kept arriving +during the freeze and nobody read the gate that named them — +`1757330006f6` landed without the trailer on 2026-08-23, and `6e73bdee3` landed +without a task branch the same day. + +### The property that must survive + +`ci.yml` records the reason for the `LAST_GREEN` base at its definition: +`github.event.before` is the previous push's sha whether or not that push was +gated, so a cancelled run's commits are skipped and **nothing re-covers them**. +That is what allows the push lane to be latest-only (#822), and reverting the +base to `before` reintroduces exactly the gap #863 measured. Cancelled runs are +common here (#1285). Losslessness is therefore a requirement on the fix, not a +nice-to-have. + +## Design + +### The floor + +One commit sha, recorded in `scripts/ci-enforcement-floor.txt`. The walk never +starts behind it. + +``` +base = last_green or before # unchanged +if floor is newer than base: # newer == base is a proper ancestor of floor + base = floor +``` + +"Newer" is decided by ancestry, not by date: `git merge-base --is-ancestor`. +A commit date is author-controlled and can go backwards across a rebase, so a +date comparison can choose the wrong commit; ancestry on a linear first-parent +`main` cannot. + +The floor is set to `bacb71109c8d63b5f862c9b121dd86e04e1a07ee`, which is past +all 41 commits enumerated below. + +### The base selection moves into a script + +`scripts/ci-walk-base.py` resolves the base for every diff-scoped gate. +`.github/workflows/ci.yml` had four byte-similar copies of the selection — +`agent-record`'s role-discipline step, `documentation-checkpoint`, +and both steps of `commit-protocol-tag`. Four copies of a rule is four places to +get the floor wrong, and inline YAML shell has no test surface at all: nothing in +`tests/scripts/` executed any of those four blocks before this change. The +extraction is what makes requirement 2 testable, which is the strongest argument +for doing it. + +Contract: + +``` +scripts/ci-walk-base.py --event --head + [--pr-base ] [--push-base ] [--last-green ] + [--floor-file ] [--floor ] +``` + +It prints the resolved base on stdout, diagnostics on stderr, and exits non-zero +only on an unusable floor record or an invalid argument. + +Resolution order, in one place: + +1. `pull_request` lane: return `pull_request.base.sha` unchanged. The floor does + not apply — see "Why the floor is push-lane only". +2. Otherwise `base = LAST_GREEN`, falling back to `github.event.before`. +3. If `base` is empty or unknown to git — the all-zero sha of a new branch, or a + force-push whose `before` is gone — return it unchanged, so the existing + downstream guard still degrades to the tip commit alone. The floor raises a + USABLE base; it never substitutes for an unusable one. +4. If the floor is unknown to git, or is not an ancestor of `head`, warn on + stderr and return `base` unchanged. A floor that the current history does not + contain cannot bound that history, and `floor..head` for an unrelated floor + is not a range anybody asked for. +5. If the floor is an ancestor of `base`, `base` is already at or past the floor: + return `base`. +6. Otherwise return the floor. + +### Why the floor is push-lane only + +The pull-request lane bases on `pull_request.base.sha` and has been green +throughout the freeze — verified on #1786 on 2026-08-23. Applying the floor +there would only ever raise a base, which is a narrowing of what that lane +enforces, and no defect asks for it. The narrowest change that fixes the bug +leaves the PR lane byte-identical. + +### Cancelled runs stay lossless + +The floor is a lower clamp on a base that is otherwise chosen exactly as it is +today. While the floor is behind `LAST_GREEN` — which is the steady state, since +`LAST_GREEN` advances on every green push and the floor only advances when a +human commits an advance — step 5 returns `LAST_GREEN` and the resolved base is +byte-identical to today's. A cancelled run does not advance `LAST_GREEN`, the +next run walks the wider range, and the cancelled run's commits are covered. + +The one window where losslessness is suspended is the interval +`LAST_GREEN..floor` immediately after a floor advance. That window is exactly the +forgiveness being asked for, it is bounded by a recorded sha, and what it +forgives is enumerated below. It is not silent. + +`tests/scripts/test_ci_walk_base.py::CancelledRunLosslessTests` builds a real +throwaway repository and replays the sequence: C1 gated green, C2 pushed and its +run cancelled, C3 pushed. It asserts the resolved base is C1 and that +`rev-list base..C3` CONTAINS C2 — and, as the positive control that proves the +assertion discriminates, that the naive `github.event.before` base for the same +push resolves to C2 and its range does NOT contain C2. + +### What is narrowed, and the argument for it + +This change narrows enforcement: 41 commits that the gate currently reports are +no longer walked. The argument is that enforcing on an immutable already-landed +commit is not enforcement. There is no action any contributor can take that +turns those 41 reds green, because the only action that would is a `main` +rewrite the protocol forbids. A gate with no available remedy is a permanent +red, and a permanent red is read by nobody — which is a strictly worse outcome +than a smaller gate that is read. + +The gate's purpose is to stop a NEW violation, and that is untouched: a commit +landing after the floor with no trailer, or with no task branch, still reds the +job. Proved by mutation, not by reading the diff — see `## Gates`. + +No assertion is deleted. `check-commit-trailers.py`, `check-role-discipline.py` +and `check-now-current.py` are not modified by this row, and the grep step's +condition is unchanged. Only the base of the walk moves. + +### Advancing the floor + +Editing one line of `scripts/ci-enforcement-floor.txt`, in a reviewed pull +request whose body says which commits the advance forgives and why each is +unrepairable. Git is the history of the floor: `git log -p` on that file lists +every advance with its reason. There is no registry and no accumulating list. + +This does not make an unrepairable commit free. It makes it cost a reviewed +commit that has to name it, which is what `AGENTS.md` means by visible debt. + +### Where the floor lives, and the record-lock rule + +`AGENTS.md` `## Records` forbids a surface that every pull request must write. +The floor is not one: an ordinary pull request never touches it, and only a +deliberate advance does. A one-value data file beside the script that reads it +matches `scripts/*-allowlist.txt`, which are the tree's existing shape for a +script's data. + +Rejected homes: + +- **A top-level `env:` in `ci.yml`.** No new file, but `ci.yml` has no top-level + `env:` block today and seven checkers and test suites parse that file. A + structural addition risks a red that has nothing to do with this row. +- **A git ref or tag.** Movable without review and invisible in a diff, which + removes the whole reason for choosing a floor over a time window. +- **A new `.agents/` document.** `check-pr-size.py::classify_path` fails closed + on an unclassified path, so the file would require an edit to + `check-pr-size.py`, which is itself a governance-checker change requiring its + own mutation evidence. A cascade in exchange for nothing. + +### The alternative that was rejected + +**A per-commit exemption list**: keep walking `LAST_GREEN..HEAD` forever and +name the 41 shas in a file the checkers consult. It records more precisely than a +floor does, and `check-commit-trailers.py` already carries one landed-message +exception, so the mechanism is not foreign. + +Rejected on three grounds: + +1. `AGENTS.md` `## Changing the rules or a checker` states the project has no + waiver registry, because an exception registry is a state log and this + protocol has no state log. One in-checker exception carrying its reason is + not a registry; a file of 41 growing to N is precisely one. +2. It needs the mechanism built three more times. The grep step and + `check-role-discipline.py` have no exemption concept, so the change would add + an exemption surface to code that currently has none — more new enforcement + machinery than the fix it delivers. +3. It never shrinks the walk. The range stays 499 commits and grows by one per + merge forever, so the cost and the log noise of every run grow without bound, + and the next unrepairable commit appends to the list rather than being + confronted. The floor bounds the walk and makes forgiveness cost a review. + +Also considered and rejected: reverting the base to `github.event.before` +(reintroduces #863 outright); making the two jobs report-only (`AGENTS.md` +`## Gates`: a permanent report-only state is not a result); and a rolling +time-window base such as "the newer of `LAST_GREEN` and 7 days ago", which +forgives continuously and silently and records nothing. + +## Scope + +In scope: + +- `scripts/ci-walk-base.py`, new. +- `scripts/ci-enforcement-floor.txt`, new: the recorded floor. +- `tests/scripts/test_ci_walk_base.py`, new. +- `.github/workflows/ci.yml`: the four base-selection blocks call the script. +- `scripts/agent-preflight.sh`: the new suite joins `SUITES`. + +Out of scope, deliberately: + +- Repairing the 41 commits. It cannot be done without rewriting `main`. +- The three checkers themselves. Not one line changes. +- `agent-record`'s missing-`hugo` red (#1722, fix in flight as #1726) and the two + `windows-msvc` reds (#584). Both are inherited and neither is this row's. +- The PR lane's base selection, which is unchanged. + +## The 41 forgiven commits + +Real protocol violations that landed unread between 2026-08-13 and 2026-08-23, +recorded here because after the floor advances no gate will name them again. + +### Fail `check-commit-trailers.py --range` (35) + +| Commit | Date | Subject | +|---|---|---| +| `7572b0f4e2fb` | 2026-08-13 | guard the parity pin header against declaration-order breaks (#558) | +| `7ba9a675f491` | 2026-08-13 | feat(rocm): implement the vt::Backend graph-capture seam on hipGraph (W1, #332) (#473) | +| `7965f12bf4bc` | 2026-08-13 | fix(GATE-PR-SIZE-BINARY): retire the fail-closed binary guard (#615) (#619) | +| `a3aa02e197ec` | 2026-08-14 | spec(MODEL-MUSIC-MUSIC3): scope MiniMax-Music3 (#672) (#679) | +| `34dc578760d0` | 2026-08-14 | oracle(MODEL-MUSIC-MUSIC3): the diffusers oracle GENERATES AUDIO (#672) (#708) | +| `8d0c2779b91a` | 2026-08-14 | feat(MODEL-MUSIC-MUSIC3): W1 — the modular checkpoint loader (#672) (#714) | +| `373aa125142a` | 2026-08-14 | spec(BACKEND-ROCM): the ROCm head_dim=128 decode arm (#564) | +| `f8cbc2310bca` | 2026-08-14 | fix(#664): the video registry's existence probes stop reaching Windows with POSIX stat | +| `0011bedf0c75` | 2026-08-14 | fix(#720): M_PI is not defined by MSVC | +| `fc903b8dd73f` | 2026-08-14 | fix(#674): the LTX-2.5 VAE loader read the safetensors mmap through a uint16_t* | +| `9f2b9bb9a30b` | 2026-08-14 | feat(tenstorrent): allowlist MistralForCausalLM + device-aware gate (#431) | +| `d8efb1fa0ccf` | 2026-08-14 | build(nix): add rocwmma to the ROCm dev shell (#444) (#638) | +| `3921160e569d` | 2026-08-14 | fix(#757): six C4456 shadowed locals block the Windows test compile | +| `c629b5d0ff78` | 2026-08-14 | feat(ltx-2.5): image conditioning at crf=0 (#644) | +| `5da1d7f2fa89` | 2026-08-14 | fix(GATE-FORK-ANCESTRY): diff a PR from its merge base (#773) (#782) | +| `ddff09093663` | 2026-08-15 | policy(POLICY-SINGLE-PR-AND-STYLE): one PR carries the spec and its code (#827) | +| `be4a3edf1727` | 2026-08-15 | fix(GATE-WINDOWS-WARNING-POLICY): /WX- is not /WX (#774) (#795) | +| `6680aab68912` | 2026-08-15 | fix(GATE-AUDIT-BRANCH-EVIDENCE): reach the IN-FLIGHT verdict in CI (#726) (#802) | +| `ca01719e6b29` | 2026-08-15 | fix(#772): four loaders cast mmap'd safetensors to uint16_t* (#815) | +| `3ce5a1dc1b0f` | 2026-08-15 | feat(MUSIC3-W7): a gated GGUF Q4_K arm (#672) (#832) | +| `51e0cb5b15fe` | 2026-08-15 | policy(POLICY-ISSUE-INTAKE): the issue index moves out of the roadmap (#846) | +| `b5a5f3b182d7` | 2026-08-15 | feat(MODEL-MUSIC-MUSIC3): W2's remainder (#672) (#831) | +| `6e6bba63d7c1` | 2026-08-15 | fix(GATE-OP-PARITY-MANIFEST): refuse a throwing golden by name (#776) (#853) | +| `bc570da0d387` | 2026-08-15 | MODEL-NEMOTRON-H: the WEIGHT LOADER (#752) | +| `34962d96bea0` | 2026-08-15 | fix(#775): the NemotronH forward's downcast was a promise, not a check (#868) | +| `b3d0f3ed5dc8` | 2026-08-15 | fix(capi): hoist SpeechRegistry() out of extern "C" (#805) (#814) | +| `1e2408526419` | 2026-08-15 | docs(dspark): the user-facing docs asserted a ratio measurement has refuted (#442) (#894) | +| `04be1390b227` | 2026-08-15 | fix(FIX-REGISTRY-DOWNCAST-SWEEP): open every registry handle with a check (#901) | +| `b5f27c9a4c7d` | 2026-08-15 | record(intake): place #904, the third sanitize-cpu red (#906) | +| `2688e6586675` | 2026-08-15 | fix(MODEL-MUSIC-MUSIC3): the e2e gate asked for 60 s of music (#852, #925) (#942) | +| `e34d71379e70` | 2026-08-16 | fix(qwen3.5): drop redundant AppleClang capture (#1054) | +| `aba8d5ffb77c` | 2026-08-18 | instrument(MUSIC3): a per-stage split (#672) (#1231) | +| `055ff1143704` | 2026-08-21 | docs: align README with current surfaces (#1302) | +| `2d2a66715ef4` | 2026-08-22 | fix(#817): CAMPPlus trusted a default over the weight (#1739) | +| `1757330006f6` | 2026-08-23 | fix(BACKEND-TENSTORRENT-GDN): W2 review repairs (#1715) | + +The 20 that also fail the grep step are the subset of the above whose message +carries no `FOLLOWING_AGENTS_PROTOCOL` string at all: `7572b0f4e2fb`, +`7ba9a675f491`, `7965f12bf4bc`, `373aa125142a`, `9f2b9bb9a30b`, `be4a3edf1727`, +`6680aab68912`, `ca01719e6b29`, `b5a5f3b182d7`, `6e6bba63d7c1`, `bc570da0d387`, +`34962d96bea0`, `b3d0f3ed5dc8`, `04be1390b227`, `b5f27c9a4c7d`, `2688e6586675`, +`e34d71379e70`, `aba8d5ffb77c`, `2d2a66715ef4`, `1757330006f6`. The remaining 15 +carry the marker in a form the strict contract rejects. + +### Fail `check-role-discipline.py` (6) + +Repository changes that reached `main` without arriving on a task branch. + +| Commit | Date | Subject | +|---|---|---| +| `dd8a3b0e184c` | 2026-08-17 | windows: fix native MSVC/Vulkan build portability | +| `8daf58e7752f` | 2026-08-18 | fix(ENG-RELEASE-WINDOWS): the api-server gate can report its own failure again | +| `38ec0da4aae8` | 2026-08-18 | feat(BACKEND-ROCM): register a ROCm attention backend for kROCM | +| `5073df62228e` | 2026-08-18 | feat(BACKEND-ROCM): select the attention backend in the runner | +| `65d6cdaed3e2` | 2026-08-18 | build: make the tree compile on gcc 16, and add a CI lane so it stays that way | +| `6e73bdee3ea1` | 2026-08-23 | fix(LTX25-POSITION-CONTRACT): gate the tower positions as integers | + +`check-now-current.py` passes over the whole range and forgives nothing. + +## Gates + +| Gate | Command | Result | +|---|---|---| +| G1 base selection | `python3 tests/scripts/test_ci_walk_base.py` | see `## Outcome` | +| G2 cancelled-run losslessness | `python3 -m unittest -v tests.scripts.test_ci_walk_base.CancelledRunLosslessTests` | see `## Outcome` | +| G3 a new violation still reds | scratch commit with no trailer on top of the floor, `commit-protocol-tag`'s grep body replayed with the resolved base | see `## Outcome` | +| G4 the deadlock is broken | the same body replayed on unmutated `HEAD` with the floor in place | see `## Outcome` | +| G5 preflight | `scripts/agent-preflight.sh` | see `## Outcome` | + +## Risks + +1. **A violating commit lands between the recorded floor and the merge of this + row.** The gate reds on that one commit, correctly, and the remedy now exists: + advance the floor in a reviewed commit that names it. This is the designed + behaviour and not a regression, but it means the floor value has to be + re-checked immediately before merge. +2. **The floor is set too far forward by mistake.** It would skip commits nobody + examined. Mitigated by ancestry — a floor ahead of `HEAD` is not an ancestor + of `HEAD` and is ignored with a warning rather than silently trusted — and by + `RecordedFloorTests`, which fails when the recorded floor is not a real + ancestor of `HEAD`. +3. **The script fails and takes four gates with it.** It runs under `set -eu` in + a command substitution, so a crash reds the job. That is fail-closed and the + right direction, but it makes the script's own suite load-bearing; it is + registered in `agent-record` and in `scripts/agent-preflight.sh`. +4. **Someone re-inlines the base selection into the YAML.** The suite asserts + that `ci.yml` carries no residual `base="${LAST_GREEN:-}"` fallback and that + the script is invoked once per diff-scoped step, so a re-inlining reds. + +## Owed + +Nothing. The 41 commits are recorded above rather than owed: no future change can +repair them. + +## Now + +`ACTIVE`. Spec committed ahead of the implementation on `row/1809`. From 6de046d361da6a4f866ed0b34ce11e2a129d9872 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Sun, 23 Aug 2026 20:23:12 +0000 Subject: [PATCH 02/11] fix(GATE-CI-ENFORCEMENT-FLOOR): the diff-scoped walk gets a floor, and its base rule gets a test (#1809) The base of the diff-scoped walk on `main` is the head of the last SUCCESSFUL push run. That is what makes a cancelled run lossless (#822, #863) and it is kept. What it did not anticipate is a violation with no available remedy: 41 commits between 2026-08-13 and 2026-08-23 are on `main` and can only be repaired by rewriting `main`, which AGENTS.md forbids. No green run is reachable, the base freezes, and every later push re-walks the same violations over a range one commit wider. `commit-protocol-tag` and `documentation-checkpoint` have been red for ten days for that reason alone. `scripts/ci-enforcement-floor.txt` records one commit the walk never goes behind, and the base becomes the newer of the last green commit and that floor, decided by `git merge-base --is-ancestor` rather than by a commit date an author controls. The floor is a LOWER CLAMP on an otherwise unchanged base, so while it sits behind the last green commit -- the steady state, because that commit advances on every green push and the floor advances only when somebody commits an advance -- the resolved base is byte-identical to today's and a cancelled run is still covered by the next run. The one window that skips anything is `last_green..floor` right after an advance, which is the forgiveness being asked for and is enumerated commit by commit in the spec. This narrows enforcement by 41 commits and the spec argues for the narrowing rather than hiding it: enforcing on an immutable landed commit is a permanent red and not a gate, because no contributor action clears it, and a permanent red is read by nobody. No assertion is deleted, no checker is modified, and a violation landing after the floor still reds. The four byte-similar copies of the selection collapse into `scripts/ci-walk-base.py`. Of those four inline blocks exactly one was ever replayed by a test, `agent-record`'s, and only under a shim that stubs every `python3` call -- so it pinned which checker ran with which range string and could not see the base rule. The extraction is what makes cancelled-run losslessness an executable assertion: the new suite replays the sequence against a real throwaway repository and carries the naive `github.event.before` base as its positive control. Three existing assertions moved rather than went away, because the rule they matched as a string now lives somewhere else. `test_main_baseline`'s shim executes the resolver for real instead of stubbing it, so its cases test the real composition; its `before` fallback case and `test_agent_gates`'s role-range case now EXECUTE the resolver instead of grepping the YAML, which is a stronger statement than the literal each replaces. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code] --- .agents/issue-index.md | 2 +- .agents/specs/ci-enforcement-floor.md | 17 +- .github/workflows/ci.yml | 94 ++++--- scripts/agent-preflight.sh | 1 + scripts/ci-enforcement-floor.txt | 25 ++ scripts/ci-walk-base.py | 205 +++++++++++++++ tests/scripts/test_agent_gates.py | 36 ++- tests/scripts/test_ci_walk_base.py | 351 ++++++++++++++++++++++++++ tests/scripts/test_main_baseline.py | 59 ++++- 9 files changed, 751 insertions(+), 39 deletions(-) create mode 100644 scripts/ci-enforcement-floor.txt create mode 100755 scripts/ci-walk-base.py create mode 100644 tests/scripts/test_ci_walk_base.py diff --git a/.agents/issue-index.md b/.agents/issue-index.md index ebac6c518..8300d79ed 100644 --- a/.agents/issue-index.md +++ b/.agents/issue-index.md @@ -664,4 +664,4 @@ rather than merged. `scripts/check-agent-record.py` gates both. | [#1777](https://github.com/mudler/vllm.cpp/issues/1777) | `GATE-FP8-NUMERIC-BOUND` | **Layer 2 of [#1189](https://github.com/mudler/vllm.cpp/issues/1189)'s `## Gate design` had no implementation, and nothing in the tree could see a per-tensor scale collapse.** Layer 1 passed on 2026-08-23 (`rc` job `2911ed39`, `TOKEN_VERDICT=PASS`), and the header of `tests/parity/test_qwen27n_fp8_tower_paged_engine.cpp` records why that is not enough: a x1.02 AND a x1.10 perturbation of every FP8 weight scale were demonstrably REACHED on the dgx production build and both still produced 16/16 IDENTICAL tokens, with only x2.00 failing. So a wrong-but-close scale and a silent dequant -- which is numerically BETTER than the quantized path -- are invisible to every token comparison here. The audit corrects the brief in one place rather than re-implementing what exists: the SHAPE ASSERTION at the GEMM boundary is already DONE in two places, `src/vt/ops.cpp::MatmulFp8BlockScaled` asserting `b_scale == [cdiv(N,block_n), cdiv(K,block_k)]` (pinned by `test_ops_matmul_fp8_block_cpu.cpp` G5) and `Fp8BlockScaledRefusalFor` refusing `N % 128` / `K % 128` BY NAME before CUTLASS can answer `Invalid status` (#1453, pinned by G4/G6), and the CUDA TU's own comment at the refusal site says so. FIXED IN FLOW: `tests/vllm/model_executor/models/test_fp8_block_numeric_bound.cpp` bounds every projection against the fixture's independent `double` reference through the production `Fp8BlockLinearMethod::Apply`, TWO-SIDED in the same case -- clean UNDER the bound and x1.10 OVER it, per shape per dtype, plus a 4x margin over the grid -- because a one-directional bound stops biting the moment somebody widens it and nothing would say so. Measured over six shapes: bf16 clean 3.82e-3 against x1.10 1.034e-1 at `kBoundBf16 = 2e-2` (5.2x each way), f32 clean 6.20e-6 against 1.000e-1 at `kBoundF32 = 1e-4`. The statistic floors its denominator at 1% of the projection's own maximum, and that was MEASURED rather than assumed: unfloored, the clean f32 reading moves 835x on one shape because a single output element cancels to near zero, which is a number that cannot carry a bound. `dense_fp8_block::Fp8BlockScaleSpread` is the scale-variance probe #1189 asks for, a max/min RATIO because the issue pins the degenerate reading at exactly 1.0 where a variance reads 0.0, carried with the GEMM counter in one `Fp8BlockStats` snapshot; single-cell grids are counted APART from collapsed ones because 11 of the model fixture's 13 grids hold one cell and a probe that reads 11 on a healthy model is one nobody believes. The split arm also gained the two GEMM-boundary operand assertions the merged arm has carried since M6 -- without the packed one, a short buffer is read PAST ITS END by the first GEMM and the call returns a value. Seven mutations in both directions, tar-snapshotted and `sha256sum -c` verified after each: x1.10 RED 14 assertions, x1.02 RED 14, the same 14 (not predicted: the bf16 readings come in at 2.32e-2 to 2.39e-2 against the 2e-2 bound because the truncating store compounds ON TOP of the scale error, so the bf16 half is caught by only 1.16x and the f32 half by 200x), the bound widened to 1.0 RED 6, a collapsing load path RED 14 across 2 cases, the probe's accounting RED 2, and each new operand assertion RED when defanged. CPU tier throughout, so `build-test-cpu` and `sanitize-cpu` run all of it on every pull request; `cuda-fat-build` runs no `ctest` and nothing here rests on it. **#1189 is NOT closed**: its gate design is now covered but its six milestones' `## Owed` sections are live, and no closing keyword appears in this change. Spec [`gate-fp8-numeric-bound.md`](specs/gate-fp8-numeric-bound.md) | gap | | [#1779](https://github.com/mudler/vllm.cpp/issues/1779) | `GATE-PREPUSH-FAIL-LOUD` | **`.githooks/pre-push` named six checkers and three of them had no file, and its file-test guard skipped each missing one in silence while the hook still exited 0** -- so it presented as six gates and ran three, and `core.hooksPath` is set to `.githooks` here, so it runs on every push. `check-policy.py` and `check-state-record.py` went with `0f3e44eee`, `check-public-doc-tables.py` with #1714; all three are deleted, not renamed. PART 1 FIXED IN FLOW: the loop now refuses a name it cannot find, the three dead names are pruned, the dead `--base` case arm goes with them, and `.githooks/README.md` stops listing the retired table gate. A red-first suite executes the hook against a scratch repository and pins both directions. PART 2 IS NOT FIXED AND STAYS OWED under `## Owed` in `.agents/specs/gate-prepush-fail-loud.md`: 65 specs still name a deleted checker, which needs its own row | bug | | [#1528](https://github.com/mudler/vllm.cpp/issues/1528) | `LTX25-GUIDED-VIDEO` | **Two comments in the LTX-2.5 guided denoiser named `RetakePipeline` as the one upstream caller that sets `force_uncond_pass`, and NO upstream caller sets it at `fd4ded7f`.** `include/vllm/model_executor/models/ltx2_denoisers.h:144-145` and `src/vllm/model_executor/models/ltx2_denoisers.cpp:111-113`, both from `daeff67f2` (row `LTX25-GUIDED-VIDEO`, [#1092](https://github.com/mudler/vllm.cpp/issues/1092), PR [#1102](https://github.com/mudler/vllm.cpp/pull/1102)). Re-derived at the local `Lightricks/LTX-2` checkout whose `git rev-parse HEAD` is `fd4ded7f2d88d3da713abcdd4ad41ecc4a9314ca`, the revision `.agents/specs/ltx25-guided-video.md:6` pins. `git grep -n force_uncond_pass` over the WHOLE tree, not only `*.py`, returns 11 LINES and not one is an assignment by a caller (the filing counted 10 because it restricted the grep to `*.py`; the two counts agree and name different populations): `utils/denoisers.py:74` declares the `_guided_denoise` keyword, `:102-103` are the two reads, `:267,273,297` are `GuidedDenoiser` storing and forwarding it, `:313,319,357` are `FactoryGuidedDenoiser` doing the same, `utils/samplers.py:692` is the substring `force_uncond_pass=True` inside a raised ERROR MESSAGE, and `packages/ltx-pipelines/CLAUDE.md:76` documents it. `git grep -n 'GuidedDenoiser('` finds SEVEN construction sites, three `GuidedDenoiser` and four `FactoryGuidedDenoiser`, which is a stronger statement than the filing's retake-only check: `a2vid_two_stage.py:230`, `keyframe_interpolation.py:232`, `retake.py:305`, `t2a_one_stage.py:155`, `ti2vid_one_stage.py:221`, `ti2vid_two_stages.py:248`, `ti2vid_two_stages_hq.py:271`. None passes the keyword, so all seven take the `force_uncond_pass: bool = False` default. The flag is a CFG++ affordance per `CLAUDE.md:76`: run the uncond pass even when `cfg_scale=1.0`, because CFG++ still needs the uncond prediction for the ordinary differential equation derivative. Upstream ships the plumbing and turns it on nowhere. TWO SMALLER ERRORS RIDE ALONG: the header cited the declaration as `:76`, which is the DOCSTRING and not the declaration at `:74`; and both comments cited `retake.py:305-311`, whose last line is BLANK, the construction being `:305-310`. THE CODE WAS ALREADY RIGHT and nothing about behavior changed: `Ltx2GuidedDenoiseInputs::force_uncond_pass` defaults to `false`, `grep -rn force_uncond_pass src/ include/ tests/` finds two reads and no assignment, and the condition at `ltx2_denoisers.cpp` mirrors `denoisers.py:102-103` operand for operand. This is a documentation defect ONLY, and no wider scope was taken. THE ANCHOR WAS LOAD-BEARING, which is why it is a bug and not a typo: a reader who trusts it concludes retake is missing a flag upstream sets and sets it, and `force_uncond_pass` adds an uncond pass per PRESENT modality, doubling retake's DiT forward count from 8 to 16 and changing its output. The comment invited the exact divergence it appeared to describe. A comment-only change CANNOT be red-first tested, and this row does not pretend otherwise: the evidence is the upstream re-derivation above, cited by `file:line` at the pin, and an independent reviewer re-derived it rather than reading it. FIXED IN FLOW, comment text only. Two specs were checked and deliberately NOT edited: `ltx25-retake.md` never mentions the field, and `ltx25-guided-video.md:198` states the CONDITION without claiming a caller, which is true at the pin | bug | -| [#1809](https://github.com/mudler/vllm.cpp/issues/1809) | `GATE-CI-ENFORCEMENT-FLOOR` | **`commit-protocol-tag` and `documentation-checkpoint` have been red on `main` since 2026-08-13 and cannot recover on their own: their walk bases on the head of the last SUCCESSFUL push run, so one unrepairable commit freezes the base and every later push re-walks the same violations over a range one commit wider.** Re-measured 2026-08-23 at `bacb71109`: `LAST_GREEN` is `fafa16f0f` of 2026-08-13T01:53, the range is **499** first-parent commits with **0** merges, and **41 distinct commits** in it can never be repaired because they are on `main` and adding a trailer or a task-branch arrival needs a rewrite `AGENTS.md` forbids — **35** fail `check-commit-trailers.py --range` (of which **20** carry no `FOLLOWING_AGENTS_PROTOCOL` marker at all and the other **15** carry it 1 to 9 times in a form the strict contract rejects, so the two counts describe the same population under different contracts, not different walks) and **6** disjoint ones fail `check-role-discipline.py` for a repository change that reached `main` with no task branch; `check-now-current.py` passes over the whole range and forgives nothing. The `LAST_GREEN` base is RIGHT about what it was built for and is not reverted: `github.event.before` skips a cancelled run's commits and nothing re-covers them, which is what lets the push lane be latest-only ([#822](https://github.com/mudler/vllm.cpp/issues/822), [#863](https://github.com/mudler/vllm.cpp/issues/863)), and cancelled runs are common here ([#1285](https://github.com/mudler/vllm.cpp/issues/1285)). FIXED IN FLOW with a recorded **enforcement floor** in `scripts/ci-enforcement-floor.txt` — one commit the walk never goes behind — taken as the newer of `LAST_GREEN` and the floor by ANCESTRY (`git merge-base --is-ancestor`, never by commit date, which is author-controlled and can go backwards). Losslessness survives because the floor is a lower clamp on an otherwise unchanged base: while the floor sits behind `LAST_GREEN`, which is the steady state, the resolved base is byte-identical to today's, and the only window that skips anything is `LAST_GREEN..floor` right after an advance — bounded, reviewed, and enumerated in the spec. The four byte-similar copies of the selection in `.github/workflows/ci.yml` collapse into `scripts/ci-walk-base.py`, which is the point of the extraction: **no test in the tree executed any of those four inline shell blocks**, and the property most likely to break silently now has one that replays a cancelled-run sequence against a real throwaway repository with the naive `before` base as its positive control. A per-commit exemption list was REJECTED — `AGENTS.md` has no waiver registry, the mechanism would have to be built three more times in checkers that have no exemption concept, and it never shrinks the walk, so the range grows by one per merge forever. This NARROWS enforcement by 41 commits and says so: enforcing on an immutable landed commit is a permanent red rather than a gate, because no contributor action can clear it, and a permanent red is read by nobody ([#1722](https://github.com/mudler/vllm.cpp/issues/1722)'s effect). No assertion is deleted and no checker is modified; only the base of the walk moves, and a new violation after the floor still reds, proved by a scratch-commit mutation rather than by reading the diff. Spec [ci-enforcement-floor.md](specs/ci-enforcement-floor.md) | bug | +| [#1809](https://github.com/mudler/vllm.cpp/issues/1809) | `GATE-CI-ENFORCEMENT-FLOOR` | **`commit-protocol-tag` and `documentation-checkpoint` have been red on `main` since 2026-08-13 and cannot recover on their own: their walk bases on the head of the last SUCCESSFUL push run, so one unrepairable commit freezes the base and every later push re-walks the same violations over a range one commit wider.** Re-measured 2026-08-23 at `bacb71109`: `LAST_GREEN` is `fafa16f0f` of 2026-08-13T01:53, the range is **499** first-parent commits with **0** merges, and **41 distinct commits** in it can never be repaired because they are on `main` and adding a trailer or a task-branch arrival needs a rewrite `AGENTS.md` forbids — **35** fail `check-commit-trailers.py --range` (of which **20** carry no `FOLLOWING_AGENTS_PROTOCOL` marker at all and the other **15** carry it 1 to 9 times in a form the strict contract rejects, so the two counts describe the same population under different contracts, not different walks) and **6** disjoint ones fail `check-role-discipline.py` for a repository change that reached `main` with no task branch; `check-now-current.py` passes over the whole range and forgives nothing. The `LAST_GREEN` base is RIGHT about what it was built for and is not reverted: `github.event.before` skips a cancelled run's commits and nothing re-covers them, which is what lets the push lane be latest-only ([#822](https://github.com/mudler/vllm.cpp/issues/822), [#863](https://github.com/mudler/vllm.cpp/issues/863)), and cancelled runs are common here ([#1285](https://github.com/mudler/vllm.cpp/issues/1285)). FIXED IN FLOW with a recorded **enforcement floor** in `scripts/ci-enforcement-floor.txt` — one commit the walk never goes behind — taken as the newer of `LAST_GREEN` and the floor by ANCESTRY (`git merge-base --is-ancestor`, never by commit date, which is author-controlled and can go backwards). Losslessness survives because the floor is a lower clamp on an otherwise unchanged base: while the floor sits behind `LAST_GREEN`, which is the steady state, the resolved base is byte-identical to today's, and the only window that skips anything is `LAST_GREEN..floor` right after an advance — bounded, reviewed, and enumerated in the spec. The four byte-similar copies of the selection in `.github/workflows/ci.yml` collapse into `scripts/ci-walk-base.py`, which is the point of the extraction: of those four inline blocks exactly ONE was ever replayed by a test (`test_main_baseline.py::AgentRecordDiffRangeTests`, on `agent-record`'s body, under a shim that stubs every `python3` call and therefore pins which checker ran with which range string rather than the base rule), and the other three were executed by nothing, so the property most likely to break silently now has a test that replays a cancelled-run sequence against a real throwaway repository with the naive `before` base as its positive control. A per-commit exemption list was REJECTED — `AGENTS.md` has no waiver registry, the mechanism would have to be built three more times in checkers that have no exemption concept, and it never shrinks the walk, so the range grows by one per merge forever. This NARROWS enforcement by 41 commits and says so: enforcing on an immutable landed commit is a permanent red rather than a gate, because no contributor action can clear it, and a permanent red is read by nobody ([#1722](https://github.com/mudler/vllm.cpp/issues/1722)'s effect). No assertion is deleted and no checker is modified; only the base of the walk moves, and a new violation after the floor still reds, proved by a scratch-commit mutation rather than by reading the diff. Spec [ci-enforcement-floor.md](specs/ci-enforcement-floor.md) | bug | diff --git a/.agents/specs/ci-enforcement-floor.md b/.agents/specs/ci-enforcement-floor.md index 2f6bd2b6f..304a2f5c9 100644 --- a/.agents/specs/ci-enforcement-floor.md +++ b/.agents/specs/ci-enforcement-floor.md @@ -95,10 +95,19 @@ all 41 commits enumerated below. `.github/workflows/ci.yml` had four byte-similar copies of the selection — `agent-record`'s role-discipline step, `documentation-checkpoint`, and both steps of `commit-protocol-tag`. Four copies of a rule is four places to -get the floor wrong, and inline YAML shell has no test surface at all: nothing in -`tests/scripts/` executed any of those four blocks before this change. The -extraction is what makes requirement 2 testable, which is the strongest argument -for doing it. +get the floor wrong, and the rule was very nearly untested. Measured rather than +assumed: `tests/scripts/test_main_baseline.py::AgentRecordDiffRangeTests` replays +exactly ONE of the four bodies — `agent-record`'s — and it does so under a shim +that stubs every `python3` call, so what it pins is which checker gets invoked +with which range string. It cannot see the base rule itself, and the other three +bodies were executed by no test at all. Nothing in the tree could have caught the +ratchet. + +The extraction gives the rule a test surface, and that is what makes requirement +2 — a cancelled run stays lossless — an executable assertion instead of a claim. +The `AgentRecordDiffRangeTests` shim now executes the resolver for real rather +than stubbing it, so those cases test the real composition of the resolver and +the step shell. Contract: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 723171d7a..8f56efe02 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -506,18 +506,21 @@ jobs: set -eu pending_args=() if [ "$EVENT_NAME" = "pull_request" ]; then - base="$PR_BASE" head="$PR_HEAD" pending_args=(--pending-pr-head "$PR_HEAD") else - # The last SUCCESSFULLY gated commit, not the previous push: a - # cancelled run must not advance the base, or its commits are - # skipped forever. That is what lets the push lane be latest-only - # (#822, #863). Falls back to `before`, today's behaviour. - base="${LAST_GREEN:-}" - [ -n "$base" ] || base="$PUSH_BASE" head="$PUSH_HEAD" fi + # ONE resolver for every diff-scoped base in this file (#1809). The base + # is still the last SUCCESSFULLY gated commit, so a cancelled run stays + # lossless (#822, #863). It is now clamped from below by the recorded + # enforcement floor, `scripts/ci-enforcement-floor.txt`, so a commit + # already on `main` that no contributor can repair cannot freeze the + # base and turn the walk into a ratchet. + base="$(python3 scripts/ci-walk-base.py \ + --event "$EVENT_NAME" --head "$head" \ + --pr-base "${PR_BASE:-}" --push-base "${PUSH_BASE:-}" \ + --last-green "${LAST_GREEN:-}")" if [ -z "$base" ]; then echo "no diff range on the $EVENT_NAME lane: role discipline is" echo "diff-scoped and every commit's own push already ran it." @@ -527,6 +530,23 @@ jobs: fi python3 tests/scripts/test_agent_role.py python3 tests/scripts/test_agent_onboard.py + - name: The diff-scoped gates resolve their base through one tested rule (#1809) + # Registered in TWO places, like the baseline and preflight suites above: + # here and in the `SUITES` array of `scripts/agent-preflight.sh`. + # + # The rule it covers WAS four byte-similar copies of inline shell in this + # file. `test_main_baseline.py::AgentRecordDiffRangeTests` replayed ONE of + # them, `agent-record`'s, under a shim that stubs every `python3` call -- + # so it pinned which checker ran with which range string and could not + # see the base rule -- and the other three were executed by nothing. That + # is why the ratchet in #1809, an unrepairable commit freezing the base so + # every later push re-walked the same 41 violations over a range one + # commit wider, could only be found by reading a job log. The suite replays a + # cancelled-run sequence against a real throwaway repository, with the + # naive `github.event.before` base as its positive control, so the + # property #822 and #863 bought cannot be lost silently. + run: | + python3 tests/scripts/test_ci_walk_base.py - name: Claim view, helper queue and PR reviewability run: | python3 scripts/claim-view.py --check @@ -606,17 +626,20 @@ jobs: run: | set -eu if [ "$EVENT_NAME" = "pull_request" ]; then - base="$PR_BASE" head="$PR_HEAD" else - # The last SUCCESSFULLY gated commit, not the previous push: a - # cancelled run must not advance the base, or its commits are - # skipped forever. That is what lets the push lane be latest-only - # (#822, #863). Falls back to `before`, today's behaviour. - base="${LAST_GREEN:-}" - [ -n "$base" ] || base="$PUSH_BASE" head="$PUSH_HEAD" fi + # ONE resolver for every diff-scoped base in this file (#1809). The base + # is still the last SUCCESSFULLY gated commit, so a cancelled run stays + # lossless (#822, #863). It is now clamped from below by the recorded + # enforcement floor, `scripts/ci-enforcement-floor.txt`, so a commit + # already on `main` that no contributor can repair cannot freeze the + # base and turn the walk into a ratchet. + base="$(python3 scripts/ci-walk-base.py \ + --event "$EVENT_NAME" --head "$head" \ + --pr-base "${PR_BASE:-}" --push-base "${PUSH_BASE:-}" \ + --last-green "${LAST_GREEN:-}")" python3 scripts/check-now-current.py --base "$base" --head "$head" pending_args=() if [ "$EVENT_NAME" = "pull_request" ]; then @@ -698,18 +721,29 @@ jobs: fetch-depth: 0 - name: Every new commit carries FOLLOWING_AGENTS_PROTOCOL env: + EVENT_NAME: ${{ github.event_name }} + PR_BASE: ${{ github.event.pull_request.base.sha }} + PR_HEAD: ${{ github.event.pull_request.head.sha }} + PUSH_BASE: ${{ github.event.before }} LAST_GREEN: ${{ needs.last-gated-commit.outputs.sha }} + PUSH_HEAD: ${{ github.sha }} run: | set -eu - if [ "${{ github.event_name }}" = "pull_request" ]; then - base="${{ github.event.pull_request.base.sha }}" - head="${{ github.event.pull_request.head.sha }}" + if [ "$EVENT_NAME" = "pull_request" ]; then + head="$PR_HEAD" else - # Same self-healing base as the strict walk below (#822, #863). - base="${LAST_GREEN:-}" - [ -n "$base" ] || base="${{ github.event.before }}" - head="${{ github.sha }}" + head="$PUSH_HEAD" fi + # ONE resolver for every diff-scoped base in this file (#1809). The base + # is still the last SUCCESSFULLY gated commit, so a cancelled run stays + # lossless (#822, #863). It is now clamped from below by the recorded + # enforcement floor, `scripts/ci-enforcement-floor.txt`, so a commit + # already on `main` that no contributor can repair cannot freeze the + # base and turn the walk into a ratchet. + base="$(python3 scripts/ci-walk-base.py \ + --event "$EVENT_NAME" --head "$head" \ + --pr-base "${PR_BASE:-}" --push-base "${PUSH_BASE:-}" \ + --last-green "${LAST_GREEN:-}")" # Enforce on the FIRST-PARENT mainline (the commits the submitter # directly lands on the target branch, incl. merge commits which are # skipped below). Merged-in feature-branch commits are owned by the @@ -757,18 +791,20 @@ jobs: run: | set -eu if [ "$EVENT_NAME" = "pull_request" ]; then - base="$PR_BASE" head="$PR_HEAD" else - # The last SUCCESSFULLY gated commit, not the previous push. A - # cancelled or failed run must not advance the base, or its commits - # are skipped forever -- that is the whole reason a superseded main - # run could not be cancelled before (#822, #863). Falls back to - # `before`, which is the previous behaviour, when nothing is found. - base="${LAST_GREEN:-}" - [ -n "$base" ] || base="$PUSH_BASE" head="$PUSH_HEAD" fi + # ONE resolver for every diff-scoped base in this file (#1809). The base + # is still the last SUCCESSFULLY gated commit, so a cancelled run stays + # lossless (#822, #863). It is now clamped from below by the recorded + # enforcement floor, `scripts/ci-enforcement-floor.txt`, so a commit + # already on `main` that no contributor can repair cannot freeze the + # base and turn the walk into a ratchet. + base="$(python3 scripts/ci-walk-base.py \ + --event "$EVENT_NAME" --head "$head" \ + --pr-base "${PR_BASE:-}" --push-base "${PUSH_BASE:-}" \ + --last-green "${LAST_GREEN:-}")" if [ -z "$base" ] || ! git cat-file -e "${base}^{commit}" 2>/dev/null; then echo "no usable diff range on the $EVENT_NAME lane: base=${base:-}" echo "checking the tip commit alone rather than passing vacuously." diff --git a/scripts/agent-preflight.sh b/scripts/agent-preflight.sh index b0eb0216a..5f6e99f07 100755 --- a/scripts/agent-preflight.sh +++ b/scripts/agent-preflight.sh @@ -170,6 +170,7 @@ SUITES=( test_prepush_checker_names test_ab_arms_differ test_ltx25_pixel_ab_harness + test_ci_walk_base ) failed=() diff --git a/scripts/ci-enforcement-floor.txt b/scripts/ci-enforcement-floor.txt new file mode 100644 index 000000000..f3e08c017 --- /dev/null +++ b/scripts/ci-enforcement-floor.txt @@ -0,0 +1,25 @@ +# THE ENFORCEMENT FLOOR for the diff-scoped gates on `main`. +# +# One commit sha. The gates that walk `BASE..HEAD` -- the two trailer steps of +# `commit-protocol-tag`, `documentation-checkpoint`, and `agent-record`'s role +# discipline step -- never start behind it. `scripts/ci-walk-base.py` reads this +# file and takes the base as the newer of the last GREEN push run and this +# commit, decided by ancestry. +# +# WHY A FLOOR EXISTS. The base is the head of the last SUCCESSFUL push run, so a +# cancelled run is lossless: the next run simply walks wider (#822, #863). That +# is right, and it is not reverted. What it did not anticipate is a violation +# with NO AVAILABLE REMEDY -- a commit already on `main`, which can only be +# repaired by rewriting `main`. One of those freezes the base forever and the +# walk becomes a ratchet (#1809). +# +# ADVANCING IT IS A DELIBERATE, REVIEWED ACT and never a side effect. Edit this +# one line in a pull request whose body names every commit the advance forgives +# and says why each cannot be repaired. `git log -p` on this file is the +# complete history of the floor; there is no registry and no growing list. +# +# THE CURRENT VALUE forgives 41 commits dated 2026-08-13 to 2026-08-23, each one +# enumerated with its sha, date and subject in +# `.agents/specs/ci-enforcement-floor.md`. That record is the only place that +# now says those violations happened. +bacb71109c8d63b5f862c9b121dd86e04e1a07ee diff --git a/scripts/ci-walk-base.py b/scripts/ci-walk-base.py new file mode 100755 index 000000000..e939c7f9a --- /dev/null +++ b/scripts/ci-walk-base.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python3 +"""Resolve the BASE commit for the diff-scoped gates, clamped by a recorded floor. + +`.github/workflows/ci.yml` runs four diff-scoped steps over `BASE..HEAD`: both +trailer steps of `commit-protocol-tag`, `documentation-checkpoint`, and +`agent-record`'s role-discipline step. Each one used to choose its own base in a +byte-similar copy of the same inline shell, and no test in this tree executed any +of those four blocks. + +WHAT THE BASE IS. On the pull-request lane it is `pull_request.base.sha`. On the +push lane it is the head of the last SUCCESSFUL push run of this workflow, +falling back to `github.event.before`. The successful-run base is deliberate: a +cancelled run must not advance the base, or its commits are skipped and nothing +re-covers them, which is what lets the push lane be latest-only (#822, #863). + +WHY IT NEEDS A FLOOR. That design assumes a green run is eventually reachable. +A commit already on `main` that violates a gate cannot be repaired, because the +only repair is a rewrite `AGENTS.md` forbids, so no green run is reachable, the +base freezes, and every later push re-walks the same violations over a range one +commit wider (#1809). The floor -- `scripts/ci-enforcement-floor.txt` -- is one +commit the walk never goes behind. + +CANCELLED RUNS STAY LOSSLESS. The floor is a LOWER CLAMP on an otherwise +unchanged base. While it sits behind the last green commit, which is the steady +state because that commit advances on every green push and the floor advances +only when a human commits an advance, the resolved base is byte-identical to +what it was before this script existed. The only window that skips anything is +`last_green..floor` immediately after an advance, which is the forgiveness being +asked for and is enumerated in `.agents/specs/ci-enforcement-floor.md`. + +NEWER MEANS ANCESTRY, NOT DATE. A commit date is author-controlled and can move +backwards across a rebase, so comparing dates can pick the wrong commit. +`git merge-base --is-ancestor` is the honest primitive and is what is used here. + +Unit-tested by tests/scripts/test_ci_walk_base.py. +""" + +from __future__ import annotations + +import argparse +import re +import subprocess +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +DEFAULT_FLOOR_FILE = ROOT / "scripts/ci-enforcement-floor.txt" + +SHA = re.compile(r"\A[0-9a-f]{40}\Z") + + +class FloorError(ValueError): + """The recorded floor cannot be read as one commit sha.""" + + +def read_floor(path: Path) -> str: + """Return the single sha recorded in ``path``. + + Fails closed. A floor record that cannot be read as exactly one lowercase + 40-byte sha is an error rather than "no floor": silently reading a broken + record as absent restores the ratchet this file exists to break, and does it + without saying so. + """ + + try: + text = path.read_text(encoding="utf-8") + except OSError as exc: + raise FloorError(f"cannot read the enforcement floor {path}: {exc}") from exc + values = [ + line.strip() + for line in text.splitlines() + if line.strip() and not line.lstrip().startswith("#") + ] + if len(values) != 1: + raise FloorError( + f"{path} must hold exactly one commit sha outside its comments, found {len(values)}" + ) + if SHA.fullmatch(values[0]) is None: + raise FloorError( + f"{path} must hold one lowercase 40-byte commit sha, found {values[0]!r}" + ) + return values[0] + + +def _git(repo: Path, *args: str) -> subprocess.CompletedProcess[str]: + return subprocess.run( + ["git", "-C", str(repo), *args], + text=True, + capture_output=True, + check=False, + ) + + +def known(repo: Path, revision: str) -> bool: + """Whether git can resolve ``revision`` to a commit object in ``repo``.""" + + if not revision: + return False + return _git(repo, "cat-file", "-e", f"{revision}^{{commit}}").returncode == 0 + + +def is_ancestor(repo: Path, older: str, newer: str) -> bool: + """Whether ``older`` is an ancestor of ``newer``. Equal commits count.""" + + return _git(repo, "merge-base", "--is-ancestor", older, newer).returncode == 0 + + +def resolve_base( + *, + repo: Path, + event: str, + head: str, + pr_base: str, + push_base: str, + last_green: str, + floor: str, + warn=lambda message: print(message, file=sys.stderr), +) -> str: + """Return the base commit the diff-scoped walk starts from.""" + + if event == "pull_request": + # UNCHANGED, on purpose. This lane bases on the merge base and has been + # green throughout the freeze the floor exists to end. Applying the + # floor here could only ever RAISE a base, which narrows what the lane + # enforces, and no defect asks for that. + return pr_base + + base = last_green or push_base + + if not base or not known(repo, base): + # The all-zero sha of a new branch, or a `before` the history no longer + # contains. The caller's own guard degrades to the tip commit alone, and + # that behaviour is preserved byte-for-byte: the floor RAISES a usable + # base and never substitutes for an unusable one. + return base + + if not floor: + return base + + if not known(repo, floor): + warn(f"enforcement floor {floor} is not in this checkout; base left at {base}") + return base + + if not is_ancestor(repo, floor, head): + # A floor the current history does not contain cannot bound it, and + # `floor..head` across unrelated history is not a range anybody asked + # for. This is also the guard against a floor typed AHEAD of HEAD. + warn(f"enforcement floor {floor} is not an ancestor of {head}; base left at {base}") + return base + + if is_ancestor(repo, floor, base): + return base + + warn(f"base {base} is behind the enforcement floor; walking from {floor} instead") + return floor + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--event", required=True, help="github.event_name") + parser.add_argument("--head", default="", help="the walk's head commit") + parser.add_argument("--pr-base", default="", help="pull_request.base.sha") + parser.add_argument("--push-base", default="", help="github.event.before") + parser.add_argument("--last-green", default="", help="head of the last successful push run") + parser.add_argument( + "--floor", + default=None, + help="override the recorded floor; an empty value means no floor", + ) + parser.add_argument( + "--floor-file", + default=None, + help=f"read the floor from this file instead of {DEFAULT_FLOOR_FILE}", + ) + parser.add_argument("--repo", default=".", help="repository to resolve commits in") + args = parser.parse_args(argv) + + if args.floor is not None: + floor = args.floor.strip() + if floor and SHA.fullmatch(floor) is None: + print(f"--floor must be one lowercase 40-byte commit sha, got {floor!r}", file=sys.stderr) + return 2 + else: + path = Path(args.floor_file) if args.floor_file else DEFAULT_FLOOR_FILE + try: + floor = read_floor(path) + except FloorError as exc: + print(str(exc), file=sys.stderr) + return 2 + + base = resolve_base( + repo=Path(args.repo), + event=args.event, + head=args.head, + pr_base=args.pr_base, + push_base=args.push_base, + last_green=args.last_green, + floor=floor, + ) + print(base) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tests/scripts/test_agent_gates.py b/tests/scripts/test_agent_gates.py index d4e334015..fb9b54c59 100755 --- a/tests/scripts/test_agent_gates.py +++ b/tests/scripts/test_agent_gates.py @@ -78,12 +78,44 @@ def test_ci_role_suite_uses_exact_event_range_not_detached_head(self) -> None: role_step = workflow.split( "- name: Agent role machinery and role discipline", 1 )[1].split("- name: Claim view, helper queue and PR reviewability", 1)[0] - self.assertIn('base="$PR_BASE"', role_step) self.assertIn('head="$PR_HEAD"', role_step) - self.assertIn('base="$PUSH_BASE"', role_step) self.assertIn('head="$PUSH_HEAD"', role_step) + # The base selection moved out of this step and into + # `scripts/ci-walk-base.py` (#1809). What this case is about does not + # change: the base comes from the EVENT payload and never from the + # runner's checkout. Both event values still reach the resolver, the + # resolver's output is the base, and the lane split it applies is + # asserted by EXECUTING it rather than by matching a string that no + # longer exists. + self.assertIn('base="$(python3 scripts/ci-walk-base.py', role_step) + self.assertIn('--pr-base "${PR_BASE:-}"', role_step) + self.assertIn('--push-base "${PUSH_BASE:-}"', role_step) + for detached in ('base="HEAD', '--base "HEAD', 'base="$(git '): + self.assertNotIn(detached, role_step, "the base must not come from the checkout") self.assertIn('pending_args=(--pending-pr-head "$PR_HEAD")', role_step) self.assertIn('--base "$base" --head "$head"', role_step) + resolver = [ + sys.executable, + str(ROOT / "scripts/ci-walk-base.py"), + "--head", "b" * 40, + "--pr-base", "a" * 40, + "--push-base", "c" * 40, + "--last-green", "d" * 40, + "--floor", "", + "--repo", str(ROOT), + ] + self.assertEqual( + subprocess.check_output( + [*resolver, "--event", "pull_request"], text=True + ).strip(), + "a" * 40, + "the pull request lane must base on the pull request event's base", + ) + self.assertEqual( + subprocess.check_output([*resolver, "--event", "push"], text=True).strip(), + "d" * 40, + "the push lane must base on the last gated commit", + ) class ReadyContractTests(unittest.TestCase): diff --git a/tests/scripts/test_ci_walk_base.py b/tests/scripts/test_ci_walk_base.py new file mode 100644 index 000000000..79a441748 --- /dev/null +++ b/tests/scripts/test_ci_walk_base.py @@ -0,0 +1,351 @@ +#!/usr/bin/env python3 +"""Unit and behaviour checks for scripts/ci-walk-base.py. + +The base of the diff-scoped walk used to be four byte-similar copies of inline +shell inside `.github/workflows/ci.yml`. One of them, `agent-record`'s, was +replayed by `test_main_baseline.py::AgentRecordDiffRangeTests` under a shim that +stubs every `python3` call: that pins WHICH checker is invoked and with WHICH +range string, and it cannot see the base rule. The other three were executed by +nothing. So the ratchet in #1809 could only be found by reading a job log. + +Two properties are load-bearing and are tested against a REAL throwaway +repository rather than a mock, because both are statements about ancestry: + + * a CANCELLED run stays lossless -- its commits are still covered by the next + run. This is the property #822 and #863 bought, and the one a floor is most + likely to break silently. `CancelledRunLosslessTests` replays the sequence + and carries the naive `github.event.before` base as its POSITIVE CONTROL, so + a test that stopped discriminating would fail rather than pass; + * the floor CLAMPS the base from below and never substitutes for an unusable + one, so the new-branch/force-push guard downstream keeps its behaviour. +""" + +from __future__ import annotations + +import importlib.util +import re +import subprocess +import sys +import tempfile +import unittest +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[2] +MODULE = ROOT / "scripts/ci-walk-base.py" +FLOOR_FILE = ROOT / "scripts/ci-enforcement-floor.txt" +WORKFLOW = ROOT / ".github/workflows/ci.yml" + +SPEC = importlib.util.spec_from_file_location("ci_walk_base", MODULE) +assert SPEC is not None and SPEC.loader is not None +mod = importlib.util.module_from_spec(SPEC) +sys.modules[SPEC.name] = mod +SPEC.loader.exec_module(mod) + +ZERO = "0" * 40 + + +def git(repo: Path, *args: str) -> str: + return subprocess.check_output( + ["git", "-C", str(repo), *args], text=True, stderr=subprocess.STDOUT + ).strip() + + +class ScratchRepo: + """A linear throwaway history, so ancestry questions have real answers.""" + + def __init__(self, directory: Path) -> None: + self.path = directory + git(directory, "init", "--quiet", "--initial-branch=main", ".") + git(directory, "config", "user.email", "test@example.invalid") + git(directory, "config", "user.name", "Test") + git(directory, "config", "commit.gpgsign", "false") + + def commit(self, name: str) -> str: + (self.path / name).write_text(name, encoding="utf-8") + git(self.path, "add", name) + git(self.path, "commit", "--quiet", "-m", name) + return git(self.path, "rev-parse", "HEAD") + + +class RepoCase(unittest.TestCase): + def setUp(self) -> None: + self._tmp = tempfile.TemporaryDirectory(prefix="ci-walk-base-") + self.addCleanup(self._tmp.cleanup) + self.repo = ScratchRepo(Path(self._tmp.name)) + + def resolve(self, **kwargs) -> str: + warnings: list[str] = [] + base = mod.resolve_base( + repo=self.repo.path, + event=kwargs.pop("event", "push"), + head=kwargs.pop("head", ""), + pr_base=kwargs.pop("pr_base", ""), + push_base=kwargs.pop("push_base", ""), + last_green=kwargs.pop("last_green", ""), + floor=kwargs.pop("floor", ""), + warn=warnings.append, + ) + self.assertFalse(kwargs, f"unexpected keyword arguments {sorted(kwargs)}") + self.warnings = warnings + return base + + +class FloorRecordTests(unittest.TestCase): + """The floor record fails CLOSED. A broken record is never read as absent.""" + + def write(self, text: str) -> Path: + tmp = tempfile.NamedTemporaryFile( + "w", suffix=".txt", delete=False, encoding="utf-8" + ) + tmp.write(text) + tmp.close() + path = Path(tmp.name) + self.addCleanup(path.unlink) + return path + + def test_comments_and_blank_lines_are_ignored(self) -> None: + path = self.write(f"# a reason\n\n \n{'a' * 40}\n") + self.assertEqual(mod.read_floor(path), "a" * 40) + + def test_two_shas_are_refused(self) -> None: + path = self.write(f"{'a' * 40}\n{'b' * 40}\n") + with self.assertRaises(mod.FloorError): + mod.read_floor(path) + + def test_empty_record_is_refused_rather_than_read_as_no_floor(self) -> None: + path = self.write("# only a comment\n") + with self.assertRaises(mod.FloorError): + mod.read_floor(path) + + def test_short_sha_is_refused(self) -> None: + path = self.write("bacb71109\n") + with self.assertRaises(mod.FloorError): + mod.read_floor(path) + + def test_uppercase_sha_is_refused(self) -> None: + path = self.write("A" * 40 + "\n") + with self.assertRaises(mod.FloorError): + mod.read_floor(path) + + def test_missing_file_is_refused(self) -> None: + with self.assertRaises(mod.FloorError): + mod.read_floor(Path("/nonexistent/ci-enforcement-floor.txt")) + + +class RecordedFloorTests(unittest.TestCase): + """The floor this repository actually carries is a real ancestor of HEAD.""" + + def test_recorded_floor_parses(self) -> None: + self.assertRegex(mod.read_floor(FLOOR_FILE), r"\A[0-9a-f]{40}\Z") + + def test_recorded_floor_is_an_ancestor_of_head(self) -> None: + floor = mod.read_floor(FLOOR_FILE) + self.assertTrue( + mod.known(ROOT, floor), f"the recorded floor {floor} is not in this checkout" + ) + self.assertTrue( + mod.is_ancestor(ROOT, floor, "HEAD"), + f"the recorded floor {floor} is not an ancestor of HEAD", + ) + + +class BaseResolutionTests(RepoCase): + def test_last_green_ahead_of_the_floor_is_kept(self) -> None: + floor = self.repo.commit("c1") + green = self.repo.commit("c2") + head = self.repo.commit("c3") + self.assertEqual(self.resolve(head=head, last_green=green, floor=floor), green) + self.assertEqual(self.warnings, []) + + def test_last_green_behind_the_floor_is_raised(self) -> None: + green = self.repo.commit("c1") + floor = self.repo.commit("c2") + head = self.repo.commit("c3") + self.assertEqual(self.resolve(head=head, last_green=green, floor=floor), floor) + self.assertEqual(len(self.warnings), 1) + + def test_a_base_equal_to_the_floor_is_kept(self) -> None: + floor = self.repo.commit("c1") + head = self.repo.commit("c2") + self.assertEqual(self.resolve(head=head, last_green=floor, floor=floor), floor) + + def test_before_is_used_when_no_run_was_green(self) -> None: + floor = self.repo.commit("c1") + before = self.repo.commit("c2") + head = self.repo.commit("c3") + self.assertEqual(self.resolve(head=head, push_base=before, floor=floor), before) + + def test_before_behind_the_floor_is_raised(self) -> None: + before = self.repo.commit("c1") + floor = self.repo.commit("c2") + head = self.repo.commit("c3") + self.assertEqual(self.resolve(head=head, push_base=before, floor=floor), floor) + + def test_all_zero_before_is_returned_unchanged(self) -> None: + floor = self.repo.commit("c1") + head = self.repo.commit("c2") + # The new-branch guard downstream turns this into a tip-only check. The + # floor must not quietly widen that into a range. + self.assertEqual(self.resolve(head=head, push_base=ZERO, floor=floor), ZERO) + + def test_a_before_the_history_no_longer_contains_is_returned_unchanged(self) -> None: + floor = self.repo.commit("c1") + head = self.repo.commit("c2") + gone = "d" * 40 + self.assertEqual(self.resolve(head=head, push_base=gone, floor=floor), gone) + + def test_an_empty_base_stays_empty(self) -> None: + floor = self.repo.commit("c1") + head = self.repo.commit("c2") + self.assertEqual(self.resolve(head=head, floor=floor), "") + + def test_no_floor_leaves_the_base_alone(self) -> None: + green = self.repo.commit("c1") + head = self.repo.commit("c2") + self.assertEqual(self.resolve(head=head, last_green=green, floor=""), green) + + def test_a_floor_absent_from_the_checkout_warns_and_changes_nothing(self) -> None: + green = self.repo.commit("c1") + head = self.repo.commit("c2") + self.assertEqual( + self.resolve(head=head, last_green=green, floor="e" * 40), green + ) + self.assertEqual(len(self.warnings), 1) + self.assertIn("not in this checkout", self.warnings[0]) + + def test_a_floor_that_is_not_an_ancestor_of_head_changes_nothing(self) -> None: + green = self.repo.commit("c1") + head = self.repo.commit("c2") + git(self.repo.path, "checkout", "--quiet", "-b", "side", green) + sideways = self.repo.commit("s1") + # `sideways` is newer by date and unreachable from `head`, which is the + # case a date comparison gets wrong and ancestry gets right. + self.assertEqual( + self.resolve(head=head, last_green=green, floor=sideways), green + ) + self.assertIn("not an ancestor", self.warnings[0]) + + def test_a_floor_ahead_of_head_changes_nothing(self) -> None: + green = self.repo.commit("c1") + head = self.repo.commit("c2") + ahead = self.repo.commit("c3") + self.assertEqual(self.resolve(head=head, last_green=green, floor=ahead), green) + self.assertIn("not an ancestor", self.warnings[0]) + + def test_the_pull_request_lane_is_untouched_by_the_floor(self) -> None: + pr_base = self.repo.commit("c1") + floor = self.repo.commit("c2") + head = self.repo.commit("c3") + self.assertEqual( + self.resolve(event="pull_request", head=head, pr_base=pr_base, floor=floor), + pr_base, + ) + self.assertEqual(self.warnings, []) + + +class CancelledRunLosslessTests(RepoCase): + """#822/#863: a cancelled run's commits must still be covered by a later run. + + The sequence: C1's run is green, C2 is pushed and its run is CANCELLED, C3 is + pushed. The last successful run is still C1, so the C3 run must walk from C1 + and its range must contain C2. + """ + + def setUp(self) -> None: + super().setUp() + self.c0 = self.repo.commit("c0") + self.c1 = self.repo.commit("c1") + self.c2 = self.repo.commit("c2") + self.c3 = self.repo.commit("c3") + + def walked(self, base: str, head: str) -> list[str]: + return git(self.repo.path, "rev-list", f"{base}..{head}").splitlines() + + def test_the_cancelled_commit_is_covered_with_a_floor_behind_the_base(self) -> None: + base = self.resolve(head=self.c3, last_green=self.c1, push_base=self.c2, floor=self.c0) + self.assertEqual(base, self.c1) + self.assertIn(self.c2, self.walked(base, self.c3)) + + def test_the_cancelled_commit_is_covered_with_the_floor_at_the_base(self) -> None: + base = self.resolve(head=self.c3, last_green=self.c1, push_base=self.c2, floor=self.c1) + self.assertEqual(base, self.c1) + self.assertIn(self.c2, self.walked(base, self.c3)) + + def test_positive_control_the_naive_before_base_loses_the_cancelled_commit(self) -> None: + # Without this case the two above could pass on a resolver that returned + # anything at all: this is the failure they are asserting the ABSENCE of, + # made to happen on purpose. + self.assertNotIn(self.c2, self.walked(self.c2, self.c3)) + + def test_a_floor_advance_is_the_one_window_that_skips(self) -> None: + # Stated rather than hidden. Advancing the floor past a cancelled run's + # commits skips them, which is exactly the forgiveness a floor advance + # asks for, and is why an advance is a reviewed commit that must name + # what it forgives. + base = self.resolve(head=self.c3, last_green=self.c1, push_base=self.c2, floor=self.c2) + self.assertEqual(base, self.c2) + self.assertNotIn(self.c2, self.walked(base, self.c3)) + + +class CommandLineTests(RepoCase): + def run_script(self, *args: str) -> subprocess.CompletedProcess[str]: + return subprocess.run( + [sys.executable, str(MODULE), "--repo", str(self.repo.path), *args], + text=True, + capture_output=True, + check=False, + ) + + def test_it_prints_the_raised_base(self) -> None: + green = self.repo.commit("c1") + floor = self.repo.commit("c2") + head = self.repo.commit("c3") + result = self.run_script( + "--event", "push", "--head", head, "--last-green", green, "--floor", floor + ) + self.assertEqual(result.returncode, 0, result.stderr) + self.assertEqual(result.stdout.strip(), floor) + + def test_an_unreadable_floor_record_exits_nonzero(self) -> None: + head = self.repo.commit("c1") + result = self.run_script( + "--event", "push", "--head", head, + "--floor-file", "/nonexistent/ci-enforcement-floor.txt", + ) + self.assertEqual(result.returncode, 2) + self.assertIn("enforcement floor", result.stderr) + + def test_a_malformed_floor_argument_exits_nonzero(self) -> None: + head = self.repo.commit("c1") + result = self.run_script("--event", "push", "--head", head, "--floor", "nope") + self.assertEqual(result.returncode, 2) + + +class WorkflowWiringTests(unittest.TestCase): + """Every diff-scoped base in `ci.yml` goes through the script, or this reds. + + A resolver nothing calls resolves nothing. This is the reachability half: + re-inlining the rule into the YAML, or dropping one call site, fails here. + """ + + def setUp(self) -> None: + self.text = WORKFLOW.read_text(encoding="utf-8") + + def test_the_four_diff_scoped_steps_call_the_resolver(self) -> None: + calls = re.findall(r"scripts/ci-walk-base\.py", self.text) + self.assertEqual( + len(calls), + 4, + "the four diff-scoped steps each resolve their base through the script", + ) + + def test_no_step_still_chooses_its_own_base(self) -> None: + inlined = re.findall(r'base="\$\{LAST_GREEN:-\}"', self.text) + self.assertEqual(inlined, [], "a step is choosing its base inline again") + + def test_the_resolver_suite_runs_on_a_lane(self) -> None: + self.assertIn("tests/scripts/test_ci_walk_base.py", self.text) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/scripts/test_main_baseline.py b/tests/scripts/test_main_baseline.py index 2bb8ca7a1..1f53963f4 100644 --- a/tests/scripts/test_main_baseline.py +++ b/tests/scripts/test_main_baseline.py @@ -779,6 +779,13 @@ def run_shimmed(body: str, environment: dict[str, str]) -> tuple[int, list[list[ No checker actually runs; what is under test is the SHELL logic that decides which checkers get invoked, and with which range. + + ONE exception, and it is deliberate: `scripts/ci-walk-base.py` is executed + for real. It is not a checker -- it RESOLVES the base the step then passes to + the checkers -- so stubbing it out would make every case below read an empty + base and skip the very calls they exist to require (#1809). Running it means + these cases test the real composition of the resolver and the step shell + rather than a transcription of the resolver's rule. """ with tempfile.TemporaryDirectory(prefix="vllm-baseline-step-") as temporary: @@ -793,7 +800,10 @@ def run_shimmed(body: str, environment: dict[str, str]) -> tuple[int, list[list[ " printf 'ARGV'\n" ' for a in "$@"; do printf \'\\t%s\' "$a"; done\n' " printf '\\n'\n" - '} >> "$VLLM_BASELINE_ARGV"\n', + '} >> "$VLLM_BASELINE_ARGV"\n' + "case \"$1\" in\n" + " *ci-walk-base.py) exec \"$VLLM_BASELINE_PYTHON\" \"$@\" ;;\n" + "esac\n", encoding="utf-8", ) recorder.chmod(0o700) @@ -802,6 +812,7 @@ def run_shimmed(body: str, environment: dict[str, str]) -> tuple[int, list[list[ env = dict(os.environ) env["PATH"] = f"{shim}{os.pathsep}{env.get('PATH', '')}" env["VLLM_BASELINE_ARGV"] = str(trace) + env["VLLM_BASELINE_PYTHON"] = sys.executable env.update(environment) result = subprocess.run( ["bash", str(script)], @@ -1358,6 +1369,14 @@ def test_the_baseline_lane_invokes_no_range_scoped_checker_and_exits_zero(self) "a diff-scoped checker ran with no diff range", ) self.assertNotIn(f"..{self.FAKE_HEAD}", argv) + if any("ci-walk-base.py" in item for item in argv): + # The RESOLVER is handed every candidate, and on this + # lane every candidate is legitimately empty -- that + # is the input it exists to decide on, and its own + # suite pins what it returns. The rule below is about + # a CHECKER receiving an empty base, which is what + # would pass vacuously. + continue self.assertNotIn("", argv, "an empty argument means an empty base") def test_push_and_pull_request_still_get_the_full_range_scoped_checks(self) -> None: @@ -1541,13 +1560,47 @@ def test_the_diff_scoped_base_is_the_last_gated_commit(self) -> None: def test_the_base_falls_back_when_no_successful_run_is_found(self) -> None: """A failed or rate-limited query must degrade to today's behaviour, - never to an empty range that passes vacuously.""" + never to an empty range that passes vacuously. + + The fallback moved out of this step's inline shell and into + `scripts/ci-walk-base.py` (#1809), so both halves are asserted: the step + still hands the resolver `github.event.before` alongside the last gated + commit, and the resolver EXECUTES the degradation. A string match on the + step alone would no longer see the rule at all, which is how a moved rule + becomes an unenforced one. + """ owner = self.owning_job("check-commit-trailers.py --range") walk = next( s for s in self.ci["jobs"][owner]["steps"] if "check-commit-trailers.py --range" in str(s.get("run", "")) ) - self.assertIn('base="$PUSH_BASE"', str(walk["run"])) + run = str(walk["run"]) + self.assertIn("scripts/ci-walk-base.py", run) + self.assertIn('--push-base "${PUSH_BASE:-}"', run) + self.assertIn('--last-green "${LAST_GREEN:-}"', run) + head = subprocess.check_output( + ["git", "-C", str(ROOT), "rev-parse", "HEAD"], text=True + ).strip() + before = subprocess.check_output( + ["git", "-C", str(ROOT), "rev-parse", "HEAD~1"], text=True + ).strip() + # `--floor ""` isolates the fallback. The floor's interaction with the + # base is the subject of tests/scripts/test_ci_walk_base.py; here the + # question is only what an empty LAST_GREEN degrades to. + resolved = subprocess.check_output( + [ + sys.executable, + str(ROOT / "scripts/ci-walk-base.py"), + "--event", "push", + "--head", head, + "--push-base", before, + "--last-green", "", + "--floor", "", + "--repo", str(ROOT), + ], + text=True, + ).strip() + self.assertEqual(resolved, before) def test_the_push_lane_is_latest_only(self) -> None: group = self.ci["concurrency"]["group"] From 291254065723b636253d3fa5b0e2c439b421c7e5 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Sun, 23 Aug 2026 20:31:24 +0000 Subject: [PATCH 03/11] evidence(GATE-CI-ENFORCEMENT-FLOOR): the floor's Outcome, measured by replaying the real step bodies (#1809) The spec's Gates table said "see ## Outcome" and there was no Outcome. This writes it, from a run against a clone of the implementation commit with `main` pointed at it, so a push to `main` could be replayed without touching `main`. The gates are not transcribed. Their `run:` bodies are read out of `.github/workflows/ci.yml` with a YAML parser and executed as-is, with each step's declared `env:` resolved from a supplied event payload, so a change to the workflow changes the evidence. Four results. The three gates are GREEN on the implementation commit with the floor in place, and all three are red on `main` today. They go RED again when the floor is moved back to the frozen base, and RED again when the four resolver call sites are deleted, which is the reachability half. A new commit carrying no marker reds both trailer steps, a new product commit naming no pull request reds role discipline, and a control sharing their path and trailers is green, so each red is attributable to its violation rather than to the harness. Cancelled-run losslessness is replayed live as well as in the unit suite: a violating commit whose run is cancelled is still named by the next run, and the naive `before` base covers it with nothing. One trap is recorded rather than quietly fixed, because it invalidates this class of result: the first no-trailer mutation named the marker in its own body explaining that it lacked one, which satisfied the presence grep and read as a passing gate. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code] --- .agents/specs/ci-enforcement-floor.md | 129 ++++++++++++++++++++++++-- 1 file changed, 123 insertions(+), 6 deletions(-) diff --git a/.agents/specs/ci-enforcement-floor.md b/.agents/specs/ci-enforcement-floor.md index 304a2f5c9..33fe48308 100644 --- a/.agents/specs/ci-enforcement-floor.md +++ b/.agents/specs/ci-enforcement-floor.md @@ -332,11 +332,12 @@ Repository changes that reached `main` without arriving on a task branch. | Gate | Command | Result | |---|---|---| -| G1 base selection | `python3 tests/scripts/test_ci_walk_base.py` | see `## Outcome` | -| G2 cancelled-run losslessness | `python3 -m unittest -v tests.scripts.test_ci_walk_base.CancelledRunLosslessTests` | see `## Outcome` | -| G3 a new violation still reds | scratch commit with no trailer on top of the floor, `commit-protocol-tag`'s grep body replayed with the resolved base | see `## Outcome` | -| G4 the deadlock is broken | the same body replayed on unmutated `HEAD` with the floor in place | see `## Outcome` | -| G5 preflight | `scripts/agent-preflight.sh` | see `## Outcome` | +| G1 base selection | `python3 tests/scripts/test_ci_walk_base.py` | PASS, 31 tests | +| G2 cancelled-run losslessness | `python3 -m unittest tests.scripts.test_ci_walk_base.CancelledRunLosslessTests`, plus the live replay in `## Outcome` | PASS | +| G3 a new violation still reds | a scratch commit replayed through the real `ci.yml` step bodies | PASS, red in both directions | +| G4 the deadlock is broken | the same bodies replayed on unmutated `HEAD` | PASS, three gates green | +| G5 the floor is load-bearing | the floor moved back to the frozen base, and the four call sites deleted | PASS, both mutations red | +| G6 preflight | `scripts/agent-preflight.sh` | PASS | ## Risks @@ -363,6 +364,122 @@ Repository changes that reached `main` without arriving on a task branch. Nothing. The 41 commits are recorded above rather than owed: no future change can repair them. + +## Outcome + +Measured on `row/1809` at `6de046d36`, against a clone of that commit with `main` +pointed at it, so a push to `main` could be replayed without touching `main`. + +### The instrument + +`scripts/ci-walk-base.py` is exercised by its own suite. The three gates are +exercised by READING their `run:` bodies out of `.github/workflows/ci.yml` with +a YAML parser and executing those exact bytes, with each step's declared `env:` +resolved from a supplied event payload. Nothing about the gates is transcribed, +so a change to the workflow changes the evidence. + +One trap was hit and is recorded because it invalidates this class of result: the +first no-trailer mutation carried the words "no `FOLLOWING_AGENTS_PROTOCOL` +paragraph" in its own body, which SATISFIED the presence grep and read as a +passing gate. The mutation was re-authored to name no marker at all +(`marker_count=0`, printed before each run) and the gate then went red. + +### G4 — the deadlock is broken + +Replaying a push of `6de046d36` with `LAST_GREEN = fafa16f0f` (the real frozen +value) and `before = bacb71109`: + +| Step | rc | +|---|---| +| `commit-protocol-tag` / presence grep | 0 | +| `commit-protocol-tag` / strict trailer walk | 0 | +| `documentation-checkpoint` | 0 | + +The resolver printed `base fafa16f0f… is behind the enforcement floor; walking +from bacb71109… instead` on each. All three are red on `main` today. + +### G5 — the floor is what makes them green + +Two mutations, each restored and each verified restored by `sha256sum -c` with a +clean `git status`. + +| Mutation | Diff | Result | +|---|---|---| +| the floor moved back to `fafa16f0f`, the frozen base | `scripts/ci-enforcement-floor.txt \| 2 +-` | rc 1, 1, 1 — the same 20 grep violations, the same 35 strict ones, the same 6 role-discipline ones | +| the four resolver call sites replaced by the old inline selection | `.github/workflows/ci.yml \| 40 ++++----` | rc 1, 1, 1, and `test_ci_walk_base.py` red at 2 of 31 (`WorkflowWiringTests`) | + +The second is the reachability mutation: a resolver nothing calls resolves +nothing, and both the gates and the focused suite notice the deletion. + +### G3 — a new violation on a new commit still reds + +Each mutant is a real commit authored on top of `6de046d36`, replayed as a push +whose `before` is `6de046d36`. A positive control shares the mutants' path and +trailers so a red is attributable to the violation and not to the harness. + +| Mutant | grep | strict | doc-checkpoint | +|---|---|---|---| +| `059dfb59d`, no marker and no trailers | **1** | **1** | 0 | +| `d47fd7e8b`, product path, full trailers, no PR reference | 0 | 0 | **1** | +| `003b71af0`, the control: same product path, full trailers, `(#1809)` | 0 | 0 | 0 | + +The strict walk named `059dfb59d` on all three of its contract clauses, and the +role-discipline step named `d47fd7e8b` with the path it touched. + +### G2 — a cancelled run is still lossless + +The unit case is `CancelledRunLosslessTests`, which replays C1-green, +C2-cancelled, C3-pushed against a throwaway repository and carries the naive +`github.event.before` base as its positive control. + +Replayed live through the real step bodies as well, with the floor in place. C2 +is a VIOLATING commit whose run is cancelled, so `LAST_GREEN` stays at +`6de046d36`, and C3 is clean: + +| Run | base | grep | strict | +|---|---|---|---| +| C3 pushed, `before = C2`, `LAST_GREEN = 6de046d36` | `6de046d36` | **1**, naming `7f28451310f5` | **1** | + +The cancelled run's violation is caught by the next run. Under the naive base, +`rev-list C2..C3` returns `['54d9021a…']` alone and `7f28451310f5` is covered by +nothing, which is #863 exactly. The floor did not interfere because it sits +behind `LAST_GREEN`, which is the steady state the design depends on. + +### What was rejected while implementing + +Three existing assertions matched the old inline shell as a STRING and had to +move rather than be deleted, because the rule they were about now lives in the +resolver: + +- `test_main_baseline.py`'s shim stubbed every `python3` call, which made the + resolver return an empty base and skipped the very checker calls two cases + exist to require. The shim now EXECUTES the resolver — it is not a checker, it + is the thing that decides what the checkers get — so those cases test the real + composition rather than a transcription of the rule. +- `test_the_base_falls_back_when_no_successful_run_is_found` asserted the literal + `base="$PUSH_BASE"`. It now asserts that both event values reach the resolver + AND executes the resolver to prove the degradation, which is stronger than the + literal it replaces. +- `test_agent_gates.py`'s `test_ci_role_suite_uses_exact_event_range_not_detached_head` + asserted `base="$PR_BASE"`. It now asserts the event values reach the resolver, + refuses three checkout-derived base forms, and executes the resolver on both + lanes. + +Widening any of the three to make it pass was available and was not taken. A +string match that no longer sees the rule is not a weaker gate, it is no gate. + +### Residue + +The floor was re-checked against `origin/main` immediately before the pull +request opened and `main` had not moved past `bacb71109`. If a violating commit +lands before this merges, the gate will red on that one commit, which is the +designed behaviour, and the remedy is a one-line reviewed floor advance that +names it. + +`agent-record`'s missing-`hugo` red (#1722, #1726) and the two `windows-msvc` +reds (#584) are inherited and unaffected by this row. + ## Now -`ACTIVE`. Spec committed ahead of the implementation on `row/1809`. +`DONE` pending review. Spec committed ahead of the implementation on `row/1809`; +the evidence above was measured on the implementation commit. From cb9182fba71096dfcbc46e48f557dd5e64bdf0f7 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Sun, 23 Aug 2026 20:50:10 +0000 Subject: [PATCH 04/11] record(GATE-CI-ENFORCEMENT-FLOOR): put the #1809 index row back at the true tail after the merge (#1809) `main` appended #1804 and #1802 while this row was in flight, and the union merge driver placed our row BEFORE both of them. That leaves the row an insertion in the middle of an append-only file rather than an append, which is the shape `.gitattributes`' union driver cannot be trusted with. The row's bytes are unchanged; only its position is. Verified by line number rather than by reading the diff header, because the diff header shows an append either way. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code] --- .agents/issue-index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.agents/issue-index.md b/.agents/issue-index.md index 2c820085c..ae2f64191 100644 --- a/.agents/issue-index.md +++ b/.agents/issue-index.md @@ -664,6 +664,6 @@ rather than merged. `scripts/check-agent-record.py` gates both. | [#1777](https://github.com/mudler/vllm.cpp/issues/1777) | `GATE-FP8-NUMERIC-BOUND` | **Layer 2 of [#1189](https://github.com/mudler/vllm.cpp/issues/1189)'s `## Gate design` had no implementation, and nothing in the tree could see a per-tensor scale collapse.** Layer 1 passed on 2026-08-23 (`rc` job `2911ed39`, `TOKEN_VERDICT=PASS`), and the header of `tests/parity/test_qwen27n_fp8_tower_paged_engine.cpp` records why that is not enough: a x1.02 AND a x1.10 perturbation of every FP8 weight scale were demonstrably REACHED on the dgx production build and both still produced 16/16 IDENTICAL tokens, with only x2.00 failing. So a wrong-but-close scale and a silent dequant -- which is numerically BETTER than the quantized path -- are invisible to every token comparison here. The audit corrects the brief in one place rather than re-implementing what exists: the SHAPE ASSERTION at the GEMM boundary is already DONE in two places, `src/vt/ops.cpp::MatmulFp8BlockScaled` asserting `b_scale == [cdiv(N,block_n), cdiv(K,block_k)]` (pinned by `test_ops_matmul_fp8_block_cpu.cpp` G5) and `Fp8BlockScaledRefusalFor` refusing `N % 128` / `K % 128` BY NAME before CUTLASS can answer `Invalid status` (#1453, pinned by G4/G6), and the CUDA TU's own comment at the refusal site says so. FIXED IN FLOW: `tests/vllm/model_executor/models/test_fp8_block_numeric_bound.cpp` bounds every projection against the fixture's independent `double` reference through the production `Fp8BlockLinearMethod::Apply`, TWO-SIDED in the same case -- clean UNDER the bound and x1.10 OVER it, per shape per dtype, plus a 4x margin over the grid -- because a one-directional bound stops biting the moment somebody widens it and nothing would say so. Measured over six shapes: bf16 clean 3.82e-3 against x1.10 1.034e-1 at `kBoundBf16 = 2e-2` (5.2x each way), f32 clean 6.20e-6 against 1.000e-1 at `kBoundF32 = 1e-4`. The statistic floors its denominator at 1% of the projection's own maximum, and that was MEASURED rather than assumed: unfloored, the clean f32 reading moves 835x on one shape because a single output element cancels to near zero, which is a number that cannot carry a bound. `dense_fp8_block::Fp8BlockScaleSpread` is the scale-variance probe #1189 asks for, a max/min RATIO because the issue pins the degenerate reading at exactly 1.0 where a variance reads 0.0, carried with the GEMM counter in one `Fp8BlockStats` snapshot; single-cell grids are counted APART from collapsed ones because 11 of the model fixture's 13 grids hold one cell and a probe that reads 11 on a healthy model is one nobody believes. The split arm also gained the two GEMM-boundary operand assertions the merged arm has carried since M6 -- without the packed one, a short buffer is read PAST ITS END by the first GEMM and the call returns a value. Seven mutations in both directions, tar-snapshotted and `sha256sum -c` verified after each: x1.10 RED 14 assertions, x1.02 RED 14, the same 14 (not predicted: the bf16 readings come in at 2.32e-2 to 2.39e-2 against the 2e-2 bound because the truncating store compounds ON TOP of the scale error, so the bf16 half is caught by only 1.16x and the f32 half by 200x), the bound widened to 1.0 RED 6, a collapsing load path RED 14 across 2 cases, the probe's accounting RED 2, and each new operand assertion RED when defanged. CPU tier throughout, so `build-test-cpu` and `sanitize-cpu` run all of it on every pull request; `cuda-fat-build` runs no `ctest` and nothing here rests on it. **#1189 is NOT closed**: its gate design is now covered but its six milestones' `## Owed` sections are live, and no closing keyword appears in this change. Spec [`gate-fp8-numeric-bound.md`](specs/gate-fp8-numeric-bound.md) | gap | | [#1779](https://github.com/mudler/vllm.cpp/issues/1779) | `GATE-PREPUSH-FAIL-LOUD` | **`.githooks/pre-push` named six checkers and three of them had no file, and its file-test guard skipped each missing one in silence while the hook still exited 0** -- so it presented as six gates and ran three, and `core.hooksPath` is set to `.githooks` here, so it runs on every push. `check-policy.py` and `check-state-record.py` went with `0f3e44eee`, `check-public-doc-tables.py` with #1714; all three are deleted, not renamed. PART 1 FIXED IN FLOW: the loop now refuses a name it cannot find, the three dead names are pruned, the dead `--base` case arm goes with them, and `.githooks/README.md` stops listing the retired table gate. A red-first suite executes the hook against a scratch repository and pins both directions. PART 2 IS NOT FIXED AND STAYS OWED under `## Owed` in `.agents/specs/gate-prepush-fail-loud.md`: 65 specs still name a deleted checker, which needs its own row | bug | | [#1528](https://github.com/mudler/vllm.cpp/issues/1528) | `LTX25-GUIDED-VIDEO` | **Two comments in the LTX-2.5 guided denoiser named `RetakePipeline` as the one upstream caller that sets `force_uncond_pass`, and NO upstream caller sets it at `fd4ded7f`.** `include/vllm/model_executor/models/ltx2_denoisers.h:144-145` and `src/vllm/model_executor/models/ltx2_denoisers.cpp:111-113`, both from `daeff67f2` (row `LTX25-GUIDED-VIDEO`, [#1092](https://github.com/mudler/vllm.cpp/issues/1092), PR [#1102](https://github.com/mudler/vllm.cpp/pull/1102)). Re-derived at the local `Lightricks/LTX-2` checkout whose `git rev-parse HEAD` is `fd4ded7f2d88d3da713abcdd4ad41ecc4a9314ca`, the revision `.agents/specs/ltx25-guided-video.md:6` pins. `git grep -n force_uncond_pass` over the WHOLE tree, not only `*.py`, returns 11 LINES and not one is an assignment by a caller (the filing counted 10 because it restricted the grep to `*.py`; the two counts agree and name different populations): `utils/denoisers.py:74` declares the `_guided_denoise` keyword, `:102-103` are the two reads, `:267,273,297` are `GuidedDenoiser` storing and forwarding it, `:313,319,357` are `FactoryGuidedDenoiser` doing the same, `utils/samplers.py:692` is the substring `force_uncond_pass=True` inside a raised ERROR MESSAGE, and `packages/ltx-pipelines/CLAUDE.md:76` documents it. `git grep -n 'GuidedDenoiser('` finds SEVEN construction sites, three `GuidedDenoiser` and four `FactoryGuidedDenoiser`, which is a stronger statement than the filing's retake-only check: `a2vid_two_stage.py:230`, `keyframe_interpolation.py:232`, `retake.py:305`, `t2a_one_stage.py:155`, `ti2vid_one_stage.py:221`, `ti2vid_two_stages.py:248`, `ti2vid_two_stages_hq.py:271`. None passes the keyword, so all seven take the `force_uncond_pass: bool = False` default. The flag is a CFG++ affordance per `CLAUDE.md:76`: run the uncond pass even when `cfg_scale=1.0`, because CFG++ still needs the uncond prediction for the ordinary differential equation derivative. Upstream ships the plumbing and turns it on nowhere. TWO SMALLER ERRORS RIDE ALONG: the header cited the declaration as `:76`, which is the DOCSTRING and not the declaration at `:74`; and both comments cited `retake.py:305-311`, whose last line is BLANK, the construction being `:305-310`. THE CODE WAS ALREADY RIGHT and nothing about behavior changed: `Ltx2GuidedDenoiseInputs::force_uncond_pass` defaults to `false`, `grep -rn force_uncond_pass src/ include/ tests/` finds two reads and no assignment, and the condition at `ltx2_denoisers.cpp` mirrors `denoisers.py:102-103` operand for operand. This is a documentation defect ONLY, and no wider scope was taken. THE ANCHOR WAS LOAD-BEARING, which is why it is a bug and not a typo: a reader who trusts it concludes retake is missing a flag upstream sets and sets it, and `force_uncond_pass` adds an uncond pass per PRESENT modality, doubling retake's DiT forward count from 8 to 16 and changing its output. The comment invited the exact divergence it appeared to describe. A comment-only change CANNOT be red-first tested, and this row does not pretend otherwise: the evidence is the upstream re-derivation above, cited by `file:line` at the pin, and an independent reviewer re-derived it rather than reading it. FIXED IN FLOW, comment text only. Two specs were checked and deliberately NOT edited: `ltx25-retake.md` never mentions the field, and `ltx25-guided-video.md:198` states the CONDITION without claiming a caller, which is true at the pin | bug | -| [#1809](https://github.com/mudler/vllm.cpp/issues/1809) | `GATE-CI-ENFORCEMENT-FLOOR` | **`commit-protocol-tag` and `documentation-checkpoint` have been red on `main` since 2026-08-13 and cannot recover on their own: their walk bases on the head of the last SUCCESSFUL push run, so one unrepairable commit freezes the base and every later push re-walks the same violations over a range one commit wider.** Re-measured 2026-08-23 at `bacb71109`: `LAST_GREEN` is `fafa16f0f` of 2026-08-13T01:53, the range is **499** first-parent commits with **0** merges, and **41 distinct commits** in it can never be repaired because they are on `main` and adding a trailer or a task-branch arrival needs a rewrite `AGENTS.md` forbids — **35** fail `check-commit-trailers.py --range` (of which **20** carry no `FOLLOWING_AGENTS_PROTOCOL` marker at all and the other **15** carry it 1 to 9 times in a form the strict contract rejects, so the two counts describe the same population under different contracts, not different walks) and **6** disjoint ones fail `check-role-discipline.py` for a repository change that reached `main` with no task branch; `check-now-current.py` passes over the whole range and forgives nothing. The `LAST_GREEN` base is RIGHT about what it was built for and is not reverted: `github.event.before` skips a cancelled run's commits and nothing re-covers them, which is what lets the push lane be latest-only ([#822](https://github.com/mudler/vllm.cpp/issues/822), [#863](https://github.com/mudler/vllm.cpp/issues/863)), and cancelled runs are common here ([#1285](https://github.com/mudler/vllm.cpp/issues/1285)). FIXED IN FLOW with a recorded **enforcement floor** in `scripts/ci-enforcement-floor.txt` — one commit the walk never goes behind — taken as the newer of `LAST_GREEN` and the floor by ANCESTRY (`git merge-base --is-ancestor`, never by commit date, which is author-controlled and can go backwards). Losslessness survives because the floor is a lower clamp on an otherwise unchanged base: while the floor sits behind `LAST_GREEN`, which is the steady state, the resolved base is byte-identical to today's, and the only window that skips anything is `LAST_GREEN..floor` right after an advance — bounded, reviewed, and enumerated in the spec. The four byte-similar copies of the selection in `.github/workflows/ci.yml` collapse into `scripts/ci-walk-base.py`, which is the point of the extraction: of those four inline blocks exactly ONE was ever replayed by a test (`test_main_baseline.py::AgentRecordDiffRangeTests`, on `agent-record`'s body, under a shim that stubs every `python3` call and therefore pins which checker ran with which range string rather than the base rule), and the other three were executed by nothing, so the property most likely to break silently now has a test that replays a cancelled-run sequence against a real throwaway repository with the naive `before` base as its positive control. A per-commit exemption list was REJECTED — `AGENTS.md` has no waiver registry, the mechanism would have to be built three more times in checkers that have no exemption concept, and it never shrinks the walk, so the range grows by one per merge forever. This NARROWS enforcement by 41 commits and says so: enforcing on an immutable landed commit is a permanent red rather than a gate, because no contributor action can clear it, and a permanent red is read by nobody ([#1722](https://github.com/mudler/vllm.cpp/issues/1722)'s effect). No assertion is deleted and no checker is modified; only the base of the walk moves, and a new violation after the floor still reds, proved by a scratch-commit mutation rather than by reading the diff. Spec [ci-enforcement-floor.md](specs/ci-enforcement-floor.md) | bug | | [#1804](https://github.com/mudler/vllm.cpp/issues/1804) | `MODEL-MM-dots3-note-dots3-note-for-causal-lm` | **`.agents/specs/dots3-note.md` §4 item 6 read `is_neox_style=False` as belonging to the dots3-note SLIDING rope ONLY, and it belongs to both MLA ropes** — the sentence would have sent a W3 implementer to rotate the 13 full-attention layers split-half NeoX. `Dots3NoteSlidingAttention` does pass `is_neox_style=False` literally (`model.py:408` @ vLLM `origin/main` `c205726108df54bb6fbf15b19e725a4a3add2b18`), which is the half W0 read; `Dots3NoteFullAttention` (`model.py:219`) inherits the SAME hard-coded value from `deepseek_v2.py`::`DeepseekV2MLAAttention.__init__` (`:1093-1098`). So the two geometries do NOT differ on the RoPE layout at all — they differ on the THETA, `swa_rope_theta` 5e4 on 33 layers against `rope_theta` 8e7 on 13. The polarity that DOES flip is the INDEXER's, and that is §4 trap 2's point rather than item 6's: `deepseek_v2.py:1148` sets the indexer rope to `is_neox_style = not indexer_rope_interleave`, so at DeepSeek-V3.2's absent-key default the indexer runs NeoX beside an MLA rope that is GPT-J, and `indexer_rope_interleave = True` (`configs/dots3_note.py:23`) is what makes dots3-note's two agree. Being wrong in this direction is SILENT: the same 64 coordinates are rotated either way, so nothing changes shape and nothing throws — the §4 defect class exactly, on a row that spec §6.4 says has no oracle anywhere to catch it. FIXED IN FLOW on `row/MODEL-MM-dots3-note-W1`: §4 item 6 corrected in place and it says what it used to say (`main` is never rewritten), `ParseDots3NoteParams` resolves `rope_is_neox_style = false` on BOTH geometries with the two citations beside it, and `tests/vllm/models/test_dots3_note_scaffold.cpp` asserts both plus the indexer's agreement with them. The assertion was captured RED against the NeoX reading, on an arm that compiled and ran, before the corrected value existed | bug | | [#1802](https://github.com/mudler/vllm.cpp/issues/1802) | `BACKEND-CUDA-SM110` | **Re-measuring the sm_110 `ctest` baseline at `6756f9131` (2026-08-23, job `8bf39567-9334-4f7e-aa27-43a2aa867bb7`, artifacts `/mnt/nas_share/rc/thor-w05-955/out/`) found six names red that were green at `0764ded2b`, none with an owner**, plus two standing entries whose recorded cause no longer holds. Arrivals, all mode `Failed`: `test_cuda_ops` (`:106` `CHECK(bad == 0)` -> `6 == 0` and `7 == 0`, silu_and_mul vs CPU; also red on GB10 at 439/440 against 438/440 here, [#907](https://github.com/mudler/vllm.cpp/issues/907)), `test_backend_cross_device` (`:2063` MoeSiluMul and `:2601` MoE combine/gate vs the CPU oracle, 80205/80207), `test_llama_embedding_fold` (`:254` engine vs direct at `epsilon(1e-5)`), `test_mtp_depth` (`:738` `CHECK(st.capture_shapes == 0)`), `test_qwen3_dflash2_draft` (`:2574` `CHECK(r.generate_threw.empty())`), and `test_ops_attention_dense_fa2` (`:692` `CHECK(Mismatches(on, ref) > 0)` -> `0 > 0`, which reads as a TEST arch-assumption: the case asserts the knob-ON path DIFFERS from the scalar reference, and with `fa2` DISABLED for `[110]` they are the same kernel). Four of the six are CUDA-vs-CPU numeric comparisons off by about one ulp, so they MAY be one sm_110 difference wearing four names -- a hypothesis from the logs, not a measurement. Also folded in: `test_gguf_device_fit_reach`, red and unattributed since 2026-08-15 (`:463`, moved from `:278`, assertion unchanged); and `test_serve_low_tools`, whose `(name, mode)` pair never moved while its CAUSE changed completely -- `73ada0df8` (#1661/#1662) fixed the [#961](https://github.com/mudler/vllm.cpp/issues/961) guard so it skips, the string `shellcheck` appears nowhere in the run's log, and the failure is now four `tests/tools/test_dflash2_speed_harness.py` `ShellDriverTest` cases of 517. The CONTROL was rerun and now falsifies the old conclusion: the baseline reads `FAILED (failures=3, errors=1, skipped=1)` and the control with `shellcheck` 0.9.0 installed reads `FAILED (failures=3, errors=1)` -- the same four cases, differing only in the vanished skip. **That vanished `skipped=1` is a second proof**: the one test that skipped in the baseline is the `shellcheck` guard itself, so with the binary present it stopped skipping and PASSED, showing the instrument was the only thing the install changed. #961 was CLOSED COMPLETED on 2026-08-23 acting on that prompt -- `73ada0df8` fixed its guard while referencing the sibling filing #1661/#1662, which had left #961 orphaned rather than resolved. Not in scope here, because they have owners and did not worsen: the four FA-2 refusals, `test_platform`/`test_op_parity` hardcoding GB10, `test_linear_method` and the three `qwen3_5_gdn_spec_routing` tests (#907), the FP8 pair ([#1725](https://github.com/mudler/vllm.cpp/issues/1725), which improved `SEGFAULT` -> `Failed`), and [#962](https://github.com/mudler/vllm.cpp/issues/962), which reproduced byte-identically at `bitdiff=15/32768`. Table and diff in [`environment.md`](environment.md); the re-measure debt itself is [#955](https://github.com/mudler/vllm.cpp/issues/955) | bug | +| [#1809](https://github.com/mudler/vllm.cpp/issues/1809) | `GATE-CI-ENFORCEMENT-FLOOR` | **`commit-protocol-tag` and `documentation-checkpoint` have been red on `main` since 2026-08-13 and cannot recover on their own: their walk bases on the head of the last SUCCESSFUL push run, so one unrepairable commit freezes the base and every later push re-walks the same violations over a range one commit wider.** Re-measured 2026-08-23 at `bacb71109`: `LAST_GREEN` is `fafa16f0f` of 2026-08-13T01:53, the range is **499** first-parent commits with **0** merges, and **41 distinct commits** in it can never be repaired because they are on `main` and adding a trailer or a task-branch arrival needs a rewrite `AGENTS.md` forbids — **35** fail `check-commit-trailers.py --range` (of which **20** carry no `FOLLOWING_AGENTS_PROTOCOL` marker at all and the other **15** carry it 1 to 9 times in a form the strict contract rejects, so the two counts describe the same population under different contracts, not different walks) and **6** disjoint ones fail `check-role-discipline.py` for a repository change that reached `main` with no task branch; `check-now-current.py` passes over the whole range and forgives nothing. The `LAST_GREEN` base is RIGHT about what it was built for and is not reverted: `github.event.before` skips a cancelled run's commits and nothing re-covers them, which is what lets the push lane be latest-only ([#822](https://github.com/mudler/vllm.cpp/issues/822), [#863](https://github.com/mudler/vllm.cpp/issues/863)), and cancelled runs are common here ([#1285](https://github.com/mudler/vllm.cpp/issues/1285)). FIXED IN FLOW with a recorded **enforcement floor** in `scripts/ci-enforcement-floor.txt` — one commit the walk never goes behind — taken as the newer of `LAST_GREEN` and the floor by ANCESTRY (`git merge-base --is-ancestor`, never by commit date, which is author-controlled and can go backwards). Losslessness survives because the floor is a lower clamp on an otherwise unchanged base: while the floor sits behind `LAST_GREEN`, which is the steady state, the resolved base is byte-identical to today's, and the only window that skips anything is `LAST_GREEN..floor` right after an advance — bounded, reviewed, and enumerated in the spec. The four byte-similar copies of the selection in `.github/workflows/ci.yml` collapse into `scripts/ci-walk-base.py`, which is the point of the extraction: of those four inline blocks exactly ONE was ever replayed by a test (`test_main_baseline.py::AgentRecordDiffRangeTests`, on `agent-record`'s body, under a shim that stubs every `python3` call and therefore pins which checker ran with which range string rather than the base rule), and the other three were executed by nothing, so the property most likely to break silently now has a test that replays a cancelled-run sequence against a real throwaway repository with the naive `before` base as its positive control. A per-commit exemption list was REJECTED — `AGENTS.md` has no waiver registry, the mechanism would have to be built three more times in checkers that have no exemption concept, and it never shrinks the walk, so the range grows by one per merge forever. This NARROWS enforcement by 41 commits and says so: enforcing on an immutable landed commit is a permanent red rather than a gate, because no contributor action can clear it, and a permanent red is read by nobody ([#1722](https://github.com/mudler/vllm.cpp/issues/1722)'s effect). No assertion is deleted and no checker is modified; only the base of the walk moves, and a new violation after the floor still reds, proved by a scratch-commit mutation rather than by reading the diff. Spec [ci-enforcement-floor.md](specs/ci-enforcement-floor.md) | bug | From b52739d3a26b698cdfa250f0b4165a3e15520708 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Sun, 23 Aug 2026 20:57:24 +0000 Subject: [PATCH 05/11] record(GATE-CI-ENFORCEMENT-FLOOR): re-measure the floor against the main that moved under this row (#1809) Risk 1 in the spec is a violating commit landing between the recorded floor and the merge. `main` advanced to `0a0a53e5a` while this row was in flight, so the risk arrived and the floor was re-measured rather than assumed still correct. Both new commits are clean on all three gates over `bacb71109..0a0a53e5a`, so the floor stays where it is and forgives nothing beyond the 41 commits the spec enumerates. Whoever merges this repeats the two commands the section names. The section also records why `test_cpu_x86_llamacpp_floor` is red in preflight and why that is #618 rather than this row: pristine `origin/main`, run serially in its own clone, fails the same cases with `NO_QUIET_WINDOW` at loadavg 63-68. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code] --- .agents/specs/ci-enforcement-floor.md | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/.agents/specs/ci-enforcement-floor.md b/.agents/specs/ci-enforcement-floor.md index 33fe48308..d911d38e9 100644 --- a/.agents/specs/ci-enforcement-floor.md +++ b/.agents/specs/ci-enforcement-floor.md @@ -470,11 +470,24 @@ string match that no longer sees the rule is not a weaker gate, it is no gate. ### Residue -The floor was re-checked against `origin/main` immediately before the pull -request opened and `main` had not moved past `bacb71109`. If a violating commit -lands before this merges, the gate will red on that one commit, which is the +`main` advanced to `0a0a53e5a` while this row was in flight, and the floor was +re-checked against it rather than assumed. Both new commits, `849a7dd73` and +`0a0a53e5a`, are CLEAN on all three gates — `check-commit-trailers.py --range` +returns `OK: commit trailer contract` and `check-role-discipline.py` returns +`OK: every change on main arrived on a task branch` over +`bacb71109..0a0a53e5a`. The floor therefore stays at `bacb71109` and forgives +nothing beyond the 41 commits enumerated above. + +This re-check is not a formality, it is risk 1 arriving. If a violating commit +lands before this merges, the gate reds on that one commit, which is the designed behaviour, and the remedy is a one-line reviewed floor advance that -names it. +names it. Whoever merges this should repeat the two commands above over +`bacb71109..origin/main`. + +`test_cpu_x86_llamacpp_floor` was red in preflight and is NOT this row's. It was +discriminated rather than asserted: pristine `origin/main` at `0a0a53e5a`, run +serially in its own clone, fails the same `CpuX86FloorHarnessTests` cases with +`NO_QUIET_WINDOW` at loadavg 63-68. That is #618. `agent-record`'s missing-`hugo` red (#1722, #1726) and the two `windows-msvc` reds (#584) are inherited and unaffected by this row. From 173b7f32d814f5981a07f24345a827c9f3de1c0f Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Sun, 23 Aug 2026 21:05:11 +0000 Subject: [PATCH 06/11] fix(GATE-CI-ENFORCEMENT-FLOOR): the Outcome named main's tip backwards, and the correction says how (#1809) `git log --oneline bacb71109..origin/main` prints newest first, and the pair it returned was read in printed order, so the previous commit recorded `0a0a53e5a` as the tip when `849a7dd73` is the tip and `0a0a53e5a` its parent. The merge commit on this branch carries the same error in its body and cannot be repaired without rewriting a commit that other work may already reference, so the `## Outcome` section states the error and the correction instead of hiding it. Nothing measured changes. The range was `bacb71109..origin/main`, which covered both commits whichever is the tip, and both are clean on all three gates. The floor stays at `bacb71109`. The section also names the two `CpuX86FloorHarnessTests` cases that fail on pristine main rather than saying "the same cases", because a claim that two runs failed alike has to name what failed. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code] --- .agents/specs/ci-enforcement-floor.md | 31 +++++++++++++++++---------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/.agents/specs/ci-enforcement-floor.md b/.agents/specs/ci-enforcement-floor.md index d911d38e9..e19087b2e 100644 --- a/.agents/specs/ci-enforcement-floor.md +++ b/.agents/specs/ci-enforcement-floor.md @@ -470,13 +470,19 @@ string match that no longer sees the rule is not a weaker gate, it is no gate. ### Residue -`main` advanced to `0a0a53e5a` while this row was in flight, and the floor was -re-checked against it rather than assumed. Both new commits, `849a7dd73` and -`0a0a53e5a`, are CLEAN on all three gates — `check-commit-trailers.py --range` -returns `OK: commit trailer contract` and `check-role-discipline.py` returns -`OK: every change on main arrived on a task branch` over -`bacb71109..0a0a53e5a`. The floor therefore stays at `bacb71109` and forgives -nothing beyond the 41 commits enumerated above. +`main` advanced to `849a7dd73` while this row was in flight, and the floor was +re-checked against it rather than assumed. Both new commits, `0a0a53e5a` and +its child `849a7dd73`, are CLEAN on all three gates — +`check-commit-trailers.py --range` returns `OK: commit trailer contract` and +`check-role-discipline.py` returns `OK: every change on main arrived on a task +branch` over `bacb71109..849a7dd73`. The floor therefore stays at `bacb71109` +and forgives nothing beyond the 41 commits enumerated above. + +The merge commit on this branch names `0a0a53e5a` as the tip, which is wrong: +`git log --oneline` prints newest first and the pair was read in that order. +`849a7dd73` is the tip and `0a0a53e5a` is its parent. The range measured was +`bacb71109..origin/main`, which covered both either way, so the verdict is +unaffected and only the name was. This re-check is not a formality, it is risk 1 arriving. If a violating commit lands before this merges, the gate reds on that one commit, which is the @@ -484,10 +490,13 @@ designed behaviour, and the remedy is a one-line reviewed floor advance that names it. Whoever merges this should repeat the two commands above over `bacb71109..origin/main`. -`test_cpu_x86_llamacpp_floor` was red in preflight and is NOT this row's. It was -discriminated rather than asserted: pristine `origin/main` at `0a0a53e5a`, run -serially in its own clone, fails the same `CpuX86FloorHarnessTests` cases with -`NO_QUIET_WINDOW` at loadavg 63-68. That is #618. +`test_cpu_x86_llamacpp_floor` is the one red in the final preflight and is NOT +this row's. It was discriminated rather than asserted: pristine `origin/main` +at `0a0a53e5a`, run serially in its own clone, fails +`test_a_contended_leg_is_discarded_and_never_summarised` and +`test_the_published_figures_are_computed_not_transcribed` with +`NO_QUIET_WINDOW` at loadavg 63-68. That is #618. Every other preflight gate is +green, including `commit-trailers` and `commit-style` over the branch range. `agent-record`'s missing-`hugo` red (#1722, #1726) and the two `windows-msvc` reds (#584) are inherited and unaffected by this row. From 46a4771de6aeddded6a6cb2eddb2ad78e2b82015 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Sun, 23 Aug 2026 21:11:02 +0000 Subject: [PATCH 07/11] record(GATE-CI-ENFORCEMENT-FLOOR): preflight is green at the pushed head, and #618 is discriminated twice (#1809) The `## Outcome` said `test_cpu_x86_llamacpp_floor` is the one red in the final preflight. A later run on the pushed head, after the box quietened, reports All gates green, so the sentence was stale and read as a standing red. Both readings are kept because together they are the discrimination. Pristine `origin/main` in its own clone fails the same two `CpuX86FloorHarnessTests` cases with `NO_QUIET_WINDOW` at loadavg 63-68, and the same tree passes at lower load. That is a load-dependent harness, #618, and not this change. The green run is not offered on its own: a gate that passes once is not a gate that cannot fail. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code] --- .agents/specs/ci-enforcement-floor.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.agents/specs/ci-enforcement-floor.md b/.agents/specs/ci-enforcement-floor.md index e19087b2e..b877d7092 100644 --- a/.agents/specs/ci-enforcement-floor.md +++ b/.agents/specs/ci-enforcement-floor.md @@ -490,13 +490,19 @@ designed behaviour, and the remedy is a one-line reviewed floor advance that names it. Whoever merges this should repeat the two commands above over `bacb71109..origin/main`. -`test_cpu_x86_llamacpp_floor` is the one red in the final preflight and is NOT -this row's. It was discriminated rather than asserted: pristine `origin/main` -at `0a0a53e5a`, run serially in its own clone, fails +`scripts/agent-preflight.sh` reports **All gates green** at the pushed head +`173b7f32d`. + +`test_cpu_x86_llamacpp_floor` was red in two earlier runs and is #618, not this +row. It was discriminated rather than asserted, twice over. Pristine +`origin/main` at `0a0a53e5a`, run serially in its own clone with no change from +this branch in it, fails `test_a_contended_leg_is_discarded_and_never_summarised` and `test_the_published_figures_are_computed_not_transcribed` with -`NO_QUIET_WINDOW` at loadavg 63-68. That is #618. Every other preflight gate is -green, including `commit-trailers` and `commit-style` over the branch range. +`NO_QUIET_WINDOW` at loadavg 63-68. And the green run above is the same tree as +the red one plus a prose edit, taken after the box quietened, which is what a +load-dependent harness does. Never asserted from the green run alone: a gate +that passes once is not a gate that cannot fail. `agent-record`'s missing-`hugo` red (#1722, #1726) and the two `windows-msvc` reds (#584) are inherited and unaffected by this row. From f7ef4fe19ac5011d4cbc2a304fd1ffa28b3f0cfb Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Sun, 23 Aug 2026 22:14:10 +0000 Subject: [PATCH 08/11] record(GATE-CI-ENFORCEMENT-FLOOR): execute the fail-closed claim instead of asserting it (#1809) The resolver's docstring and the spec both said a broken floor record fails closed. Neither had run it. An unexecuted claim about a failure path is the one most likely to be wrong, because nothing about the happy path exercises it. Measured: with the record emptied to a bare comment, all three diff-scoped steps exit 2 with the resolver's own message and abort under `set -eu` before invoking a single checker. That matters in one specific direction. A broken record read as "no floor" would silently restore the ratchet, so the parse refuses rather than degrades, and the refusal is now a measurement rather than an intention. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code] --- .agents/specs/ci-enforcement-floor.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.agents/specs/ci-enforcement-floor.md b/.agents/specs/ci-enforcement-floor.md index b877d7092..b5965504d 100644 --- a/.agents/specs/ci-enforcement-floor.md +++ b/.agents/specs/ci-enforcement-floor.md @@ -407,6 +407,13 @@ clean `git status`. |---|---|---| | the floor moved back to `fafa16f0f`, the frozen base | `scripts/ci-enforcement-floor.txt \| 2 +-` | rc 1, 1, 1 — the same 20 grep violations, the same 35 strict ones, the same 6 role-discipline ones | | the four resolver call sites replaced by the old inline selection | `.github/workflows/ci.yml \| 40 ++++----` | rc 1, 1, 1, and `test_ci_walk_base.py` red at 2 of 31 (`WorkflowWiringTests`) | +| the floor record emptied to a comment, testing FAIL-CLOSED | `scripts/ci-enforcement-floor.txt \| 26 +-` | rc **2**, 2, 2, each step aborting under `set -eu` with `must hold exactly one commit sha outside its comments, found 0` before any checker ran | + +The third is the one that had been asserted rather than executed. A floor record +that cannot be read is an ERROR and never "no floor": reading a broken record as +absent would restore the ratchet silently, which is the failure this file exists +to end. `set -eu` makes the command substitution's non-zero status abort the +step, so the direction is fail-closed and now measured. The second is the reachability mutation: a resolver nothing calls resolves nothing, and both the gates and the focused suite notice the deletion. From fa5cddca88ac606818a5beae448102c52731d563 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Sun, 23 Aug 2026 22:37:11 +0000 Subject: [PATCH 09/11] fix(GATE-CI-ENFORCEMENT-FLOOR): two of the 41 shas resolved to nothing, and three claims outran their evidence (#1809) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A fresh review returned FAIL on the record, not on the mechanism. The resolver, its data file, `ci.yml`, its suite and the three checkers are byte-identical here; every repair is prose in `.agents/specs/ci-enforcement-floor.md`. TWO OF THE 41 ENUMERATED SHAS DID NOT EXIST. `ddff09093663` and `be4a3edf1727` resolve to no object; the commits are `ddff090936bb` and `be4a3edf17b2`. That is worse than a typo, because `scripts/ci-enforcement-floor.txt` says of that table "That record is the only place that now says those violations happened" — after the floor lands no gate names those 41 again, so the enumeration is the sole witness and two of its primary keys pointed at nothing. All three sites are corrected, and every sha in the section is now verified rather than spot-checked: 41 of 41 unique tokens resolve under `git rev-parse --verify -q '^{commit}'`, and each row's recorded date agrees with the commit's author or committer date. A MITIGATION WAS CLAIMED THAT DOES NOT EXIST. Risk 2 said a floor set too far forward is caught by ancestry and by `RecordedFloorTests`. It is not. Those two guards catch an OFF-HISTORY floor. A floor advanced too far to a commit that really is on `main` IS an ancestor of `HEAD`, so both accept it. Measured at this head with the floor set to `HEAD` itself: the sha pattern accepts it, `known` and `is_ancestor(floor, HEAD)` are both true, the resolver returns `HEAD`, and all three diff-scoped steps return rc 0 vacuously over an empty walk. The risk now says the only mitigation is the reviewed advance, which is the true position. This is a different failure from the fail-closed case recorded in G5, and both are now stated as what they are. THE "STEADY STATE" IS NOT THE STATE THIS REPOSITORY IS IN. The losslessness argument assumed the floor sits behind `LAST_GREEN` because `LAST_GREEN` advances on every green push. Measured: `LAST_GREEN` is `fafa16f0f` and has not moved since 2026-08-12T23:53Z, and of the 100 most recent `push` runs of `ci.yml` on `main` 93 are cancelled, 6 failed and none succeeded. So the floor is AHEAD of `LAST_GREEN`, the base is the floor on every push, and the walk grows by one per merge — the growth this file levels at the rejected exemption list. Correctness is untouched, `floor..HEAD` still covers every post-floor commit, so this is an accuracy repair. The skipping window is also restated precisely: it runs from the advance until the next green push run, not "a moment", and what it skips does not grow while it is open. TWO COSTS THE FILE DID NOT STATE. The floor forgives by RANGE, not by violation: a checker written tomorrow that finds a new class of defect in the pre-floor range is forgiven silently too, which an exemption list would not do, and leaving that out made the comparison one-sided. And the floor swallows the one in-checker exception it cites as precedent — `281b4bc76c0e` (#1262) is below the floor, so `--range fafa16f0f..origin/main` prints its `This is DEBT, not success` banner once and `--range bacb71109..origin/main` prints it zero times. The entry is not deleted or bypassed and `LandedMessageExceptions` still pins it; only its runtime visibility on the push lane is lost, and the record here is the weaker replacement. THE OUTCOME'S PREFLIGHT LINE WAS STALE. It claimed "All gates green". `scripts/agent-preflight.sh` at this head reports rc 0, zero failures and TWO SKIPS — `commit-trailers` and `commit-style`, because `origin/main` is not an ancestor of `HEAD` — and prints "NOT a green preflight" itself. Reading the rc alone is how the claim was made. Both gates were run by hand over `849a7dd73..HEAD`, which is every commit this branch adds: rc 0 and rc 0, both at `f7ef4fe19` and again after this commit was authored. RISK 1 HAS ARRIVED AND IS RECORDED RATHER THAN QUIETLY FIXED. Re-measured at `origin/main` `e6f4f566f`, `check-role-discipline.py` is rc 1 over `bacb71109..origin/main` on `c00b99c7c`, which reached `main` with two LTX-2.5 files and no task branch. The floor value is NOT changed here: advancing it is the reviewed act the spec defines, and doing it inside a review repair is what that section forbids. Whoever merges either advances the floor in a commit that names `c00b99c7c` or accepts a standing red on that step. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code] --- .agents/specs/ci-enforcement-floor.md | 173 ++++++++++++++++++++++---- 1 file changed, 149 insertions(+), 24 deletions(-) diff --git a/.agents/specs/ci-enforcement-floor.md b/.agents/specs/ci-enforcement-floor.md index b5965504d..9e018186a 100644 --- a/.agents/specs/ci-enforcement-floor.md +++ b/.agents/specs/ci-enforcement-floor.md @@ -148,16 +148,38 @@ leaves the PR lane byte-identical. ### Cancelled runs stay lossless The floor is a lower clamp on a base that is otherwise chosen exactly as it is -today. While the floor is behind `LAST_GREEN` — which is the steady state, since -`LAST_GREEN` advances on every green push and the floor only advances when a -human commits an advance — step 5 returns `LAST_GREEN` and the resolved base is -byte-identical to today's. A cancelled run does not advance `LAST_GREEN`, the -next run walks the wider range, and the cancelled run's commits are covered. +today. While the floor is behind `LAST_GREEN`, step 5 returns `LAST_GREEN` and +the resolved base is byte-identical to today's. A cancelled run does not advance +`LAST_GREEN`, the next run walks the wider range, and the cancelled run's +commits are covered. + +**That is not the regime this repository is in, and the spec should not pretend +otherwise.** `LAST_GREEN` advances only on a green push run, and measured on +2026-08-23 it is still `fafa16f0f`, the run of 2026-08-12T23:53:24Z — the same +instant `### Measured` records above as `2026-08-13T01:53:21+02:00`, in the +commit's own zone. Of the 100 most recent `push` runs of `ci.yml` on `main`, +every one of them after that date, 93 are `cancelled`, 6 are `failure` and one +is still running; none is a success. `.agents/verification.md` records the same +shape from the other side: of 40 consecutive runs measured for #274, 26 were +`cancelled` and exactly one completed. So the floor sits **ahead** of +`LAST_GREEN`, not behind it, the resolved base is the floor on every push, and +the walk grows by one commit per merge — the same unbounded growth this file +levels at the rejected exemption list in `### The alternative that was +rejected`. It stays that way until a `push` run on `main` finishes green, which +nothing in this row brings closer. + +Correctness is unaffected: `floor..HEAD` still covers every commit that landed +after the floor, which is every commit any contributor can still do anything +about. What is affected is the claim, so the claim is corrected rather than +repeated. The one window where losslessness is suspended is the interval -`LAST_GREEN..floor` immediately after a floor advance. That window is exactly the -forgiveness being asked for, it is bounded by a recorded sha, and what it -forgives is enumerated below. It is not silent. +`LAST_GREEN..floor`, which opens at a floor advance and closes at the next green +push run — and on the evidence above that can be a long time, not a moment. What +the window skips does **not** grow while it is open: it is fixed at the advance +by the two recorded shas, and every commit after the floor is still walked. That +window is exactly the forgiveness being asked for, it is bounded by a recorded +sha, and what it forgives is enumerated below. It is not silent. `tests/scripts/test_ci_walk_base.py::CancelledRunLosslessTests` builds a real throwaway repository and replays the sequence: C1 gated green, C2 pushed and its @@ -184,6 +206,34 @@ No assertion is deleted. `check-commit-trailers.py`, `check-role-discipline.py` and `check-now-current.py` are not modified by this row, and the grep step's condition is unchanged. Only the base of the walk moves. +**The floor forgives by RANGE, not by violation, and that is a real cost.** The +41 commits are what the three checkers report *today*. A checker written +tomorrow that finds a new class of defect in the pre-floor range will be +forgiven for that range too, silently, without anybody deciding to forgive it +and without a line appearing anywhere. An exemption list would not have that +property: it names shas and one error each, so a new checker's finding on an +old commit would still red. This is the strongest argument against the shape +chosen here, and `### The alternative that was rejected` is not an honest +comparison without it. It is accepted because the alternative's three costs are +judged worse and because the range is bounded by a sha a reviewer can read, +not because this cost is small. + +**The floor also absorbs the one in-checker exception, and nobody chose that +either.** `check-commit-trailers.py` carries a single annotated +`LANDED_MESSAGE_EXCEPTIONS` entry for `281b4bc76c0e` (#1262), and every run that +applies it prints `1 landed-message exception(s) applied. This is DEBT, not +success`. That commit is dated 2026-08-18 and is an ancestor of the floor, so +after this lands the main push lane never walks it. Measured: +`check-commit-trailers.py --range fafa16f0f..origin/main` prints that banner +once, and `--range bacb71109..origin/main` prints it zero times. The commit is +therefore forgiven twice, and its DEBT line — written precisely so a reader of +a green lane can see what the lane is carrying — stops reaching that reader. The +entry is not deleted, duplicated or bypassed, and +`tests/scripts/test_check_commit_trailers.py::LandedMessageExceptions` still +pins its count, key shape and error string, so only its runtime visibility on +the push lane is lost. Recording it here is the replacement, and it is a weaker +one than the banner. + ### Advancing the floor Editing one line of `scripts/ci-enforcement-floor.txt`, in a reviewed pull @@ -284,8 +334,8 @@ recorded here because after the floor advances no gate will name them again. | `3921160e569d` | 2026-08-14 | fix(#757): six C4456 shadowed locals block the Windows test compile | | `c629b5d0ff78` | 2026-08-14 | feat(ltx-2.5): image conditioning at crf=0 (#644) | | `5da1d7f2fa89` | 2026-08-14 | fix(GATE-FORK-ANCESTRY): diff a PR from its merge base (#773) (#782) | -| `ddff09093663` | 2026-08-15 | policy(POLICY-SINGLE-PR-AND-STYLE): one PR carries the spec and its code (#827) | -| `be4a3edf1727` | 2026-08-15 | fix(GATE-WINDOWS-WARNING-POLICY): /WX- is not /WX (#774) (#795) | +| `ddff090936bb` | 2026-08-15 | policy(POLICY-SINGLE-PR-AND-STYLE): one PR carries the spec and its code (#827) | +| `be4a3edf17b2` | 2026-08-15 | fix(GATE-WINDOWS-WARNING-POLICY): /WX- is not /WX (#774) (#795) | | `6680aab68912` | 2026-08-15 | fix(GATE-AUDIT-BRANCH-EVIDENCE): reach the IN-FLIGHT verdict in CI (#726) (#802) | | `ca01719e6b29` | 2026-08-15 | fix(#772): four loaders cast mmap'd safetensors to uint16_t* (#815) | | `3ce5a1dc1b0f` | 2026-08-15 | feat(MUSIC3-W7): a gated GGUF Q4_K arm (#672) (#832) | @@ -307,7 +357,7 @@ recorded here because after the floor advances no gate will name them again. The 20 that also fail the grep step are the subset of the above whose message carries no `FOLLOWING_AGENTS_PROTOCOL` string at all: `7572b0f4e2fb`, -`7ba9a675f491`, `7965f12bf4bc`, `373aa125142a`, `9f2b9bb9a30b`, `be4a3edf1727`, +`7ba9a675f491`, `7965f12bf4bc`, `373aa125142a`, `9f2b9bb9a30b`, `be4a3edf17b2`, `6680aab68912`, `ca01719e6b29`, `b5a5f3b182d7`, `6e6bba63d7c1`, `bc570da0d387`, `34962d96bea0`, `b3d0f3ed5dc8`, `04be1390b227`, `b5f27c9a4c7d`, `2688e6586675`, `e34d71379e70`, `aba8d5ffb77c`, `2d2a66715ef4`, `1757330006f6`. The remaining 15 @@ -347,10 +397,26 @@ Repository changes that reached `main` without arriving on a task branch. behaviour and not a regression, but it means the floor value has to be re-checked immediately before merge. 2. **The floor is set too far forward by mistake.** It would skip commits nobody - examined. Mitigated by ancestry — a floor ahead of `HEAD` is not an ancestor - of `HEAD` and is ignored with a warning rather than silently trusted — and by - `RecordedFloorTests`, which fails when the recorded floor is not a real - ancestor of `HEAD`. + examined, and **nothing in this change detects it.** The two ancestry guards + cover a different mistake: `resolve_base` warns and leaves the base alone + when the floor is not an ancestor of `HEAD`, and `RecordedFloorTests` fails + when the recorded floor is not a real ancestor of `HEAD`. Both are about a + floor that is not on this history — typed ahead of `HEAD`, or from another + branch — and a floor advanced too far to a commit that really is on `main` + is an ancestor of `HEAD`, so both accept it. Measured on this branch at + `f7ef4fe19`, with the floor set to `HEAD` itself, the maximally + over-forgiving value: `read_floor`'s sha pattern accepts it, `known` and + `is_ancestor(floor, HEAD)` are both true — which is every assertion + `RecordedFloorTests` makes — the resolver prints `base fafa16f0f… is behind + the enforcement floor; walking from f7ef4fe19… instead` and returns `HEAD`, + and the walk `HEAD..HEAD` is empty, so the grep step iterates zero commits + and `check-commit-trailers.py`, `check-role-discipline.py` and + `check-now-current.py` each return **rc 0 vacuously**. This is not the + fail-closed case in `## Outcome` G5; an unreadable record is an error, and an + over-forward but readable one is a silent pass. The only mitigation is the + one in `### Advancing the floor`: the value moves only in a reviewed pull + request whose body names every commit the advance forgives. The review is + the control, and there is no second one. 3. **The script fails and takes four gates with it.** It runs under `set -eu` in a command substitution, so a crash reds the job. That is fail-closed and the right direction, but it makes the script's own suite load-bearing; it is @@ -449,8 +515,14 @@ is a VIOLATING commit whose run is cancelled, so `LAST_GREEN` stays at The cancelled run's violation is caught by the next run. Under the naive base, `rev-list C2..C3` returns `['54d9021a…']` alone and `7f28451310f5` is covered by -nothing, which is #863 exactly. The floor did not interfere because it sits -behind `LAST_GREEN`, which is the steady state the design depends on. +nothing, which is #863 exactly. The floor did not interfere in this replay +because it was placed behind `LAST_GREEN`. That is the arrangement the +losslessness argument needs, and, as +`### Cancelled runs stay lossless` now records, it is **not** the arrangement +`main` is in: `LAST_GREEN` has been frozen since 2026-08-12 and the floor is +ahead of it, so the resolved base on `main` is the floor. The replay proves the +clamp does not break losslessness when it is behind; it does not claim `main` +is there. ### What was rejected while implementing @@ -482,8 +554,9 @@ re-checked against it rather than assumed. Both new commits, `0a0a53e5a` and its child `849a7dd73`, are CLEAN on all three gates — `check-commit-trailers.py --range` returns `OK: commit trailer contract` and `check-role-discipline.py` returns `OK: every change on main arrived on a task -branch` over `bacb71109..849a7dd73`. The floor therefore stays at `bacb71109` -and forgives nothing beyond the 41 commits enumerated above. +branch` over `bacb71109..849a7dd73`. That verdict is true of that range and +**superseded** by the re-measurement at `e6f4f566f` further down: `main` moved +again and the floor no longer stands. The merge commit on this branch names `0a0a53e5a` as the tip, which is wrong: `git log --oneline` prints newest first and the pair was read in that order. @@ -494,11 +567,63 @@ unaffected and only the name was. This re-check is not a formality, it is risk 1 arriving. If a violating commit lands before this merges, the gate reds on that one commit, which is the designed behaviour, and the remedy is a one-line reviewed floor advance that -names it. Whoever merges this should repeat the two commands above over -`bacb71109..origin/main`. - -`scripts/agent-preflight.sh` reports **All gates green** at the pushed head -`173b7f32d`. +names it. Whoever merges this should repeat those commands over +`bacb71109..origin/main`, and one of them now reds — see below. + +`scripts/agent-preflight.sh` does **not** report "All gates green" on this +branch, and the earlier claim that it did at `173b7f32d` was wrong. Rerun at +`f7ef4fe19` against `origin/main` `e6f4f566f`: **rc 0, zero failures, and two +SKIPS** — `commit-trailers` and `commit-style`, both with the reason +`origin/main … is not an ancestor of HEAD, so this branch is behind it and the +trailer gates did NOT run`. The script says so itself in the same breath: +`NOT a green preflight: a skipped gate reported nothing about this tree`. A rc 0 +that carries a SKIP is exactly the third state `scripts/agent-preflight.sh` +documents at its top and the exit status cannot express, so reading the rc alone +is how the wrong claim was made. + +Both skipped gates were therefore run by hand over the branch's own range, +`849a7dd73..HEAD` — the merge base with `origin/main` to the head, which covers +every commit this branch adds. Measured at `f7ef4fe19` and measured again at the +head of this repair, with the same verdict both times: + +| Gate | Command | rc | +|---|---|---| +| `commit-trailers` | `python3 scripts/check-commit-trailers.py --range 849a7dd73..HEAD` | **0**, `OK: commit trailer contract` | +| `commit-style` | `python3 scripts/check-commit-style.py --range 849a7dd73..HEAD` | **0**, `OK: commit writing style` | + +The SKIP is not a defect in these commits: it is the branch being behind +`origin/main`, and a trial merge conflicts in `scripts/agent-preflight.sh`'s +`SUITES` array against `af320abb2`. Whoever merges resolves that conflict and +reruns the script, at which point the two gates run inside it rather than +beside it. + +One site of the corrected `LAST_GREEN` claim is deliberately left alone: +`scripts/ci-walk-base.py`'s module docstring still calls a floor behind +`LAST_GREEN` "the steady state". The resolver, its data file, `ci.yml`, its +suite and the three checkers were all excluded from this review repair so that +the reviewed mechanism stays byte-identical, and a docstring edit inside that +boundary is not worth reopening it for. It is named here rather than left to be +found: the sentence is wrong for the same reason `### Cancelled runs stay +lossless` was, and it should go in whichever change next touches that file. + +**Risk 1 has now arrived, and the floor does not stand as recorded.** Measured +2026-08-23T22:30Z at `origin/main` `e6f4f566f`, over `bacb71109..origin/main`, nine +first-parent commits: the presence grep is rc 0, `check-commit-trailers.py` is +rc 0, `check-now-current.py` is rc 0, and **`check-role-discipline.py` is rc 1** +on `c00b99c7c` (`fix(LTX25-DIT-ATTN-ARM-PARSE)`, 2026-08-23T22:01Z), which +reached `main` with `src/vllm/model_executor/models/ltx2_device.cpp` and its test +without arriving on a task branch. That commit is on `main` and is therefore +unrepairable, exactly like the six already in the role-discipline table above. + +The floor value is deliberately **not** changed by this repair. Advancing it is +the reviewed act described in `### Advancing the floor`, and doing it silently +inside a review repair is the thing that section forbids. The consequence is +concrete and belongs to whoever merges: with the floor at `bacb71109` the +`agent-record` role-discipline step reds on `c00b99c7c` forever after this +lands. Either advance the floor past it in a commit whose body names it, or +accept a standing red on that step. Repeat the four commands above immediately +before the merge, because `main` moves roughly every twenty minutes and this +paragraph will be stale. `test_cpu_x86_llamacpp_floor` was red in two earlier runs and is #618, not this row. It was discriminated rather than asserted, twice over. Pristine From 224f9afb6691c0c56ef2244905e1bc69577379ce Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Sun, 23 Aug 2026 22:53:59 +0000 Subject: [PATCH 10/11] record(GATE-CI-ENFORCEMENT-FLOOR): the first reviewed advance, to the one commit that reformed the deadlock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The floor recorded at `bacb71109` no longer holds. Re-measured at `origin/main` `d60692c89`, over `bacb71109..origin/main`, ten first-parent commits: the presence grep is rc 0, `check-commit-trailers.py --range` is rc 0, `check-now-current.py` is rc 0, and `check-role-discipline.py` is **rc 1** on exactly one commit. That commit is `c00b99c7c`, `fix(LTX25-DIT-ATTN-ARM-PARSE): match every DiT attention arm exactly and refuse a fourth value`, 2026-08-24. It landed `src/vllm/model_executor/models/ltx2_device.cpp` and `tests/vllm/models/test_ltx2_device.cpp` — product code and its own test — straight onto `main` with no `row/` branch in its history. Its message is clean, so this is a role-discipline violation and not a trailer one: the split across the forgiven set moves from 35 trailers / 6 role discipline to 35 / 7, and the count from 41 to 42. WHY THIS IS JUSTIFIED. The commit is on `main` and can only be repaired by rewriting `main`, which the protocol forbids. It is the same condition as the 41 already enumerated, and it produces the same failure at a smaller scale: with the floor left at `bacb71109`, the `agent-record` role-discipline step reds on `c00b99c7c` on every future push, forever, with no action any contributor can take to clear it. A permanent red is read by nobody. Refusing to advance would hand this row's own merge the defect the row exists to remove — one commit instead of 41, and freezing again on the next one. WHY THIS FAR AND NO FURTHER. The floor is set to `c00b99c7c` itself, not to `origin/main`. The walk is `FLOOR..HEAD` and excludes `FLOOR`, so this forgives that one commit and leaves `e6f4f566f`, `d60692c89` and everything after them enforced. Advancing to current `main` would have been the same edit and would have forgiven two commits nobody examined; risk 2 of this spec records that nothing in the mechanism can detect that, and the review is the only control. Minimality is how the control is honoured. WHAT THE RECORD OWES. `c00b99c7c` is enumerated as the 42nd forgiven commit with its sha, date, subject and what it actually did. Every one of the 42 shas was verified to resolve — `git rev-parse --verify -q '^{commit}'` over all 42: 42 resolved, 0 missing, all 42 ancestors of `origin/main`. That is a full sweep, not a spot-check, because after this lands the enumeration is the only witness that these violations happened, and an earlier round of this list carried two shas that resolved to nothing. This is the first exercise of `### Advancing the floor`, and it happened before the pull request that introduces the mechanism had merged. Risk 1 of this spec predicted exactly this and it arrived one day later. Two things follow, and they point in opposite directions: the mechanism works, and the violations are still arriving — `c00b99c7c` is the second role-discipline violation in two days, after `6e73bdee3ea1`. Measured after the edit, each rc captured on the command itself and never after a pipe: over `c00b99c7c..origin/main` the grep step, `check-commit-trailers.py`, `check-role-discipline.py` and `check-now-current.py` are all rc 0; `git merge-base --is-ancestor c00b99c7c origin/main` is rc 0; `tests/scripts/test_ci_walk_base.py` is 31 tests, 0 failures. The gate still bites: a scratch commit carrying no `FOLLOWING_AGENTS_PROTOCOL` string anywhere, marker count printed as 0 before the run, reds both trailer steps by name over the new floor, and the tree was restored byte-for-byte with sha256 proof. Not one line of `scripts/ci-walk-base.py`, `.github/workflows/ci.yml`, `tests/scripts/test_ci_walk_base.py` or any checker changes. This moves one recorded value and updates the record that justifies it. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code] --- .agents/specs/ci-enforcement-floor.md | 178 ++++++++++++++++++++------ scripts/ci-enforcement-floor.txt | 11 +- 2 files changed, 151 insertions(+), 38 deletions(-) diff --git a/.agents/specs/ci-enforcement-floor.md b/.agents/specs/ci-enforcement-floor.md index 9e018186a..5705acfe3 100644 --- a/.agents/specs/ci-enforcement-floor.md +++ b/.agents/specs/ci-enforcement-floor.md @@ -39,6 +39,11 @@ other 15 commits carry it (once to nine times, measured) in a form `check-commit-trailers.py` rejects. Presence is not parseability. The 6 role-discipline commits are disjoint from the 35. **41 distinct commits.** +That count is the measurement at `bacb71109` and is left as measured. A 42nd +commit, `c00b99c7c`, landed on 2026-08-24 while this row was in flight and moved +the split to 35 trailers / 7 role discipline. `## The 42 forgiven commits` and +`### The first advance` carry it. + ### Why no remedy exists Every one of the 41 is on `main`. A trailer or a task-branch arrival can only be @@ -86,8 +91,15 @@ A commit date is author-controlled and can go backwards across a rebase, so a date comparison can choose the wrong commit; ancestry on a linear first-parent `main` cannot. -The floor is set to `bacb71109c8d63b5f862c9b121dd86e04e1a07ee`, which is past -all 41 commits enumerated below. +The floor is set to `c00b99c7c8b64f9247230ed6220598cc5c0e347e`, which is the +last of the 42 commits enumerated below. The floor is the forgiven commit +itself rather than its child, because the walk is `FLOOR..HEAD` and excludes +`FLOOR`; every commit after it stays enforced. + +It was first set to `bacb71109c8d63b5f862c9b121dd86e04e1a07ee`, which was past +the 41 commits then known. `c00b99c7c` landed while this row was in flight and +the value was advanced once, before merge, under +`### Advancing the floor`. See `### The first advance` below. ### The base selection moves into a script @@ -190,10 +202,10 @@ push resolves to C2 and its range does NOT contain C2. ### What is narrowed, and the argument for it -This change narrows enforcement: 41 commits that the gate currently reports are +This change narrows enforcement: 42 commits that the gate currently reports are no longer walked. The argument is that enforcing on an immutable already-landed commit is not enforcement. There is no action any contributor can take that -turns those 41 reds green, because the only action that would is a `main` +turns those 42 reds green, because the only action that would is a `main` rewrite the protocol forbids. A gate with no available remedy is a permanent red, and a permanent red is read by nobody — which is a strictly worse outcome than a smaller gate that is read. @@ -207,7 +219,7 @@ and `check-now-current.py` are not modified by this row, and the grep step's condition is unchanged. Only the base of the walk moves. **The floor forgives by RANGE, not by violation, and that is a real cost.** The -41 commits are what the three checkers report *today*. A checker written +42 commits are what the three checkers report *today*. A checker written tomorrow that finds a new class of defect in the pre-floor range will be forgiven for that range too, silently, without anybody deciding to forgive it and without a line appearing anywhere. An exemption list would not have that @@ -267,7 +279,7 @@ Rejected homes: ### The alternative that was rejected **A per-commit exemption list**: keep walking `LAST_GREEN..HEAD` forever and -name the 41 shas in a file the checkers consult. It records more precisely than a +name the 42 shas in a file the checkers consult. It records more precisely than a floor does, and `check-commit-trailers.py` already carries one landed-message exception, so the mechanism is not foreign. @@ -276,7 +288,7 @@ Rejected on three grounds: 1. `AGENTS.md` `## Changing the rules or a checker` states the project has no waiver registry, because an exception registry is a state log and this protocol has no state log. One in-checker exception carrying its reason is - not a registry; a file of 41 growing to N is precisely one. + not a registry; a file of 42 growing to N is precisely one. 2. It needs the mechanism built three more times. The grep step and `check-role-discipline.py` have no exemption concept, so the change would add an exemption surface to code that currently has none — more new enforcement @@ -304,17 +316,22 @@ In scope: Out of scope, deliberately: -- Repairing the 41 commits. It cannot be done without rewriting `main`. +- Repairing the 42 commits. It cannot be done without rewriting `main`. - The three checkers themselves. Not one line changes. - `agent-record`'s missing-`hugo` red (#1722, fix in flight as #1726) and the two `windows-msvc` reds (#584). Both are inherited and neither is this row's. - The PR lane's base selection, which is unchanged. -## The 41 forgiven commits +## The 42 forgiven commits -Real protocol violations that landed unread between 2026-08-13 and 2026-08-23, +Real protocol violations that landed unread between 2026-08-13 and 2026-08-24, recorded here because after the floor advances no gate will name them again. +35 fail the strict trailer contract and 7 fail role discipline. The two sets are +disjoint. 41 of them were enumerated when the floor was first recorded at +`bacb71109`; the 42nd, `c00b99c7c`, arrived afterwards and moved the split from +35/6 to 35/7 — see `### The first advance`. + ### Fail `check-commit-trailers.py --range` (35) | Commit | Date | Subject | @@ -363,7 +380,7 @@ carries no `FOLLOWING_AGENTS_PROTOCOL` string at all: `7572b0f4e2fb`, `e34d71379e70`, `aba8d5ffb77c`, `2d2a66715ef4`, `1757330006f6`. The remaining 15 carry the marker in a form the strict contract rejects. -### Fail `check-role-discipline.py` (6) +### Fail `check-role-discipline.py` (7) Repository changes that reached `main` without arriving on a task branch. @@ -375,9 +392,61 @@ Repository changes that reached `main` without arriving on a task branch. | `5073df62228e` | 2026-08-18 | feat(BACKEND-ROCM): select the attention backend in the runner | | `65d6cdaed3e2` | 2026-08-18 | build: make the tree compile on gcc 16, and add a CI lane so it stays that way | | `6e73bdee3ea1` | 2026-08-23 | fix(LTX25-POSITION-CONTRACT): gate the tower positions as integers | +| `c00b99c7c8b6` | 2026-08-24 | fix(LTX25-DIT-ATTN-ARM-PARSE): match every DiT attention arm exactly and refuse a fourth value | + +`c00b99c7c8b6` is the 42nd and the newest. It landed +`src/vllm/model_executor/models/ltx2_device.cpp` and +`tests/vllm/models/test_ltx2_device.cpp` — product code and its test — straight +onto `main` with no `row/` branch in its history, which is what +`check-role-discipline.py` names: + +``` +ERROR: c00b99c7c: repository change (src/vllm/model_executor/models/ltx2_device.cpp, +tests/vllm/models/test_ltx2_device.cpp) reached main without arriving on a task +branch. +``` + +Its message is clean: it carries `FOLLOWING_AGENTS_PROTOCOL` and passes +`check-commit-trailers.py`. This is a **role-discipline** violation and not a +trailer one, so it is the seventh row of this table and not the thirty-sixth of +the one above, and the split across the 42 is 35 trailers / 7 role discipline +rather than 35 / 6. `check-now-current.py` passes over the whole range and forgives nothing. +**Every one of the 42 shas above resolves.** Verified with +`git rev-parse --verify -q '^{commit}'` over all 42, first at `origin/main` +`d60692c89` and again at `3574065e7` after the merge, both times against the +shas parsed back out of this committed table rather than a hand-kept copy: 42 +resolved, 0 missing, and all 42 are ancestors of `origin/main` by +`git merge-base --is-ancestor`. This is a full sweep and not a +spot-check, because after this lands the enumeration is the only witness that +these violations happened, and an earlier round of this list carried two shas +that resolved to nothing. + +### The first advance + +**This is the first exercise of `### Advancing the floor`, and it happened +before the pull request that introduces the mechanism had merged.** The row's +own risk 1 — "a violating commit lands between the recorded floor and the merge +of this row" — arrived on 2026-08-24, one day after the floor was recorded, and +was resolved by the procedure the row defines rather than by an exception to it. + +Two things are worth reading off that, and they point in opposite directions. +The mechanism works: the deadlock the row exists to break re-formed at a scale +of one commit instead of 41, and a one-line reviewed edit cleared it. And the +violations are still arriving: `c00b99c7c` is the second role-discipline +violation in two days, after `6e73bdee3ea1` on 2026-08-23. The floor is a way +to stop an unrepairable commit freezing a gate. It is not a fix for whatever is +putting product code on `main` without a task branch. + +**The advance is minimal by construction.** Measured at `origin/main` +`d60692c89`, ten first-parent commits sat above `bacb71109`, and exactly one of +them violated anything. The floor moved to that commit and no further. Setting +it to `origin/main` instead would have been one character of extra typing and +would have forgiven `e6f4f566f` and `d60692c89` unexamined, which is the abuse +risk 2 says nothing in this mechanism can detect. Both stay enforced. + ## Gates | Gate | Command | Result | @@ -395,7 +464,11 @@ Repository changes that reached `main` without arriving on a task branch. row.** The gate reds on that one commit, correctly, and the remedy now exists: advance the floor in a reviewed commit that names it. This is the designed behaviour and not a regression, but it means the floor value has to be - re-checked immediately before merge. + re-checked immediately before merge. **This risk fired.** `c00b99c7c` landed + on 2026-08-24 and the floor was advanced to it by exactly that remedy; see + `### The first advance`. The obligation it names does not expire with this + one discharge — `main` moves roughly every twenty minutes, so whoever merges + re-runs the four commands over `..origin/main` again. 2. **The floor is set too far forward by mistake.** It would skip commits nobody examined, and **nothing in this change detects it.** The two ancestry guards cover a different mistake: `resolve_base` warns and leaves the base alone @@ -427,7 +500,7 @@ Repository changes that reached `main` without arriving on a task branch. ## Owed -Nothing. The 41 commits are recorded above rather than owed: no future change can +Nothing. The 42 commits are recorded above rather than owed: no future change can repair them. @@ -591,11 +664,24 @@ head of this repair, with the same verdict both times: | `commit-trailers` | `python3 scripts/check-commit-trailers.py --range 849a7dd73..HEAD` | **0**, `OK: commit trailer contract` | | `commit-style` | `python3 scripts/check-commit-style.py --range 849a7dd73..HEAD` | **0**, `OK: commit writing style` | -The SKIP is not a defect in these commits: it is the branch being behind -`origin/main`, and a trial merge conflicts in `scripts/agent-preflight.sh`'s -`SUITES` array against `af320abb2`. Whoever merges resolves that conflict and -reruns the script, at which point the two gates run inside it rather than -beside it. +The SKIP was not a defect in these commits: it was the branch being behind +`origin/main`, and a trial merge conflicted in `scripts/agent-preflight.sh`'s +`SUITES` array against `af320abb2`, which also meant GitHub could produce no +merge ref for the pull request lane to check out. + +**Both are resolved.** `origin/main` `3574065e7` is merged into the branch and +the conflict is taken as a union of the two additions: `af320abb2`'s +`test_ltx2_dit_attn_knob_arms`, `test_ltx25_ab_memwatch` and +`test_tower_skip_rss_report`, plus this branch's `test_ci_walk_base`. Rerun +after the merge, `scripts/agent-preflight.sh` reports `ok commit-trailers` and +`ok commit-style` inside the script, against `origin/main` `3574065e7`, with no +SKIP. The merge is also what makes the advanced floor recordable: +`RecordedFloorTests::test_recorded_floor_is_an_ancestor_of_head` asserts the +recorded value is an ancestor of `HEAD`, `c00b99c7c` landed on `main` after this +branch left it, and the suite reds at 1 of 31 without the merge and is 31 of 31 +with it. `.agents/issue-index.md`'s #1809 row appears exactly once afterwards +and is no longer the tail, which is correct for an append-only union file; its +prose still says 41 because an index row is never rewritten. One site of the corrected `LAST_GREEN` claim is deliberately left alone: `scripts/ci-walk-base.py`'s module docstring still calls a floor behind @@ -606,24 +692,44 @@ boundary is not worth reopening it for. It is named here rather than left to be found: the sentence is wrong for the same reason `### Cancelled runs stay lossless` was, and it should go in whichever change next touches that file. -**Risk 1 has now arrived, and the floor does not stand as recorded.** Measured -2026-08-23T22:30Z at `origin/main` `e6f4f566f`, over `bacb71109..origin/main`, nine -first-parent commits: the presence grep is rc 0, `check-commit-trailers.py` is -rc 0, `check-now-current.py` is rc 0, and **`check-role-discipline.py` is rc 1** -on `c00b99c7c` (`fix(LTX25-DIT-ATTN-ARM-PARSE)`, 2026-08-23T22:01Z), which -reached `main` with `src/vllm/model_executor/models/ltx2_device.cpp` and its test -without arriving on a task branch. That commit is on `main` and is therefore -unrepairable, exactly like the six already in the role-discipline table above. - -The floor value is deliberately **not** changed by this repair. Advancing it is -the reviewed act described in `### Advancing the floor`, and doing it silently -inside a review repair is the thing that section forbids. The consequence is -concrete and belongs to whoever merges: with the floor at `bacb71109` the -`agent-record` role-discipline step reds on `c00b99c7c` forever after this -lands. Either advance the floor past it in a commit whose body names it, or -accept a standing red on that step. Repeat the four commands above immediately -before the merge, because `main` moves roughly every twenty minutes and this -paragraph will be stale. +**Risk 1 arrived, and the floor has been advanced once. RESOLVED.** It was +first measured 2026-08-23T22:30Z at `origin/main` `e6f4f566f`, over +`bacb71109..origin/main`, nine first-parent commits: the presence grep rc 0, +`check-commit-trailers.py` rc 0, `check-now-current.py` rc 0, and +**`check-role-discipline.py` rc 1** on `c00b99c7c` +(`fix(LTX25-DIT-ATTN-ARM-PARSE)`), which reached `main` with +`src/vllm/model_executor/models/ltx2_device.cpp` and its test without arriving +on a task branch. That review repair deliberately left the floor alone, because +advancing it silently inside a review repair is what `### Advancing the floor` +forbids. + +The advance is this commit, and it is a separate reviewed act with the argument +in its body. Re-measured independently at `origin/main` `d60692c89`, ten +first-parent commits, so the finding was reproduced rather than inherited: + +| Floor | grep step | `check-commit-trailers.py` | `check-role-discipline.py` | `check-now-current.py` | +|---|---|---|---|---| +| `bacb71109` (old) | rc 0 | rc 0 | **rc 1**, `c00b99c7c` | rc 0 | +| `c00b99c7c` (new) | rc 0 | rc 0 | rc 0 | rc 0 | + +Each rc was captured as `rc=$?` on the command itself and never after a pipe, +which reports the last stage of the pipeline and has misread a red as a green +twice in this row's history. `git merge-base --is-ancestor c00b99c7c +origin/main` is rc 0, so the new floor is on this history and the resolver's +ancestry guard accepts it. `tests/scripts/test_ci_walk_base.py` re-run over the +new value: 31 tests, 0 failures, 0 errors. + +The gate still bites over the new floor. A scratch commit on top of +`origin/main` whose message contains no `FOLLOWING_AGENTS_PROTOCOL` string +anywhere — marker count printed as **0** before the run, because a mutation +whose own message mentions the marker satisfies the presence grep and reads as +a pass — reds both trailer steps by name over `c00b99c7c..`. The tree +was restored and the restore proved by sha256 on both changed files, not by a +`git status` that a mutation can leave clean. + +Nothing about the value is permanent. `main` keeps moving, so whoever merges +repeats the four commands over `c00b99c7c..origin/main` and, if one reds again, +performs another advance the same way. `test_cpu_x86_llamacpp_floor` was red in two earlier runs and is #618, not this row. It was discriminated rather than asserted, twice over. Pristine diff --git a/scripts/ci-enforcement-floor.txt b/scripts/ci-enforcement-floor.txt index f3e08c017..d59c18f47 100644 --- a/scripts/ci-enforcement-floor.txt +++ b/scripts/ci-enforcement-floor.txt @@ -18,8 +18,15 @@ # and says why each cannot be repaired. `git log -p` on this file is the # complete history of the floor; there is no registry and no growing list. # -# THE CURRENT VALUE forgives 41 commits dated 2026-08-13 to 2026-08-23, each one +# THE CURRENT VALUE forgives 42 commits dated 2026-08-13 to 2026-08-24, each one # enumerated with its sha, date and subject in # `.agents/specs/ci-enforcement-floor.md`. That record is the only place that # now says those violations happened. -bacb71109c8d63b5f862c9b121dd86e04e1a07ee +# +# THE FLOOR IS THE FORGIVEN COMMIT ITSELF, not the one after it. The walk is +# `FLOOR..HEAD`, which excludes `FLOOR`, so setting it to the violating commit +# forgives that commit and every commit before it, and leaves every commit +# after it enforced. Advance it to the violation, never past it: a floor set +# further forward forgives whatever lands in between, unexamined, and nothing +# in this mechanism can detect that. The review is the only control. +c00b99c7c8b64f9247230ed6220598cc5c0e347e From eb3ca38cb72d272f911ffd77ffbe48d5f1ebcbd5 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Mon, 24 Aug 2026 01:50:29 +0000 Subject: [PATCH 11/11] record(GATE-CI-ENFORCEMENT-FLOOR): quote the role-discipline error whole, because a truncated one understates what it names The fenced block that justifies forgiving `c00b99c7c` re-wrapped the checker's output and cut it off after `...reached main without arriving on a task branch.`, with no ellipsis marking the cut. A reader had no way to see that the message continues, and the half that was dropped is the half that states the rule: work happens in its own worktree on a `row/` branch and lands through a reviewed PR or an authorized local merge naming that branch. That sentence is the reason the commit is a violation, so a record that omits it argues for the advance with the weaker half of the evidence. The block now carries the checker's single unwrapped line verbatim, and the prose names the exact invocation it came from so the next reader can reproduce it rather than trust a transcription. Copied from the checker's own stdout and compared byte-for-byte, not retyped. Nothing else changes. The floor value, the mechanism, the walk, and the enumerated 42 are untouched. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code] --- .agents/specs/ci-enforcement-floor.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.agents/specs/ci-enforcement-floor.md b/.agents/specs/ci-enforcement-floor.md index 5705acfe3..2c2d64bae 100644 --- a/.agents/specs/ci-enforcement-floor.md +++ b/.agents/specs/ci-enforcement-floor.md @@ -398,12 +398,13 @@ Repository changes that reached `main` without arriving on a task branch. `src/vllm/model_executor/models/ltx2_device.cpp` and `tests/vllm/models/test_ltx2_device.cpp` — product code and its test — straight onto `main` with no `row/` branch in its history, which is what -`check-role-discipline.py` names: +`check-role-discipline.py` names. The checker writes one unwrapped line, and +this is that line verbatim, copied from +`python3 scripts/check-role-discipline.py --base b207f34d3 --head c00b99c7c`, +which exits 1: ``` -ERROR: c00b99c7c: repository change (src/vllm/model_executor/models/ltx2_device.cpp, -tests/vllm/models/test_ltx2_device.cpp) reached main without arriving on a task -branch. +ERROR: c00b99c7c: repository change (src/vllm/model_executor/models/ltx2_device.cpp, tests/vllm/models/test_ltx2_device.cpp) reached main without arriving on a task branch. Work happens in its own worktree on a `row/` branch and lands through a reviewed PR or an authorized local merge naming that branch; never directly on the shared checkout ``` Its message is clean: it carries `FOLLOWING_AGENTS_PROTOCOL` and passes