From 99791f5bb860a0a44a8052e82cc8c17056d75e54 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Sun, 23 Aug 2026 16:05:12 +0000 Subject: [PATCH 1/4] record(SPEC-DFLASH2): #1456's conclusion is retracted at the artifact, and the 0.8017 denominator inherits it (#1796) #1456 measured a real source build at `CUDA_ARCHS=12.0` emitting `sm_80` for `_vllm_fa2_C` and `sm_75` for `_vllm_fa3_C`, and concluded that vLLM's vendored flash-attention cannot target sm_12x, so the GB10 oracle has no `FLASH_ATTN` denominator. The measurement stands. The conclusion does not, and showing that needed no lease: both staged oracle wheels were opened with `zipfile` and walked as fatbinaries on the CPU dev box, and every one of the 76 FA2 and 192 FA3 fatbinaries in each wheel carries a PTX image beside its SASS image. The first FA2 payload decompresses to `.version 9.0` / `.target sm_80`, which is the `+PTX` half of `FA2_ARCHS "8.0+PTX"` and is how the module reaches sm_121. `cudaErrorUnsupportedPtxVersion` is the opposite failure. vLLM says the same in its own source: `FlashAttentionBackend.supports_compute_capability` returns `capability >= DeviceCapability(8, 0)`. The downstream is why this is filed rather than noted. #1456's body records that the DFlash2 speed gate's denominator would be vLLM pinned to `TRITON_ATTN`, by developer decision on 2026-08-20, explicitly because of that conclusion, and the first DFlash2 speed ratio `0.8016987337853048` was taken against it. AGENTS.md requires vLLM's production configuration as the denominator, and on this box vLLM's own auto-selection picks `FLASH_ATTN` -- the gate run's log carries both branches in one process. So if `TRITON_ATTN` is the slower backend, which vLLM's priority ordering asserts and nothing here measures, the denominator is too low and the ratio is too high. An error in our own favour is the one nobody chases, so it is recorded with its sign. Nothing is re-measured and no denominator is substituted: a wave must not replace a denominator the developer declared. What remains is one lease running vLLM against itself on this workload with `attention_backend=FLASH_ATTN` against `TRITON_ATTN`, each read back off the built engine, and no GPU lease is authorised, so it is PENDING. The same read also settles #1685's three open readings. The DFlash draft's config sets `backend=speculative_config.attention_backend` unconditionally, so a harness that sets only the engine backend leaves the draft at `None` and the draft re-runs auto-selection; the sibling dspark and gemma4 speculators both carry the target's backend through, and dspark's comment names the hazard. 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/dflash2-spec-decode.md | 104 ++++++++++++++++++++++++++- 2 files changed, 104 insertions(+), 1 deletion(-) diff --git a/.agents/issue-index.md b/.agents/issue-index.md index e4ef48c1f..5bfb1264e 100644 --- a/.agents/issue-index.md +++ b/.agents/issue-index.md @@ -660,3 +660,4 @@ rather than merged. `scripts/check-agent-record.py` gates both. | [#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 | | [#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 | +| [#1796](https://github.com/mudler/vllm.cpp/issues/1796) | `SPEC-DFLASH2` | **[#1456](https://github.com/mudler/vllm.cpp/issues/1456)'s conclusion is retracted AT THE ARTIFACT, off-GPU, and the DFlash2 speed ratio's denominator inherits the retraction: `0.8016987337853048` MAY BE FLATTERING US.** #1456 measured a real source build at `CUDA_ARCHS=12.0` emitting `sm_80` for `_vllm_fa2_C` and `sm_75` for `_vllm_fa3_C`, and concluded the GB10 oracle has no `FLASH_ATTN` denominator. **The arch measurement stands; the conclusion does not, and no lease was needed to show it.** Both staged oracle wheels were opened with `zipfile` and walked as fatbinaries on the CPU dev box: `0.1.dev1+g66e5414c6` (this row's oracle, `/mnt/nas_share/rc/oracle-dflash2/`) and `0.1.dev1+g555967922` (the parity pin, `/mnt/nas_share/rc/oracle-vllm/`) each carry 76 FA2 fatbinaries and 192 FA3 fatbinaries, and **every one holds a PTX image beside its SASS image** -- arch 80 for FA2, arch 75 for FA3. The first FA2 PTX payload is zstd and decompresses to `.version 9.0` / `.target sm_80` for `flash_fwd_hdim128_bf16_causal_sm80`. That is the `+PTX` half of `FA2_ARCHS "8.0+PTX"` and it is how the module reaches sm_121; `cudaErrorUnsupportedPtxVersion` is the OPPOSITE failure, PTX ISA newer than the driver, which `.version 9.0` under driver 580.173.02 is not. vLLM says it directly too: `FlashAttentionBackend.supports_compute_capability` returns `capability >= DeviceCapability(8, 0)` (`vllm/v1/attention/backends/flash_attn.py:251-252` in the staged wheel). **THE DOWNSTREAM IS THE THING TO CHASE.** #1456's body records that the DFlash2 speed gate's denominator "will be vLLM pinned to `TRITON_ATTN`, by developer decision on 2026-08-20", explicitly because of that conclusion. AGENTS.md requires vLLM's PRODUCTION configuration as the denominator, and on this box vLLM's own auto-selection picks `FLASH_ATTN`: the 0.8017 gate run's log carries BOTH paths in one process, the forced branch taking `TRITON_ATTN` for the 27B target (`cuda.py:426`) and the auto branch taking `FLASH_ATTN` out of four valid backends (`cuda.py:486`), in `/mnt/nas_share/rc/dflash2-1673/out-n1673b/m-gate.log`. **So if `TRITON_ATTN` is the slower backend -- which vLLM's own priority ordering asserts and nothing here measures -- then 16.279 tok/s is too LOW and the ratio is too HIGH. An error in our own favour is the one nobody chases, so it is recorded with its sign.** The ratio is NOT withdrawn and no denominator is substituted, because a wave must not replace a denominator the developer declared. **The five FA layers of [#1685](https://github.com/mudler/vllm.cpp/issues/1685) fall out of the same read**: `vllm/v1/worker/gpu/spec_decode/dflash/utils.py:31-46` sets the draft's `backend=speculative_config.attention_backend` UNCONDITIONALLY, so a harness that sets only the engine backend leaves the draft at `None` and the draft re-runs auto-selection; the siblings `dspark/utils.py:24-28` and `gemma4/speculator.py:66-89` both carry the target's backend through, and dspark's comment names this hazard by name. NOT reconciled in flow, and the reason is precise: what remains is ONE lease running vLLM against itself on this workload with `attention_backend=FLASH_ATTN` against `TRITON_ATTN`, each read back off the built engine, and **no GPU lease is authorised for this session**, so it is PENDING. Recommended collapse, recommended and not taken: #1456, [#1679](https://github.com/mudler/vllm.cpp/issues/1679) and #1685 observe ONE mechanism on two wheels, and #1685 is the one attached to a live number and should survive. Owed under `## Owed` O33 of [the DFlash2 spec](specs/dflash2-spec-decode.md), with caveat 5 beside the ratio in the same file | verification | diff --git a/.agents/specs/dflash2-spec-decode.md b/.agents/specs/dflash2-spec-decode.md index 264ec80fb..a8255f0d9 100644 --- a/.agents/specs/dflash2-spec-decode.md +++ b/.agents/specs/dflash2-spec-decode.md @@ -2889,6 +2889,98 @@ list items. difference as a defect is the failure this row keeps having, so it is written down rather than filed. +- **O33 — the denominator is NOT vLLM's production configuration, and the + constraint that justified substituting one is RETRACTED AT THE ARTIFACT.** + Owner: `SPEC-DFLASH2` for this row's ratio, the developer for the declaration. + [#1796](https://github.com/mudler/vllm.cpp/issues/1796) carries this entry and + its evidence, [#1456](https://github.com/mudler/vllm.cpp/issues/1456) is the + retracted premise, and [#1685](https://github.com/mudler/vllm.cpp/issues/1685) + is the observation it explains. + **NOTHING IS RE-MEASURED HERE AND NO DENOMINATOR IS SUBSTITUTED.** + + O22 records that a W6 RUN falsified #1456's conclusion. This entry records that + the WHEEL ITSELF falsifies it, off-GPU, so the retraction no longer rests on + reading a log that was lost with its lease. Both staged oracle wheels were read + with `zipfile` and a fatbinary walk on the CPU dev box — no lease, no GPU, no + CUDA toolkit: + + | wheel | module | fatbins | images per fatbin | arch | + |---|---|---:|---|---:| + | `0.1.dev1+g66e5414c6` (this row's oracle) | `_vllm_fa2_C.abi3.so` | 76 | ELF **and PTX** | 80 | + | `0.1.dev1+g66e5414c6` | `_vllm_fa3_C.abi3.so` | 192 | ELF **and PTX** | 75 | + | `0.1.dev1+g555967922` (the parity pin) | `_vllm_fa2_C.abi3.so` | 76 | ELF **and PTX** | 80 | + | `0.1.dev1+g555967922` | `_vllm_fa3_C.abi3.so` | 192 | ELF **and PTX** | 75 | + + Every fatbinary carries a PTX image beside its SASS image. The first FA2 PTX + payload is zstd, and it decompresses to `.version 9.0` / `.target sm_80` for + `flash_fwd_hdim128_bf16_causal_sm80`. **That is the `+PTX` half of + `FA2_ARCHS "8.0+PTX"`, and it is how the module reaches sm_121.** #1456 read + the SASS arch and concluded the module "cannot target sm_12x"; the arch reading + is right and the conclusion drops the PTX. + `cudaErrorUnsupportedPtxVersion` is raised when PTX ISA is NEWER than the + driver, and `.version 9.0` under driver 580.173.02 is not that case. vLLM says + the same thing in its own words: `FlashAttentionBackend.supports_compute_capability` + returns `capability >= DeviceCapability(8, 0)` at + `vllm/v1/attention/backends/flash_attn.py:251-252` in the staged wheel, so 12.1 + is a capability upstream declares supported. + + **WHAT THAT DOES TO THE RATIO.** #1456's body records the denominator decision + in one sentence: the DFlash2 speed gate's denominator "will be vLLM pinned to + `TRITON_ATTN`, by developer decision on 2026-08-20 ... it is NOT vLLM's default + backend on this device, and any ratio taken against it must say so." AGENTS.md + requires vLLM's PRODUCTION configuration as the denominator. On this box that + configuration selects `FLASH_ATTN`, and the gate run's own log shows both paths + in the same process: the forced path took `TRITON_ATTN` for the 27B target + (`out-n1673b/m-gate.log:30`, `cuda.py:426`, the branch that honours an explicit + request) and the auto path chose `FLASH_ATTN` out of four valid backends + (`m-gate.log:57`, `cuda.py:486`). So the denominator ran vLLM's sixteen + full-attention target layers on a backend vLLM itself ranks below its first + choice, on a premise that no longer holds. + + **SAY THE DIRECTION PLAINLY: THE ERROR, IF IT IS ONE, IS IN OUR FAVOUR.** If + `TRITON_ATTN` is the slower backend — which is what vLLM's own priority + ordering asserts and what nothing here measures — then the denominator + 16.27918250335551 tok/s is too LOW and `0.8016987337853048` is too HIGH. An + error that flatters us is the one nobody chases, so it is written down beside + the number rather than left to be noticed. **The ratio is not withdrawn and no + replacement is asserted.** What is asserted is that its denominator rests on a + retracted premise, and that the exposure has a sign. + + **WHAT IS OWED, AND IT IS PENDING A LEASE THIS SESSION DOES NOT HAVE.** One run + of vLLM against itself on this identical workload — same wheel, same host, same + k, same prompts, same `max_num_seqs` — with `attention_backend=FLASH_ATTN` + against `attention_backend=TRITON_ATTN`, each read back off the built engine as + O22 requires. That measurement decides whether 0.8017 stands, is flattered, or + is conservative. It also needs the developer to revisit the 2026-08-20 + declaration, because a wave must not substitute a denominator the developer + set. + + **AND THE FIVE FA LAYERS INSIDE THE DENOMINATOR ARE NOW EXPLAINED, which #1685 + left open as three readings.** + `vllm/v1/worker/gpu/spec_decode/dflash/utils.py:31-46` builds the draft's + config with `backend=speculative_config.attention_backend`, UNCONDITIONALLY: + the target's `attention_config.backend` is not carried through. The harness set + the engine backend and not `speculative_config.attention_backend`, so the + draft's backend was `None`, which is the auto-selection branch of + `CudaPlatform.get_attn_backend_cls` (`vllm/platforms/cuda.py:429-496`), and it + chose `FLASH_ATTN`. Those are the five `model.layers.64-68.self_attn.attn` in + `evidence/vllm-arm.json`. **Two sibling speculators in the same wheel DO carry + the target's backend through** — `dspark/utils.py:24-28`, whose comment names + this exact hazard ("None re-runs backend auto-selection for the draft, which + can pick a different attention class than the target; fall back to the + target's"), and `gemma4/speculator.py:66-89`. So the DFlash path is the + un-defended case rather than an upstream intent. #1685's reading 1 is + therefore wrong; reading 2 is refuted, because `FlashAttentionImpl.__init__` + logged `Using FlashAttention version 2` at `flash_attn.py:906-914` and an FA + implementation was constructed for those layers; reading 3 is what the artifact + supports. + + **WHAT IS STILL NOT PROVEN IS THE KERNEL LAUNCH.** Construction is proven and + coherent output is measured on both arms. A trace showing an FA2 kernel enter + the SM on this box is not in hand and needs a lease. It is not needed for the + retraction, and it IS needed before anybody claims the forward JIT is free. + + ## Now **W6 TOOK THE GATES on 2026-08-21, on `dgx:gpu0` through an `rc` lease, and G2 @@ -3198,7 +3290,7 @@ own leg boundaries since O32, the folded legs are 3.744 s to 10.385 s each, and four ~200-290 s cold legs are discarded by name. The loads sat outside every span. -**FOUR CAVEATS TRAVEL WITH THE RATIO, and they are the reason it is recorded +**FIVE CAVEATS TRAVEL WITH THE RATIO, and they are the reason it is recorded rather than claimed.** 1. **[#1673](https://github.com/mudler/vllm.cpp/issues/1673) FIRED AND DID NOT @@ -3224,6 +3316,16 @@ rather than claimed.** still costs a lease. 4. **One measured axis is not a speed gate.** Memory, TTFT and per-token latency remain open gaps on this row. +5. **[#1456](https://github.com/mudler/vllm.cpp/issues/1456) IS RETRACTED, so + caveat 2 grew a SIGN: the denominator may be flattering us.** `TRITON_ATTN` + was declared for this box because #1456 concluded the wheel's flash-attention + cannot reach sm_12x. Both staged wheels carry `.target sm_80` PTX beside the + SASS, and vLLM's own `supports_compute_capability` admits `>= 8.0`, so the + premise is gone and `FLASH_ATTN` is what vLLM's production configuration + selects here. If it is also the faster one, then 16.279 tok/s is too low and + 0.8017 is too high. Nothing is re-measured, the ratio is not withdrawn, and + [#1796](https://github.com/mudler/vllm.cpp/issues/1796) with `## Owed` O33 + carries what it would take to settle it. **AND O32 IS WHAT MADE THIS RUN EMIT A NUMBER AT ALL.** The whole-window summary the sampler wrote, `evidence/clock-ours.json`, reads 550 busy of 2943 samples — From a55c5d4788503376e09ea7a62689c4e4a14c130e Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Sun, 23 Aug 2026 16:17:18 +0000 Subject: [PATCH 2/4] record(SPEC-DFLASH2): repair four fresh-review findings on the #1456 retraction (#1796) The fresh review re-derived every cited anchor and confirmed all twelve, with one enumeration wrong and four notes. All are repaired here, and the repairs land before the row does, so `main` sees one appended index row in its final form. The enumeration: `FA_USABLE` also appears in `.agents/issue-index.md` at the #1456, #1658 and #1685 rows, not only in `.agents/benchmark-record.md` and this spec. The index is append-only, so those three cannot be edited, which is exactly why naming them matters; `## Owed` O33 now names all four inheriting sites and keeps the confirmed part, that `.agents/oracles/` and `.agents/upstream-sync.md` contain none of `FA_USABLE`, `FLASH_ATTN` or `TRITON_ATTN`, so no oracle file needs retracting. The notes. "It is how the module reaches sm_121" is now "the mechanism by which it CAN reach sm_121", because the artifact establishes a necessary condition and the JIT having run is an inference; the paragraph that disclaims the kernel launch no longer contradicts the one above it. "vLLM's own priority ordering asserts" becomes "implies rather than states", because a preference list is not a speed claim. #1685's reading 2 is refuted on the runtime half as well as the constructor half: `flash_attn.py` carries no `fallback` token and `FlashAttentionImpl.forward` raises `NotImplementedError` rather than degrading. Reading 1 is wrong AS INTENT, which is the accurate form. A double blank line before `## Now` is closed. 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/dflash2-spec-decode.md | 40 ++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/.agents/issue-index.md b/.agents/issue-index.md index 0debf2f01..84bfec793 100644 --- a/.agents/issue-index.md +++ b/.agents/issue-index.md @@ -661,4 +661,4 @@ rather than merged. `scripts/check-agent-record.py` gates both. | [#1783](https://github.com/mudler/vllm.cpp/issues/1783) | `ENG-EXPERT-STREAM-DEVICE` | **`.agents/benchmark-record.md`'s W0f entry transcribes the CUDA arm's 32 ids with `7172` dropped in TWO places, so every record that inherited it names the wrong divergence point, and the branch-force run that caught it also FALSIFIES W0h ground 1.** With `7172` restored the two arms share **eight** generated tokens and first diverge at **position 9**, `279` (" the") against `9338` (" France"); the records said six tokens, step 7, and `7172` against `303`. Step 7 is a step both arms AGREE on, which is what the W0f entry's own top-2 table says (`7172` 18.779411 over `303` 18.514702), and the divergent step is step 9 at margin 0.022802. The error is visible with no log at all: [`cuda-arm-degradation-experiment.md`](specs/cuda-arm-degradation-experiment.md) quotes the CUDA text as "a city **located** in France" and " located" IS `7172`, while the transcribed ids decode to "a city in France". **Inherited at SEVEN sites, enumerated because two earlier passes over this fact each under-counted them**: [`expert-stream-device-slots.md`](specs/expert-stream-device-slots.md) at FOUR -- its W0e G0-CORRECT bullet, its `## Gates` G0-CORRECT cell, its W0f narrative and its `## Owed` ratified-gate cell; the PUBLIC [`docs/models/qwen3-8-2-4t.md`](../docs/models/qwen3-8-2-4t.md) at TWO -- the divergence paragraph and the coin-flip clause 33 lines below it, which asserted the argument this same change falsifies; and the SHIPPED HEADER `include/vllm/model_executor/models/qwen3_5_weights.h`, whose `kDeviceAliasAlignment` comment carried the same 0.264709 attribution. The append-only [`benchmark-record.md`](benchmark-record.md)'s W0g entry then carries TWO further defects rather than one, and they are DIFFERENT defects that have to be searched for separately: an EIGHTH restatement of the wrong margin, and about 200 lines below it the coin-flip inference itself, whose token count is RIGHT ("agree for 8 tokens") and whose ARGUMENT this run falsifies, which is why four sweeps that searched for the number walked past it. The entry keeps its bytes and each defect gains its own INSERTED note rather than an edit. A stale W0e-era sentence in the same spec also still said "Both continuations are coherent" while two other places in that one file said the CUDA continuation degenerates. **The substantive half is ground 1 of W0h** ([#1736](https://github.com/mudler/vllm.cpp/issues/1736), which stays OPEN): it argued the recursion proves the CUDA arm is worse because "a coin flip between two equally good tokens does not produce that". A five-arm CPU-only branch-force run on `dgx:gpu0` (2026-08-23, source `ff8f728071bd5`, one binary, identity arm first and byte-exact against the four-times-recorded CPU answer including its stream counters) shows it does: prefilled with the eight shared tokens plus `9338` the CPU arm recurses into the CUDA continuation, prefilled with `279` it reproduces the CPU tail with 23 ids byte-identical. Independently, reaching the same branch-point context by PREFILL instead of decode flips the top-2 on the CPU arm alone, `9338` 19.962210 over `279` 19.820848 against the reference decode's `279` 19.850554 over `9338` 19.827751. FIXED IN FLOW: benchmark-record is append-only so the W0f entry keeps its bytes and gains an INSERTED correction note plus a new W0h section, the W0g entry keeps its bytes and gains TWO INSERTED notes, the seven inheriting sites listed above are corrected in place and each says what it used to say, and W0h ground 1 is rewritten as OFFERED, TESTED, FALSIFIED rather than deleted. The pre-registered decision rule is byte-identical across the change and the spec carries the one-command digest check that proves it. G0-CORRECT stays FAILING and G0-SPEED stays VOID; grounds 2 and 3 carry W0h | bug | | [#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 | -| [#1796](https://github.com/mudler/vllm.cpp/issues/1796) | `SPEC-DFLASH2` | **[#1456](https://github.com/mudler/vllm.cpp/issues/1456)'s conclusion is retracted AT THE ARTIFACT, off-GPU, and the DFlash2 speed ratio's denominator inherits the retraction: `0.8016987337853048` MAY BE FLATTERING US.** #1456 measured a real source build at `CUDA_ARCHS=12.0` emitting `sm_80` for `_vllm_fa2_C` and `sm_75` for `_vllm_fa3_C`, and concluded the GB10 oracle has no `FLASH_ATTN` denominator. **The arch measurement stands; the conclusion does not, and no lease was needed to show it.** Both staged oracle wheels were opened with `zipfile` and walked as fatbinaries on the CPU dev box: `0.1.dev1+g66e5414c6` (this row's oracle, `/mnt/nas_share/rc/oracle-dflash2/`) and `0.1.dev1+g555967922` (the parity pin, `/mnt/nas_share/rc/oracle-vllm/`) each carry 76 FA2 fatbinaries and 192 FA3 fatbinaries, and **every one holds a PTX image beside its SASS image** -- arch 80 for FA2, arch 75 for FA3. The first FA2 PTX payload is zstd and decompresses to `.version 9.0` / `.target sm_80` for `flash_fwd_hdim128_bf16_causal_sm80`. That is the `+PTX` half of `FA2_ARCHS "8.0+PTX"` and it is how the module reaches sm_121; `cudaErrorUnsupportedPtxVersion` is the OPPOSITE failure, PTX ISA newer than the driver, which `.version 9.0` under driver 580.173.02 is not. vLLM says it directly too: `FlashAttentionBackend.supports_compute_capability` returns `capability >= DeviceCapability(8, 0)` (`vllm/v1/attention/backends/flash_attn.py:251-252` in the staged wheel). **THE DOWNSTREAM IS THE THING TO CHASE.** #1456's body records that the DFlash2 speed gate's denominator "will be vLLM pinned to `TRITON_ATTN`, by developer decision on 2026-08-20", explicitly because of that conclusion. AGENTS.md requires vLLM's PRODUCTION configuration as the denominator, and on this box vLLM's own auto-selection picks `FLASH_ATTN`: the 0.8017 gate run's log carries BOTH paths in one process, the forced branch taking `TRITON_ATTN` for the 27B target (`cuda.py:426`) and the auto branch taking `FLASH_ATTN` out of four valid backends (`cuda.py:486`), in `/mnt/nas_share/rc/dflash2-1673/out-n1673b/m-gate.log`. **So if `TRITON_ATTN` is the slower backend -- which vLLM's own priority ordering asserts and nothing here measures -- then 16.279 tok/s is too LOW and the ratio is too HIGH. An error in our own favour is the one nobody chases, so it is recorded with its sign.** The ratio is NOT withdrawn and no denominator is substituted, because a wave must not replace a denominator the developer declared. **The five FA layers of [#1685](https://github.com/mudler/vllm.cpp/issues/1685) fall out of the same read**: `vllm/v1/worker/gpu/spec_decode/dflash/utils.py:31-46` sets the draft's `backend=speculative_config.attention_backend` UNCONDITIONALLY, so a harness that sets only the engine backend leaves the draft at `None` and the draft re-runs auto-selection; the siblings `dspark/utils.py:24-28` and `gemma4/speculator.py:66-89` both carry the target's backend through, and dspark's comment names this hazard by name. NOT reconciled in flow, and the reason is precise: what remains is ONE lease running vLLM against itself on this workload with `attention_backend=FLASH_ATTN` against `TRITON_ATTN`, each read back off the built engine, and **no GPU lease is authorised for this session**, so it is PENDING. Recommended collapse, recommended and not taken: #1456, [#1679](https://github.com/mudler/vllm.cpp/issues/1679) and #1685 observe ONE mechanism on two wheels, and #1685 is the one attached to a live number and should survive. Owed under `## Owed` O33 of [the DFlash2 spec](specs/dflash2-spec-decode.md), with caveat 5 beside the ratio in the same file | verification | +| [#1796](https://github.com/mudler/vllm.cpp/issues/1796) | `SPEC-DFLASH2` | **[#1456](https://github.com/mudler/vllm.cpp/issues/1456)'s conclusion is retracted AT THE ARTIFACT, off-GPU, and the DFlash2 speed ratio's denominator inherits the retraction: `0.8016987337853048` MAY BE FLATTERING US.** #1456 measured a real source build at `CUDA_ARCHS=12.0` emitting `sm_80` for `_vllm_fa2_C` and `sm_75` for `_vllm_fa3_C`, and concluded the GB10 oracle has no `FLASH_ATTN` denominator. **The arch measurement stands; the conclusion does not, and no lease was needed to show it.** Both staged oracle wheels were opened with `zipfile` and walked as fatbinaries on the CPU dev box: `0.1.dev1+g66e5414c6` (this row's oracle, `/mnt/nas_share/rc/oracle-dflash2/`) and `0.1.dev1+g555967922` (the parity pin, `/mnt/nas_share/rc/oracle-vllm/`) each carry 76 FA2 fatbinaries and 192 FA3 fatbinaries, and **every one holds a PTX image beside its SASS image** -- arch 80 for FA2, arch 75 for FA3. The first FA2 PTX payload is zstd and decompresses to `.version 9.0` / `.target sm_80` for `flash_fwd_hdim128_bf16_causal_sm80`. That is the `+PTX` half of `FA2_ARCHS "8.0+PTX"` and it is the mechanism by which the module CAN reach sm_121 -- the artifact establishes a necessary condition, forward-JITtable code being shipped, and that the JIT then ran is an inference from that plus a run selecting `FLASH_ATTN` and generating; `cudaErrorUnsupportedPtxVersion` is the OPPOSITE failure, PTX ISA newer than the driver, which `.version 9.0` under driver 580.173.02 is not. vLLM says it directly too: `FlashAttentionBackend.supports_compute_capability` returns `capability >= DeviceCapability(8, 0)` (`vllm/v1/attention/backends/flash_attn.py:251-252` in the staged wheel). **THE DOWNSTREAM IS THE THING TO CHASE.** #1456's body records that the DFlash2 speed gate's denominator "will be vLLM pinned to `TRITON_ATTN`, by developer decision on 2026-08-20", explicitly because of that conclusion. AGENTS.md requires vLLM's PRODUCTION configuration as the denominator, and on this box vLLM's own auto-selection picks `FLASH_ATTN`: the 0.8017 gate run's log carries BOTH paths in one process, the forced branch taking `TRITON_ATTN` for the 27B target (`cuda.py:426`) and the auto branch taking `FLASH_ATTN` out of four valid backends (`cuda.py:486`), in `/mnt/nas_share/rc/dflash2-1673/out-n1673b/m-gate.log`. **So if `TRITON_ATTN` is the slower backend -- which vLLM's own priority ordering IMPLIES rather than states, and which nothing here measures -- then 16.279 tok/s is too LOW and the ratio is too HIGH. An error in our own favour is the one nobody chases, so it is recorded with its sign.** The ratio is NOT withdrawn and no denominator is substituted, because a wave must not replace a denominator the developer declared. **The five FA layers of [#1685](https://github.com/mudler/vllm.cpp/issues/1685) fall out of the same read**: `vllm/v1/worker/gpu/spec_decode/dflash/utils.py:31-46` sets the draft's `backend=speculative_config.attention_backend` UNCONDITIONALLY, so a harness that sets only the engine backend leaves the draft at `None` and the draft re-runs auto-selection; the siblings `dspark/utils.py:24-28` and `gemma4/speculator.py:66-89` both carry the target's backend through, and dspark's comment names this hazard by name. NOT reconciled in flow, and the reason is precise: what remains is ONE lease running vLLM against itself on this workload with `attention_backend=FLASH_ATTN` against `TRITON_ATTN`, each read back off the built engine, and **no GPU lease is authorised for this session**, so it is PENDING. Recommended collapse, recommended and not taken: #1456, [#1679](https://github.com/mudler/vllm.cpp/issues/1679) and #1685 observe ONE mechanism on two wheels, and #1685 is the one attached to a live number and should survive. Owed under `## Owed` O33 of [the DFlash2 spec](specs/dflash2-spec-decode.md), with caveat 5 beside the ratio in the same file | verification | diff --git a/.agents/specs/dflash2-spec-decode.md b/.agents/specs/dflash2-spec-decode.md index a8255f0d9..e876e52b8 100644 --- a/.agents/specs/dflash2-spec-decode.md +++ b/.agents/specs/dflash2-spec-decode.md @@ -2914,9 +2914,13 @@ list items. Every fatbinary carries a PTX image beside its SASS image. The first FA2 PTX payload is zstd, and it decompresses to `.version 9.0` / `.target sm_80` for `flash_fwd_hdim128_bf16_causal_sm80`. **That is the `+PTX` half of - `FA2_ARCHS "8.0+PTX"`, and it is how the module reaches sm_121.** #1456 read - the SASS arch and concluded the module "cannot target sm_12x"; the arch reading - is right and the conclusion drops the PTX. + `FA2_ARCHS "8.0+PTX"`, and it is the mechanism by which the module CAN reach + sm_121.** Be exact about what that buys: the artifact establishes a NECESSARY + condition, that forward-JITtable code is shipped. That the JIT then ran is an + inference from the PTX being there and a run selecting `FLASH_ATTN` and + generating. #1456 read the SASS arch and concluded the module "cannot target + sm_12x"; the arch reading is right, and the conclusion drops the PTX, which is + enough to retract it. `cudaErrorUnsupportedPtxVersion` is raised when PTX ISA is NEWER than the driver, and `.version 9.0` under driver 580.173.02 is not that case. vLLM says the same thing in its own words: `FlashAttentionBackend.supports_compute_capability` @@ -2938,8 +2942,9 @@ list items. choice, on a premise that no longer holds. **SAY THE DIRECTION PLAINLY: THE ERROR, IF IT IS ONE, IS IN OUR FAVOUR.** If - `TRITON_ATTN` is the slower backend — which is what vLLM's own priority - ordering asserts and what nothing here measures — then the denominator + `TRITON_ATTN` is the slower backend — which vLLM's own priority ordering + IMPLIES rather than states, and which nothing here measures — then the + denominator 16.27918250335551 tok/s is too LOW and `0.8016987337853048` is too HIGH. An error that flatters us is the one nobody chases, so it is written down beside the number rather than left to be noticed. **The ratio is not withdrawn and no @@ -2969,18 +2974,31 @@ list items. this exact hazard ("None re-runs backend auto-selection for the draft, which can pick a different attention class than the target; fall back to the target's"), and `gemma4/speculator.py:66-89`. So the DFlash path is the - un-defended case rather than an upstream intent. #1685's reading 1 is - therefore wrong; reading 2 is refuted, because `FlashAttentionImpl.__init__` - logged `Using FlashAttention version 2` at `flash_attn.py:906-914` and an FA - implementation was constructed for those layers; reading 3 is what the artifact - supports. + un-defended case rather than an upstream intent, which makes #1685's reading 1 + wrong AS INTENT — the inference is about intent, drawn from two siblings that + defend against exactly this. Reading 2, "those layers fall back at runtime", is + refuted on two counts: `FlashAttentionImpl.__init__` logged `Using + FlashAttention version 2` at `flash_attn.py:906-914`, so an FA implementation + was CONSTRUCTED for those layers, and the runtime half has no fallback to take + — `flash_attn.py` in the staged wheel contains no `fallback` token at all, and + `FlashAttentionImpl.forward` (line 970) raises `NotImplementedError` rather + than degrading. Reading 3 is what the artifact supports. + + **THE RETRACTION HAS FOUR INHERITING SITES IN THIS TREE, AND THREE OF THEM + CANNOT BE EDITED.** `FA_USABLE` appears in `.agents/benchmark-record.md`, in + this file, and in `.agents/issue-index.md` at the #1456, #1658 and #1685 rows, + each quoting `FA_USABLE=0` as a live constraint. The index is append-only, so + those three stay as written and this entry is where a reader lands instead. A + grep of `.agents/oracles/` and `.agents/upstream-sync.md` for `FA_USABLE`, + `FLASH_ATTN` and `TRITON_ATTN` returns nothing, so no oracle file needs + retracting; the plan in #1456's body to write the constraint into + `.agents/oracles/vllm.md` was never carried out. **WHAT IS STILL NOT PROVEN IS THE KERNEL LAUNCH.** Construction is proven and coherent output is measured on both arms. A trace showing an FA2 kernel enter the SM on this box is not in hand and needs a lease. It is not needed for the retraction, and it IS needed before anybody claims the forward JIT is free. - ## Now **W6 TOOK THE GATES on 2026-08-21, on `dgx:gpu0` through an `rc` lease, and G2 From 51c7cc7e3d6e87213be9271ee1de448ddf96d869 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Sun, 23 Aug 2026 16:27:04 +0000 Subject: [PATCH 3/4] record(SPEC-DFLASH2): the retraction inherits into three files, not four sites of which three are frozen (#1796) The delta review closed four of five findings and opened one: the sentence that repaired a wrong count shipped a second wrong one. "FOUR INHERITING SITES ... AND THREE OF THEM CANNOT BE EDITED" does not reconcile with its own enumeration, which names two files plus three index rows, and it undercounts what is frozen. `.agents/benchmark-record.md:3` self-declares "Append-only forensic record" too, so BOTH the other files are append-only and this spec is the only one of the three that can carry the retraction. O33 now uses the framing the GitHub prose already used and states the measured thing: `grep -rln FA_USABLE . --exclude-dir=.git` returns three files. It also names the un-annotated site, `.agents/benchmark-record.md`'s live "#1685 (new, OPEN)" item, and records that this file's append-only status is a convention rather than a gate, which is #1373's subject. TWO DEPARTURES, ARGUED HERE SO THEY STAY WITH THE DIFF. First, the appended `.agents/issue-index.md` row was EDITED by the two repair commits rather than appended again. `scripts/check-issue-index-append-only.py:45-52` diffs `merge-base(origin/main, HEAD)..HEAD`, so it reads the net effect, and the row has never existed on `main`; the squash lands one clean append. A reader of `git log -p` on this branch will see the row change shape, and that is why this paragraph exists. Second, the same implementer who wrote the findings repaired them. AGENTS.md bars the COORDINATOR from repairing and this session is a helper, not the coordinator, but the same step asks for a FRESH implementer and these were prose-accuracy repairs in a records-only change. The control that protects correctness held: the fresh reviewer re-derived the FA_USABLE enumeration independently before being told, and re-verified each repaired claim on the new head. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [claude-code] --- .agents/specs/dflash2-spec-decode.md | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/.agents/specs/dflash2-spec-decode.md b/.agents/specs/dflash2-spec-decode.md index e876e52b8..26ca47efb 100644 --- a/.agents/specs/dflash2-spec-decode.md +++ b/.agents/specs/dflash2-spec-decode.md @@ -2984,13 +2984,21 @@ list items. `FlashAttentionImpl.forward` (line 970) raises `NotImplementedError` rather than degrading. Reading 3 is what the artifact supports. - **THE RETRACTION HAS FOUR INHERITING SITES IN THIS TREE, AND THREE OF THEM - CANNOT BE EDITED.** `FA_USABLE` appears in `.agents/benchmark-record.md`, in - this file, and in `.agents/issue-index.md` at the #1456, #1658 and #1685 rows, - each quoting `FA_USABLE=0` as a live constraint. The index is append-only, so - those three stay as written and this entry is where a reader lands instead. A - grep of `.agents/oracles/` and `.agents/upstream-sync.md` for `FA_USABLE`, - `FLASH_ATTN` and `TRITON_ATTN` returns nothing, so no oracle file needs + **THE RETRACTION INHERITS INTO THREE FILES, AND THIS IS THE ONLY ONE OF THEM + THAT CAN CARRY IT.** `grep -rln FA_USABLE . --exclude-dir=.git` returns + `.agents/benchmark-record.md`, this file, and `.agents/issue-index.md`. The + index quotes `FA_USABLE=0` as a live constraint in the #1456, #1658 and #1685 + rows, and it is append-only by rule and by + `scripts/check-issue-index-append-only.py`. + `.agents/benchmark-record.md:3` self-declares "Append-only forensic record", + and it carries `FA_USABLE=0` un-annotated inside the live "#1685 (new, OPEN)" + item of the 2026-08-22 entry; note that its append-only status is a convention + rather than a gate, which is the whole subject of + [#1373](https://github.com/mudler/vllm.cpp/issues/1373). So this entry is + where a reader lands instead, and the two append-only sites stay as written. + + A grep of `.agents/oracles/` and `.agents/upstream-sync.md` for `FA_USABLE`, + `FLASH_ATTN` and `TRITON_ATTN` exits 1 with no output, so no oracle file needs retracting; the plan in #1456's body to write the constraint into `.agents/oracles/vllm.md` was never carried out. From 644c021be034a4a4901523b0106a3f09cd91b193 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Sun, 23 Aug 2026 16:32:20 +0000 Subject: [PATCH 4/4] record(SPEC-DFLASH2): the stale benchmark-record item is carried by the next append, not by a lock (#1796) O33 named `.agents/benchmark-record.md`'s live "#1685 (new, OPEN)" item as the site that quotes `FA_USABLE=0` without a pointer to the retraction, and left what happens to it unsaid. It says now. That item is STALE rather than WRONG. It states that `FA-CONSTRAINT.txt` RECORDS `FA_USABLE=0`, which is still true, and it closes "Unresolved.", which has stopped being true. Nothing there needs retracting, so the #1783 precedent of an INSERTED note does not reach it: that precedent exists for a site carrying a transcription error seven other sites inherited. The retraction rides the next `SPEC-DFLASH2` entry appended to that file, which is an append and takes no lock. Annotating in place would take a lock on the one file whose own issue, #1373, says every appending pull request conflicts, purely to add a forward pointer, which is the shape AGENTS.md's Records section names. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [claude-code] --- .agents/specs/dflash2-spec-decode.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.agents/specs/dflash2-spec-decode.md b/.agents/specs/dflash2-spec-decode.md index 26ca47efb..4e1de151b 100644 --- a/.agents/specs/dflash2-spec-decode.md +++ b/.agents/specs/dflash2-spec-decode.md @@ -2996,6 +2996,12 @@ list items. rather than a gate, which is the whole subject of [#1373](https://github.com/mudler/vllm.cpp/issues/1373). So this entry is where a reader lands instead, and the two append-only sites stay as written. + **That `benchmark-record.md` item is STALE rather than wrong** — it says + `FA-CONSTRAINT.txt` RECORDS `FA_USABLE=0`, which is still true, and closes + "Unresolved.", which has stopped being true — so nothing there needs + retracting and the retraction rides the next `SPEC-DFLASH2` entry APPENDED to + that file. Annotating it in place would take a lock on the one file whose own + issue says every appending pull request conflicts, to add a forward pointer. A grep of `.agents/oracles/` and `.agents/upstream-sync.md` for `FA_USABLE`, `FLASH_ATTN` and `TRITON_ATTN` exits 1 with no output, so no oracle file needs