Skip to content

Commit aeba0de

Browse files
mudler's LocalAI [bot]mudler
andauthored
gate(GATE-CONFLICT-MARKERS): refuse a tracked file that carries a merge conflict marker (#1450)
Four record gates return rc 0 on a `docs/STATUS.md` carrying a spliced merge conflict. Each measures its own budget, and none asks whether a merge tool wrote into the file at all, so a keyed row that is half one branch and half another satisfies every budget it is measured against. An earlier revision of #1414's branch carried exactly that file, the full record gate set ran, and it reported clean; a person caught it by reading `git diff --stat`. This adds one tree-scoped checker, in one place rather than four, and wires it where the pre-push record gates already run. ## The rule, and why the separator is conditional A line that starts with seven `<` and a space opens a hunk, and a line that starts with seven `>` and a space closes one. Either fails, anywhere in a tracked text file. A line of exactly seven `=` fails only when a start marker opened a hunk above it. The separator stays conditional because a bare row of `=` is legal markdown: it is the setext heading underline and it is a horizontal rule. Two independent narrowings keep the gate off ordinary text, and both were measured rather than assumed. **Exactly seven:** five shipped files already carry a rule of eight or more `=` (three logs under `docs/bench-evidence/gdn-replayssm-w0-20260818/` and two tokenizer corpora under `tests/parity/goldens/`), so a `^=+` rule would have been red on arrival. **Adjacency:** even a line of exactly seven is silent unless a real marker opened a hunk. The diff3 `|||||||` marker is deliberately absent. A diff3 conflict still carries the start and end markers, so nothing escapes, and a line of seven `|` is a plausible empty row in a repository whose records are wide markdown tables. ## No allowlist, and no per-change registration Every pattern is built by character repetition rather than written as a literal, so the checker and its suite carry no marker at column 0 and need no exemption from the gate they implement. The suite builds its fixtures in temporary git repositories. Nothing in the repository has to register itself with this gate, and no file accumulates a list that every change must append to. AGENTS.md § *Records* forbids that surface: if N concurrent pull requests edit file F, F is a lock. A document that quotes a conflict marker on purpose indents it. That remedy is printed in the failure message, and it is per instance and in the text, not a registry entry. ## RED-BEFORE The defect was re-derived rather than quoted, on a detached scratch worktree at `b537a5344`. Five lines were spliced into the `docs/STATUS.md` capability table: a start marker, a duplicated keyed row, a separator, the same row again, and an end marker. The mutation asserted its own application against the file's sha256 before and after, and `git diff --stat` read `docs/STATUS.md | 5 +++++`. ``` === check-public-doc-tables rc=0 === OK: docs/BENCHMARKS.md and docs/FEATURES.md are human-readable keyed tables, docs/STATUS.md is inside its size ratchet, and .agents/benchmark-record.md carries the append-only record. === check-agent-record rc=0 === agent record OK: ENGINE=168 MODEL=377 QUANT=84 KERNEL=52 BACKEND=85 ANCHOR-ROT=38 === check-doc-checkpoint --base b537a53 --head HEAD rc=0 === OK: public documents match the claims this change makes. === check-issue-index-append-only --base b537a53 --head HEAD rc=0 === OK: issue index append-only ``` The two range-scoped checkers ran over a detached scratch **commit**, not over the working tree. A working-tree mutation of a commit-reading checker returns 0 because the checker never reads the mutated bytes, and that 0 looks exactly like a gate that cannot detect the defect. The suite was written before the checker existed and was seen failing: `Ran 17 tests`, `FAILED (failures=17)`, rc 1. ## GREEN-AFTER Same tree, same splice, the new gate: ``` root: /dev/shm/red-1417 docs/STATUS.md:129: conflict start marker: <<<<<<< HEAD docs/STATUS.md:131: conflict separator inside the hunk opened at line 129: ======= docs/STATUS.md:133: conflict end marker: >>>>>>> origin/main conflict markers: 3 findings in 1 file; examined 3728 tracked text files (1077 binary, 1 symlink, 0 absent skipped, 4806 tracked paths) Resolve the merge before committing. A document that quotes a conflict marker on purpose must indent it, so that it does not start at column 0. rc=1 ``` On the clean tree of this branch: ``` root: /home/mudler/_git/vllm.cpp/.claude/worktrees/fix-1417 conflict markers: 0 findings in 0 files; examined 3733 tracked text files (1077 binary, 1 symlink, 0 absent skipped, 4811 tracked paths) rc=0 ``` **3739 tracked text files examined**, out of 4817 tracked paths: 1077 binary, 1 symlink and 0 absent were skipped, and each class is counted and printed rather than dropped in silence. (It read 3733 of 4811 before the last merge of `main`; both figures are the same run on different trees.) A gate that cannot say how many things it examined has not reported, so an examined count of zero exits 2 instead of printing a clean verdict, and a file the run could not READ exits 2 as well rather than being called clean. The report also names the resolved root, because a checker resolves its root from its own path and a run from a linked worktree can otherwise print OK about the shared checkout. The clean-tree case does not assert a floor. It asserts EQUALITY with git's own tracked text set, derived at read time from `git grep -I --name-only -e ''` plus the tracked files that have no lines at all. Both sides are re-derived on every run, so nothing is stored and nothing drifts; the two agreed byte for byte. The suite: `Ran 21 tests`, `OK`, `cases run: 21`, rc 0. The count is asserted by the runner itself, so a suite that ran zero cases exits 2 rather than printing OK. Cost: 0.29 s of CPU for the whole tree, against 0.9 s before the scan was moved off decoding 142 MB of text to bytes. Wall time on this box ranged 1.17 s to 4.60 s under load from two sibling sessions, which is why the spec's stop condition bounds CPU and not wall. ## The gate is armed, proven by mutation Each mutation was applied in a scratch worktree under `/dev/shm`, never in the reviewed tree. Each asserted that its bytes actually changed, printed the new sha256, compiled the result before running anything, and restored the file byte-identically afterwards. | Mutation | Suite | |---|---| | M1 the detection core deleted (`scan_text` returns nothing) | **RED**, 8 failures | | M2 the separator adjacency guard `open_at is not None` dropped | **RED**, 1 failure | | M3 the examined count deleted from the report | **RED**, 5 failures | | M5 the index dedupe removed (`return names`) | **RED**, 1 failure | | M6 an unreadable file filed as a finding again | **RED**, 1 failure | | M7 the file count split on the first colon again | **RED**, 1 failure | | M4 the whole-buffer reject deleted | GREEN, and expected | Each mutation reds the case that owns it. M1 to M3 were re-run after the refactor, so no earlier commit's mutation proof was silently disarmed by a later one. **M2 is the finding this pull request is most worth reading for.** On the first run it stayed GREEN: the adjacency guard was in the source and no case could tell whether it was there. A file with no marker leaves the scan early, so the guard never decided anything in any fixture, and a new gate carrying a branch no mutation can falsify has the same defect it was added to fix. `test_a_separator_after_the_hunk_closes_is_not_named` was written to close it. It gives a file a closed hunk and then a legal setext underline below it; the exit code is 1 either way, so the case asserts the report, and it carries its own positive control (three named lines) before it claims a fourth is absent. M4 is green on purpose and is recorded as such. The whole-buffer reject is a pure optimization that decides nothing the per-line pass would decide differently, and its docstring says so, so a later reader cannot mistake it for the semantic guard. ## The four existing checkers are unchanged Byte-identical to `origin/main`, verified by sha256 rather than by eye: ``` scripts/check-public-doc-tables.py same=YES scripts/check-agent-record.py same=YES scripts/check-doc-checkpoint.py same=YES scripts/check-issue-index-append-only.py same=YES ``` All four still pass on this tree, tree-scoped and range-scoped, at rc 0. This adds a gate; it alters no existing gate's semantics. ## Repairs from the fresh review The review returned PASS with two LOW findings. Both are repaired here, because both bear on the principle this change elevates. **An unmerged index triple-counted.** `git ls-files` emits stages 1, 2 and 3 for a conflicted path, so during a live merge the checker read one file three times and reported `9 findings in 1 file; examined 3 tracked text files`. The verdict stayed 1, so nothing was ever missed, but the count was wrong in exactly the state the gate exists for, and no fixture built an unmerged index. `tracked_paths` now deduplicates with `dict.fromkeys`, which keeps git's order. `test_an_unmerged_index_is_counted_once` makes `git merge` genuinely fail and asserts the three stage entries before it asserts anything else, so the dedupe is falsifiable rather than merely present. **The clean-tree floor was 27% of the real count.** `> 1000` against a real 3733 would have stayed green over a scan that collapsed to markdown alone. It is now equality with git's own text set, as described above. Three accuracy repairs came with them. An unreadable file was filed as a finding, so an `OSError` exited 1 and printed "Resolve the merge before committing"; it now takes its own list and exits 2, because a file this run could not read is a file it cannot call clean. The summary file count split each report line on its first colon and merged two tracked paths sharing a prefix. And the creation-mutation comments in `check-pr-size.py` claimed the disabled stub fails *every* case that runs the checker: measured, it fails **16 of 21**, and the five survivors assert only that an ordinary document exits 0, or never run the checker at all. The mutation is still detected; the sentence was wrong, and it is corrected in both places. The spec's `## Risks` now records the unmerged index as **not seen** when the spec was written, rather than as a trade-off that was weighed and dropped. ## Where it runs `CHECKERS` in `scripts/agent-preflight.sh`, deliberately first, so a reader who sees it fail knows to stop reading the verdicts below it; `SUITES` for the mutation suite; and a step in the `agent-record` job of `.github/workflows/ci.yml`, so a pull request is gated even when preflight was never run. The workflow was re-parsed with a loader that rejects duplicate mapping keys: 17 jobs, one registered step. PyYAML accepts workflows GitHub rejects, and a duplicate key yields zero jobs. ## One in-flow repair, tracked separately as #1448 Registering a new checker requires an entry in `CREATION_MUTATIONS`, so this change necessarily edits `scripts/check-pr-size.py`, and a change to that file must prove its own HEAD checker/test pair passes. It could not: `test_every_tracked_and_current_change_path_is_classified` sweeps every tracked path, and ten files of `docs/bench-evidence/gdn-replayssm-w0-20260818/` have been unclassified since 2026-08-18, because `BENCH_EVIDENCE` matches exactly one path segment. That suite is RED on `origin/main`, verified in a detached worktree at `9ecaf1bb3`, and it is in no preflight `SUITES` entry, so preflight is green over it. It surfaces only as `ERROR: HEAD checker/test pair failed for 'scripts/check-pr-size.py'`, which reads as a defect in the change under review. Repaired here, per AGENTS.md § *Every change starts from an issue*: a `BENCH_EVIDENCE_RUN` pattern that names the surface rather than widening a rule, restricted to the extensions the directory carries and deliberately excluding `.md` and `.json`, which already classify as `public_document` and would be silently reclassified because the `evidence` arm is tested first. Classification of all 4811 tracked paths was captured before and after: exactly those ten move, and no other path changes class. Issue #1448 tracks it and is not closed by this body's keyword, so it can be closed by hand after review confirms the repair. Fourth instance of that class after #856, #668 and #989. ## Gates All re-run after the last merge of `origin/main` `0adeb8b0e`, so the base is an ancestor of HEAD and the trailer gates EXECUTE rather than skip. - `python3 scripts/check-conflict-markers.py` — rc 0, 3739 files examined. - `python3 tests/scripts/test_check_conflict_markers.py` — rc 0, 21 cases, `OK`. - `python3 scripts/check-agent-record.py` — rc 0, re-run after the merge. - `python3 scripts/check-public-doc-tables.py` — rc 0. - `python3 scripts/check-doc-checkpoint.py --base origin/main --head HEAD` — rc 0. - `python3 scripts/check-issue-index-append-only.py --base origin/main --head HEAD` — rc 0. - `python3 scripts/check-pr-size.py --base origin/main --head HEAD` — rc 0, `OK: every explicit path class is within its review budget.` - `python3 scripts/check-commit-trailers.py --range origin/main..HEAD` — rc 0 over 7 commits, EXECUTED rather than skipped. - `python3 scripts/check-commit-style.py --range origin/main..HEAD` — rc 0, same range. One accounted-for red, and it is not this change's: `test_cpu_x86_llamacpp_floor` reports `NO_QUIET_WINDOW` exit 4 where the case expects 2. That is #618's load dependence, measured on this box at load average 122-129 and later 157-225, driven by sibling agent sessions. This branch touches no benchmark harness, and the same suite re-run on the same sources at load average 2.5 reported `Ran 10 tests`, `OK`, rc 0. The full `scripts/agent-preflight.sh` on this head, after the merge: **85 gates `ok`, ZERO skipped**, and rc 1 for that one suite alone. `commit-trailers` and `commit-style` both read `ok` rather than `SKIP`, which is the point of merging `main` first: a skipped gate reports nothing about the tree, and the harness refuses the green banner over one. `windows-msvc-cpu` and `windows-msvc-vulkan` are red on every pull request (#584, #968) with no `main` baseline. This diff carries no C++. Closes #1417 FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code] --------- Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
1 parent 0adeb8b commit aeba0de

8 files changed

Lines changed: 1078 additions & 0 deletions

File tree

.agents/issue-index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,4 +479,6 @@ rather than merged. `scripts/check-agent-record.py` gates both.
479479
| [#1439](https://github.com/mudler/vllm.cpp/issues/1439) | `LTX25-DEVICE-RESIDENCY` | `ltx2 video: a render through the ABI emits a phase table that SUMS to wall` asserts `CHECK(leaves >= 0.95 * wall)` (`tests/vllm/multimodal/test_ltx2_video.cpp:2854`) and is **RED on `origin/main`**, not on the branch that found it. MEASURED on one x86 box, one build directory, `CMAKE_BUILD_TYPE` empty as CI has it, with this lane's four files reverted so the binary IS main at `89261c955`: six in-suite runs read 94.32%, 95.20%, 93.74%, 94.20%, 94.69% and one `-tc` run 94.19% - **five of six red**, 93 cases / 3321 assertions / 1 failed, exit 1. The W0-live merge reads 93.82%, 93.68%, 94.34%, 94.62%, 94.39% in-suite (96 cases / 3555 assertions / 1 failed) and 94.12% with `VLLM_RENDER_PROGRESS=0`, so neither the new emitter nor its call site is the term; one `-tc` run passed at 95.40%. It is NOT box contention, and the run that disproves that is main's single green: it had `wall=0.579684s`, more than double every other run, because the box was LOADED - a slower render passes, since the un-named residue grows more slowly than the wall it is divided by. The residue is 4.80% to 6.32% of `wall` across all twelve runs (0.0128 s to 0.0278 s against a `wall` of 0.220 s to 0.580 s), so a 95% floor sits INSIDE the measurement's own range at the 64x64 / 9-frame FIXTURE scale and the case decides by coin flip, mostly red. The tolerance was argued for the 21.004 B render, where the same residue would be a far smaller fraction. NOT FIXED IN FLOW, deliberately: naming the un-named time, or bounding `unaccounted_seconds` beside the ratio so the assertion says the same thing at both scales, is a change to a gate's semantics and needs its own row, spec and red-first evidence per `AGENTS.md` "Changing the rules or a checker". Found while merging `origin/main` into `row/LTX25-RESIDENCY-W0-LIVE` after [#1419](https://github.com/mudler/vllm.cpp/pull/1419) was auto-closed by its base branch being deleted. Listed under `## Owed` in [`ltx25-device-residency.md`](specs/ltx25-device-residency.md) | bug |
480480
| [#1435](https://github.com/mudler/vllm.cpp/issues/1435) | `VT-MATMUL-FP8-BLOCK-CUDA` | **A CUDA build without CUTLASS headers segfaults on the block-wise FP8 path instead of refusing by name, and configure reports the feature ENABLED anyway.** Measured 2026-08-20 on `dgx:gpu0` (GB10, cc 12.1) in an `rc` lease at `63d87805c`. `src/vt/cuda/cuda_matmul_fp8_block_cutlass.cu` is the only TU that registers `kMatmulFp8BlockScaled` for `kCUDA` and it reaches `target_sources(vllm PRIVATE ... ${_FP8_CUTLASS_SOURCES})` only through TWO nested conditions in `CMakeLists.txt` -- the outer `if(VLLM_CPP_CUTLASS)` (one occurrence in the file) and, inside it, the `if(VT_CUTLASS_FP8_ARCHS)` that SETS `_FP8_CUTLASS_SOURCES` -- so with no CUTLASS headers the op is unregistered, a device tensor reaches the portable HOST kernel, and the process SIGSEGVs while the reference tier prints `correct but slow`. Anchored by SYMBOL rather than by line on purpose, and the reason is measured on this very row: the guard sat at `CMakeLists.txt:1695@63d87805c` -- the only line number in this row, sha-qualified so it stays resolvable -- and by the time this row was written that number was already stale, then rotted AGAIN by four lines when `origin/main` was merged into the row's own branch mid-review. Two rots inside one pull request. A bare head-relative number here would be permanent, because this index is append-only and no checker scans it, and it would resolve to plausible unrelated code rather than to nothing: at `63d87805c` that line was the guard, and two trees later it was an NCCL include directory. Resolve the anchors above by grepping the symbols; do not trust any number quoted for them. Reachable on a default build: `VLLM_CPP_CUTLASS_FETCH` defaults OFF (the single `option(VLLM_CPP_CUTLASS_FETCH ...)` line, `OFF` at its default argument) and CUTLASS is not a submodule. This contradicts the design note in `cuda_matmul_fp8_block_cutlass.cu`, which states an unsupported build `keeps refusing by name -- which is the honest answer and not the #960/#844 fall-through`: the refusal IS real on the model path (`RefuseUnrunnableQwen3_5DenseFp8Block`, plus the two `VT_CHECK`s) but a caller entering through the op registry, which is what the ported upstream test does, bypasses all three. Second, smaller defect in the same run: `vt_cuda_report_feature` printed `CUDA feature cutlass-fp8: ENABLED for [121a]` for a build whose `build.ninja` contains ZERO references to either FP8 CUTLASS TU, because the report runs on the arch intersection alone, before CUTLASS-header detection. `cmake/CudaArchFeatures.cmake` opens by naming this exact class as what the feature table exists to prevent. NOT fixed in flow: both are code changes on a CUDA path needing their own row, spec and hardware re-gate. Owned by row `VT-MATMUL-FP8-BLOCK-CUDA`, under `## Owed` in [`vt-matmul-fp8-block-cuda.md`](specs/vt-matmul-fp8-block-cuda.md) | bug |
481481
| [#1437](https://github.com/mudler/vllm.cpp/issues/1437) | `VT-MATMUL-FP8-BLOCK-CUDA` | **The mainloop-scaled CUTLASS block-wise FP8 GEMM throws `cutlass Invalid status` on upstream's own ported case, on the arch it targets.** FIRST on-hardware execution of #1189 M5 (`489a9a4c0`), measured 2026-08-20 on `dgx:gpu0` (GB10, driver 580.173.02, compute capability 12.1) in an `rc` lease at `63d87805c`, CUDA 13.0 Release, `-DVLLM_CPP_CUDA_ARCHITECTURES=121a -DVLLM_CPP_CUTLASS_FETCH=ON`. G2 (upstream's `test_w8a8_block_fp8_cutlass_matmul` ported whole: M=32, N=576, K=7168, block [128,128], bf16 out) and G7 both THROW from `gemm_op.can_implement(args)`, so CUTLASS rejects the configuration before any launch -- not a numerical disagreement and not a launch failure. G6, G8 and G9 PASS. That this was an EXECUTION and not a skip rests on the throw TEXT, not on a count: `vt cuda: matmul_fp8_block_scaled: cutlass Invalid status` is assembled by the `VT_CUTLASS_CHECK` macro in `src/vt/cuda/cuda_matmul_fp8_block_cutlass.cu`, and the message prefix `matmul_fp8_block_scaled: cutlass ` occurs in NO other translation unit (the per-tensor sibling `cuda_matmul_fp8_cutlass.cu` defines a same-named macro but writes a different message), in a TU compiled only when CUTLASS is found, so no host fallback can produce that string; the run also logged ZERO `[vt reference-tier]` lines, and artifact provenance was confirmed by `cuobjdump --list-elf` reporting `cuda_matmul_fp8_block_cutlass.cu.1.sm_121a.cubin`. Suite: 5 cases, 3 passed, 2 failed, **34 assertions, 0 failed** -- recorded, but attributed rather than leaned on, because **27** of the 34 are G6, which has no `HasCuda()` guard and prints identically on a GPU-less box (8 grid entries x 3 `CHECK` + 3 tile-config `CHECK`s); the device-only remainder is G8's 2 and G9's 5, and a pure skip of this file prints 27. NO shape has had its output compared with the CPU reference: G2 and G7 are the only two cases that make that comparison and BOTH threw before their first assertion -- G7 aborted at `Grid()[0]`, the same M=32 N=576 K=7168 case, so its other seven shapes, including the second ragged-N entry M=8 N=576 K=1024, were never attempted -- and G8 compares a device f32 out against a device bf16 out, which is the kernel against ITSELF. Hypothesis recorded in the issue and explicitly NOT isolated: N=576 is 4*128+64, a ragged final scale block, which the test header records as upstream's reason for choosing it; G8 passing makes the failure shape-dependent rather than universal. This moves the row from `unmeasured` to `measured and failing`, a worse position than the spec previously described. NO speed claim: the lease took no clock control and recorded no contention. Owned by row `VT-MATMUL-FP8-BLOCK-CUDA`, under `## Owed` in [`vt-matmul-fp8-block-cuda.md`](specs/vt-matmul-fp8-block-cuda.md) | measurement |
482+
| [#1417](https://github.com/mudler/vllm.cpp/issues/1417) | `GATE-CONFLICT-MARKERS` | **Four record gates return rc 0 on a document carrying literal conflict markers.** Re-derived on a detached scratch worktree at `b537a5344`: five lines spliced into the `docs/STATUS.md` capability table (start marker, a duplicated keyed row, separator, the same row again, end marker) leave `scripts/check-public-doc-tables.py`, `scripts/check-agent-record.py`, `scripts/check-doc-checkpoint.py` and `scripts/check-issue-index-append-only.py` all at rc 0 with their normal OK messages. The two range-scoped checkers were run over a scratch COMMIT, because a working-tree mutation of a commit-reading checker returns 0 without ever reading the mutated bytes. Closed by one tree-scoped checker, `scripts/check-conflict-markers.py`, wired into `scripts/agent-preflight.sh` and the `agent-record` CI job: it refuses a line that starts with seven `<` or seven `>` and a space, and a line of exactly seven `=` only when a start marker opened a hunk above it. The separator stays conditional because a bare row of `=` is a legal setext heading underline, and five shipped files already carry lines of eight or more `=`. No allowlist: the checker builds its patterns from character repetition, so it and its suite carry no marker at column 0. Spec [gate-conflict-markers.md](specs/gate-conflict-markers.md) | bug |
483+
| [#1448](https://github.com/mudler/vllm.cpp/issues/1448) | `GATE-CONFLICT-MARKERS` | **`scripts/check-pr-size.py`'s `classify_path` has no entry for a per-run `docs/bench-evidence/<run-id>/<file>` directory, so its own suite is red on `main`.** `BENCH_EVIDENCE` matches exactly one path segment, and the ten files of `docs/bench-evidence/gdn-replayssm-w0-20260818/` (landed 2026-08-18) match none of it. Measured at `9ecaf1bb3`: sweeping every tracked path through `classify_path` leaves exactly 10 unclassified, and `test_every_tracked_and_current_change_path_is_classified` is RED in a detached worktree at that SHA. That suite is in no preflight `SUITES` entry, so preflight is green over it; it surfaces only through the checker-evidence contract, where it reads as `ERROR: HEAD checker/test pair failed for 'scripts/check-pr-size.py'` and looks like a defect in the change under review. Registering any NEW checker requires editing `CREATION_MUTATIONS`, so every future checker was blocked behind it. Fourth instance after [#856](https://github.com/mudler/vllm.cpp/issues/856), [#668](https://github.com/mudler/vllm.cpp/issues/668) and [#989](https://github.com/mudler/vllm.cpp/issues/989). FIXED in flow by a `BENCH_EVIDENCE_RUN` pattern restricted to the extensions the directory carries, excluding `.md` and `.json` because the `evidence` arm is tested before `public_document` and would silently reclassify `docs/bench-evidence/mxfp4-qwen/*`. Verified to move exactly those 10 paths and no others | bug |
482484
| [#1447](https://github.com/mudler/vllm.cpp/issues/1447) | `ENG-EXPERT-STREAM` | **`docs/USAGE.md` said EVERY Qwen3.8 decode figure came from the W0e C ABI harness; the 66.7 s/token streaming-off row of 16 August 2026 came from `vllm-server`, the same binary the section tells the reader to run.** Introduced by #1211 and fixed in the same flow: the sentence is scoped to the W0e and W0f runs and the exception is named, in `docs/USAGE.md` and in the spec paragraph that mirrors it. Provenance read at the source, `.agents/specs/expert-streaming.md:837` (server entry point) and `:905`. | record |

0 commit comments

Comments
 (0)