Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .agents/issue-index.md
Original file line number Diff line number Diff line change
Expand Up @@ -652,3 +652,5 @@ rather than merged. `scripts/check-agent-record.py` gates both.
| [#1770](https://github.com/mudler/vllm.cpp/issues/1770) | `VT-CONV1D-TIME-BLOCK` | **The two b0 op-level losses the `out_channels * kernel <= in_len` condition was derived from do not reproduce on a second boot, and the condition measures NEUTRAL on the window.** Found while closing [#1683](https://github.com/mudler/vllm.cpp/issues/1683) in `rc` job `16b594ec-7987-4cae-b377-414adbe0f944` on `thor:gpu0`, worker `rc-worker-kk96r`, boot id `e2112cac-660b-434e-911d-33cbd29b9176`, with arms A, C and D built from `origin/main` at `8eecc05a9` inside one lease and differing only in the row's own files. `.agents/specs/vt-conv1d-time-block.md` §2b prices the UNCONDITIONAL arm C against the baseline at 86 latents and reads `b0_res_conv1` 0.82x and `b0_res_conv2` 0.89x; §3b's condition exists to decline exactly those two shapes and §9 records unconditional blocking as REJECTED on that evidence. The second job, same instrument, same length, three alternated rounds, medians: `b0_res_conv1` C 0.04073 s against D 0.03824 s = **1.065x**, keeping the direction at a quarter of the size, and `b0_res_conv2` C 0.00897 s against D 0.01134 s = **0.791x**, REVERSED -- blocking that shape is 21 % faster and the rule declines it. Over the two shapes together C reads 0.04970 s against D's 0.04958 s, a tie. The window agrees the condition is neutral: at 86 latents the rule decides differently on exactly four shapes, `vocoder.conv1d` makes 54 calls per window so they run 2, 2, 6 and 6 times, and the per-call deltas bound the condition's whole window effect at **0.36 ms, 0.01 % of a 3.5 s window**; the paired 7-round pairing reads C 3.3899 s against D 3.5072 s (0.97x), which at 3 % therefore CANNOT be the condition, arm D's legs being bimodal at 3.394-3.429 and 3.507-3.530 s against arm C's 3.368-3.468 s; at 20 latents the arms are within 1.2 % at every thread count from 1 to 14. Nothing is broken: the shipped arm is correct, bit-identical at two fingerprints across three arms and five thread counts, and scales 11.54x of 14. What is unsupported is that the condition BUYS anything on this box, so either the b0 readings are boot-sensitive at a magnitude the row did not budget for, or one of the two jobs measured something other than the geometry it named. NOT FIXED IN FLOW: settling it needs a fresh lease and a per-geometry spread rather than a median of three rounds, at both 20 and 86 latents, plus the probe's own `--control` residency sweep at the b0 footprint. Owned by [`vt-conv1d-time-block.md`](specs/vt-conv1d-time-block.md) `## Owed` | verification |
| [#1715](https://github.com/mudler/vllm.cpp/issues/1715) | `BACKEND-TENSTORRENT-GDN` | **The Qwen3.5/3.8 GDN-hybrid family cannot run on Tenstorrent: the GDN linear-attention op chain (`kGdnPrefill`, `kGdnDecode`, `kL2Norm`, `kRmsNormGated`, `kCausalConv1dFwd`/`kCausalConv1dUpdate`, `kGdnStateGather`/`kGdnStateScatter`) has no TT kernel, and the P150 is discrete so an op miss refuses by name rather than falling back** (`src/vt/op_provider.cpp` `Resolve`; `src/vllm/platforms/tenstorrent.cpp:55` allow-lists only OPT/Qwen3-dense/Mistral). Planned at the 2026-08-22 Qwen3.8 gap pass as the family's hard prerequisite on TT. Substrate anchor: the pinned tt-metal ships `ttnn::transformer::chunk_gated_delta_rule` (FLA chunked GDN forward, on-core state), mapping onto `kGdnPrefill` behind a varlen+state-permute adapter; decode composes the rank-1 update from matmul+eltwise with a device shadow keyed by host pointer (the `PagedKvShadow` pattern). Owned by this issue; spec [tenstorrent-gdn.md](specs/tenstorrent-gdn.md) | feature |
| [#1765](https://github.com/mudler/vllm.cpp/issues/1765) | `GATE-METAL-MLX-COMPILE` | **[#1692](https://github.com/mudler/vllm.cpp/issues/1692) says `src/vt/metal/metal_mlx_provider.mm` is "compiled by NO job in this repository". MEASURED, and that is wrong in a way that changes what is owed:** `.github/workflows/release.yml:347` `mlx_arm64` builds it on `macos-15` against the real `mlx==0.32.0` wheel. The defect is the TRIGGER -- `release.yml` fires on a `v*` tag or a manual dispatch, never on a pull request and never on a push to `main`, and `ci.yml` has no Apple runner (all 17 `runs-on` lines are ubuntu-latest x14, ubuntu-24.04-arm x1, windows-2022 x2; its single `macos` string is `test_release_macos_metadata.py` at `:199`, which compiles nothing). So the only build of the file happens AFTER a change lands, and a break presents as a BLOCKED RELEASE rather than a red check; #1584's edit to `MlxFallback` is the case that proved it. On a configured CPU tree the file has **0** occurrences in `build.ninja` and **0** in `compile_commands.json` -- as does every other `.mm` -- against 3 for `src/vt/op_provider.cpp` as a control. **Closed by a never-linked OBJECT library** (`vllm_metal_mlx_provider_syntax_check`, the `vllm_rocm_platform_syntax_check` idiom) that compiles the file on Linux: it is the ONLY Metal TU that can be, carrying 0 Objective-C constructs against 10/5/19 for `metal_ops.mm`/`metal_backend.mm`/`metal_context.mm`, because `metal_context.h:22` hands it every Metal handle as a `void*` on purpose. `LANGUAGE CXX` for `-x c++`; `-Wno-deprecated` for `#import`, MEASURED narrow (a `[[deprecated]]` call still fails as `-Werror=deprecated-declarations`); guarded `NOT VLLM_CPP_MLX` (the LANGUAGE property is directory-scoped and must not reach the shipping build) and `NOT MSVC` (`#import` there means a type library). **The limit is stated rather than glossed:** the stubs under `src/vt/metal/stubs` are written from this file's call sites, so the gate proves it compiles against the REAL `vt::` seam -- the #1584 defect class exactly -- and is blind to every MLX API change, which `mlx_arm64` alone can see. Red-before/green-after and the `## Owed` residue in [gate-metal-mlx-compile.md](specs/gate-metal-mlx-compile.md) | bug |
| [#1773](https://github.com/mudler/vllm.cpp/issues/1773) | `GATE-ANCHOR-PER-JOB` | **`main` cannot return to green by itself: the diff gates anchor on a RUN-level `status=success`, so a red or cancelled `main` widens its own range and keeps re-flagging the commits blocking it.** Measured at `21abaf169`: the query returns `fafa16f0f` from 2026-08-12, a **484-commit** range, while `documentation-checkpoint` itself concluded `success` at `1fdd3e26d` eleven days later inside a run whose own conclusion is `cancelled` (run `32625264281`) -- exactly the per-job/run-level distinction `scripts/main-baseline.py` has documented since [#274](https://github.com/mudler/vllm.cpp/issues/274) and which the job asking the question never called. A SECOND defect, sharper than the cycle: `last-gated-commit` is itself cancellable and the consumers carry `if: always()`, so when the resolver loses the race `LAST_GREEN` renders empty, the step falls back to `PUSH_BASE`, and the gate passes over one push -- **`main`'s diff gates are green when the resolver dies and red when it lives**, neither reading being about the tree. The re-flagged population is FIVE commits, not the three [#1764](https://github.com/mudler/vllm.cpp/issues/1764) saw (`dd8a3b0e1`, `8daf58e77`, `38ec0da4a`, `5073df622`, `65d6cdaed`); a widening range accretes offenders. **The external-fork hypothesis in #1764 and #1773 is REFUTED:** `check-role-discipline.py` reads no ref at all -- for a single-parent commit `arrives_via_row_pr` is commit-message text only -- and the one NON-fork commit of the five (`8daf58e77`, from `mudler/vllm.cpp:row/ENG-RELEASE-WINDOWS-test-thread-raii`) fails identically. The real discriminator is the squash SUBJECT: all five lack `(#N)`, where every other squash on `main` carries one even under `squash_merge_commit_title = PR_TITLE`. **What suppressed it is INFERRED, NOT MEASURED.** An explicit `commit_title` at merge is the documented way to suppress the append and the only candidate this row found, but the pulls endpoint keeps no merge-input payload, so the hypothesis is consistent with the evidence rather than demonstrated by it -- and all five were merged by the same `localai-bot` account that appends `(#N)` correctly on every other squash it lands. The design does not rest on it: the anchor fix is correct whatever suppressed the append. FIXED IN FLOW by the anchor, not by the rule: each diff-scoped job resolves its own anchor in its own first step, and **the unit of the verdict is the STEP, not the job** -- GitHub concludes a job `failure` the moment any step fails and marks every remaining step `skipped`, so a job-level question reads `failure` over a gate that refused the range and over a gate that never executed and cannot tell them apart (measured on `commit-protocol-tag`, runs `32601353990` through `32623377380`: job `failure` five times running with the strict-trailer step `skipped` every time, and `038ff61e5..a4f2a9585`, six commits, never gated). A gate step also SKIPS rather than narrows on a degraded anchor read, because a narrowed pass would conclude and advance the anchor past what the narrowing dropped. The checker is untouched. Spec [gate-anchor-per-job.md](specs/gate-anchor-per-job.md) | bug |
| [#1787](https://github.com/mudler/vllm.cpp/issues/1787) | `GATE-ANCHOR-PER-JOB` | **`scripts/check-symbol-anchors.py` resolves a citation written as `path::Symbol`, so a document that cites a symbol as a BARE backticked name with no path is outside its population entirely and the citation can name nothing at all.** Measured on `row/GATE-ANCHOR-PER-JOB` at `f671ca92d`: `.agents/specs/ci-concurrency.md:151` named `test_every_diff_scoped_step_bases_on_the_last_gated_commit`, which `26def4c8f` renamed to `test_every_diff_scoped_step_bases_on_its_own_jobs_anchor` in the same pull request ([#1776](https://github.com/mudler/vllm.cpp/pull/1776)); a `grep -rn` returns one hit, in the spec, and none in `tests/`, while the suite is green and `scripts/agent-preflight.sh` is rc 0. DISTINCT from [#1199](https://github.com/mudler/vllm.cpp/issues/1199), which measured the `path::Symbol` form WORKING, and from [#1601](https://github.com/mudler/vllm.cpp/issues/1601), which is a bare LINE citation into an upstream: this is the bare SYMBOL form, the one this repository's own style prefers and the one the checker never sees. **NOT FIXED IN FLOW:** resolving a bare backticked identifier is a change to checker semantics needing its own row, spec and red-before evidence, and it carries a real design question -- which backticked tokens are citations and which are prose -- so a naive rule would red on every backticked word in every document. The stale citation itself IS repaired in #1776. Owned by `GATE-ANCHOR-PER-JOB` and listed under `## Owed` in [`gate-anchor-per-job.md`](specs/gate-anchor-per-job.md) | gap |
20 changes: 18 additions & 2 deletions .agents/specs/ci-concurrency.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,18 @@ commits the cancelled one skipped. `github.event.before` remains the fallback
when no successful run is found, which preserves today's behaviour on a fresh
branch.

> **SUPERSEDED, 2026-08-23, by `GATE-ANCHOR-PER-JOB`
> ([#1773](https://github.com/mudler/vllm.cpp/issues/1773)).** The paragraph
> above describes the shape this row shipped and it is no longer what the tree
> does. A RUN-level `status=success` froze the base for eleven days and 484
> commits: `main` could not return to green by itself, because a red run never
> advanced the anchor and each push therefore re-flagged the same landed
> commits over a wider range. The base is now resolved PER GATE STEP, by the
> job that consumes it, from the newest push run in which that STEP returned a
> verdict -- `success` or `failure`, because a commit on `main` is immutable
> and one alarm per violation is a complete alarm. Read
> [`gate-anchor-per-job.md`](gate-anchor-per-job.md) for the current rule.

This is what makes cancellation lossless. It is the enabling change, not a
side change.

Expand Down Expand Up @@ -148,8 +160,12 @@ a group-free job, on the theory that group-freeness was the invariant. It is
not. A workflow-level `cancel-in-progress` cancels every job in the run,
including jobs carrying no group, so the move protects nothing once the push
lane is latest-only. The self-healing base is the whole repair; the move is
tidiness. `test_every_diff_scoped_step_bases_on_the_last_gated_commit` asserts
the real invariant and says so in its docstring.
tidiness. `test_every_diff_scoped_step_bases_on_its_own_jobs_anchor` asserts the
real invariant and says so in its docstring. (It was
`test_every_diff_scoped_step_bases_on_the_last_gated_commit` until #1773
renamed it with the rule; the citation is a bare backticked name with no
`path::Symbol` form, so `scripts/check-symbol-anchors.py` did not catch the
staleness -- see `gate-anchor-per-job.md` §10.)

**What the tests found.** Writing the group-free assertion surfaced a second
diff-scoped gate nobody had noticed: `check-role-discipline.py --base/--head`
Expand Down
Loading
Loading