From cbcbc2af285d14d15199711cbf23ecc0a7c3c365 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Thu, 20 Aug 2026 23:30:16 +0000 Subject: [PATCH] fix(#1520): the quickstart page is a landing source, so a README that SHRINKS into a pointer can land `check-doc-checkpoint` refuses a `README.md` claim change that touches no member of `LANDING_SOURCE_FILES`. The set names `.agents/mission.md`, `CMakeLists.txt`, three `benchmarks/demo/*.json` files and the two example mains, and it has no entry for a document that owns the start of a reader's path. The gate's own message names the two failures it exists to stop: > The README is the landing page. Routine checkpoints belong in the > purpose-specific docs. Co-edited public projections never justify README > churn. Both are a README that GROWS. `row/DOCS-QUICKSTART-1281` is the opposite. It adds `docs/QUICKSTART.md` and cuts the README `## Quickstart` block from three command fences to a four-line pointer at that page, so the README loses material and the material moves to the purpose-specific document. At head `1b6e458c8` that branch reports 88 gates ok, zero skips and one failure, `doc-checkpoint range`, while touching no member of the set, which it honestly should not, because nothing in `.agents/mission.md` became untrue. Add `docs/QUICKSTART.md` to the set. Every existing member is something the README quotes: the mission it paraphrases, the build entry point its build line invokes, the demo measurements its numbers come from, and the two example mains its commands run. The quickstart page is that relation with the direction made explicit. The README's claim about where a reader starts changed BECAUSE the page now exists and now owns the starting procedure, and the page is a source rather than a projection, because nothing else in the tree records what it says. This admits one exact path and no class. `docs/BUILD.md`, `docs/ROCM.md`, `docs/RELEASES.md` and every public projection still cannot license a README claim change, and `landing_page` still permits a README edit rather than demanding one. Three cases in `tests/scripts/test_doc_checkpoint.py` state that: the new one was RED before this change with the exact `landing source` refusal, and the two guards were green before and after. Three mutations red them one at a time, and the checker at `origin/main` refuses `d69a43c51` while the checker here accepts it. Deliberately its own change. The previous implementer on the quickstart row refused to widen the set inside the change it unblocks, because AGENTS.md names making a red gate green that way as the forbidden move. That refusal was correct, so the widening is made here with its own spec, its own red-first evidence and its own mutations. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: Claude:Opus-5 [Claude Code] --- .agents/issue-index.md | 1 + ...oc-checkpoint-landing-source-quickstart.md | 151 ++++++++++++++++++ scripts/check-doc-checkpoint.py | 13 ++ tests/scripts/test_doc_checkpoint.py | 29 ++++ 4 files changed, 194 insertions(+) create mode 100644 .agents/specs/doc-checkpoint-landing-source-quickstart.md diff --git a/.agents/issue-index.md b/.agents/issue-index.md index ea880ad4a..563cfc753 100644 --- a/.agents/issue-index.md +++ b/.agents/issue-index.md @@ -507,3 +507,4 @@ rather than merged. `scripts/check-agent-record.py` gates both. | [#1474](https://github.com/mudler/vllm.cpp/issues/1474) | `VT-CONV1D-F32-ACC` | `vt::Conv1d` and `vt::ConvTranspose1d` accumulate every output cell in **f64** against a reference that accumulates **f32**, and the provenance recorded for that width is wrong in two independent ways. **vLLM owns no such op** at the parity pin `555967922` — no `Conv1dLayer`, no `ConvTranspose*Layer`, and the only `ConvTranspose` string in the tree names `torch.nn` classes inside an NVTX annotation hook (`vllm/utils/nvtx_pytorch_hooks.py:47-49`); vLLM deliberately drops the vocoder it would otherwise own (`qwen3_omni_moe_thinker.py:1975`, `skip_prefixes=["talker.", "code2wav."]`), and where it DOES own a convolution it states this polarity itself (`csrc/cpu/mamba_kernels.hpp` — `// Accumulate in float32 for precision`). So the reference is torch, and torch was MEASURED rather than read: a 27-tap `[+1e8, 0.1 x 25, -1e8]` probe over a uniform input, where an f32 accumulator lands on exactly `0.0` in ANY order and an f64 one on ~2.5, returns **0.0** for `F.conv1d` at f32 AND at bf16, **0.0** for `F.conv_transpose1d` at f32, and 2.4999998510 at f64 (torch 2.11.0+cu130). **The recorded justification fails twice.** `.agents/specs/minimax-music3.md` §13.2 and §18.3 say f64 "is what every committed golden for all four consumers was taken with", but all three generators run torch in f32 — `gen-bigvgan-goldens.py:48` builds f64 then `.float()`, `gen-ltx2-vae-goldens.py:223,234` and `gen-minimax-music3-acoustic-goldens.py:81,134` cast every parameter and input with `astype(np.float32)` — so the goldens are the output of an **f32-accumulating** reference and the f64 arm has been wider than its own oracle since the op landed. And `include/vt/ops.h` clause (1) cites "every committed golden under `tests/parity/goldens/`", a directory whose 101 entries contain **no** vocoder, BigVGAN, LTX-2.5 VAE, FVQ or general-conv1d golden at all; those live in `tests/vllm/models/*_goldens.inc`. An uncheckable citation is how the first claim survived. **The precedent is landed inside one of the same models**: [#1008](https://github.com/mudler/vllm.cpp/issues/1008) narrowed LTX-2.5's conv VIDEO VAE f64->f32 on this exact argument (`d1b0ea3a8`, [PR #1036](https://github.com/mudler/vllm.cpp/pull/1036)), leaving LTX-2.5 shipping f32 video decode and f64 audio decode in ONE model. The measured risk is the summation ORDER, not the width: in #1008 naive-serial f32 pushed one arm to 5.00679e-06 against a 5e-06 tolerance, repaired by per-input-channel BLOCKED partials — which is what torch's blocked-GEMM convolution does and what `vt::Conv3d` already declares as its contract. Spec [`vt-conv1d-f32-accumulator.md`](specs/vt-conv1d-f32-accumulator.md); corrects both false records in the same flow | bug | | [#1501](https://github.com/mudler/vllm.cpp/issues/1501) | `SPEC-DFLASH2` | **The row recorded DFlash2's T>0 walk as "inverse CDF" from its opening brief; upstream draws GUMBEL-MAX at BOTH pull-request heads it has cited.** `.agents/specs/dflash2-spec-decode.md` `## Upstream chain` mechanism 2 said "At T>0 the walk is by inverse CDF and returns q over the K candidates", and the `SPEC-DFLASH2` engine-matrix row said the same. At `19c9351904df4c63042671bc67a866ca48dc7d6f` the non-greedy branch of `_selector_walk_kernel` drew `uniform = tl_rand32(gumbel_seed, candidates, includes_zero=False)`, `noise = -tl.log(-tldevice.log1p(-uniform))` and took the argmax of `scores / temperature + noise` — Gumbel-max; at `66e5414c6d75a8529473d977f7458c140bbab8a0` that branch is replaced by one call to `gumbel_noised_argmax`, the same draw. No inverse-CDF walk exists upstream. BLAST RADIUS is a mis-scoped wave rather than a shipped defect: W4 ships the GREEDY arm, which is byte-for-byte upstream's `SAMPLE_PROBABILISTIC=False` arm, and the noised arm is not ported (`ParseSpeculativeConfigJson` refuses `draft_sample_method: "probabilistic"` by name against an accept-iff-equal verify) — but an implementer scoped to write an inverse-CDF walk would have written the wrong algorithm with no oracle to catch it, because the acceptance gate that would notice is itself owed. FIXED IN THE SAME FLOW by W4: both records corrected in place rather than annotated, `## Risks/decisions` D13 records why the noised arm is unreachable here, and `## Owed` O12 records its layout and the Triton Philox stream (`tl.randint4x`, Philox 4x32-10, keyed by the candidate token ids) a bit-parity port would need. Also corrected there: the six-item enumeration of the speculator head move was verified item by item against the two blobs and is correct, but it was missing a SEVENTH change in the base class (`DraftModelSpeculator.__init__` now calls a virtual `draft_logits_spec`) and the `+24 / -6` file it lives in was absent from the delta table. Listed under `## Risks/decisions` D13 in [dflash2-spec-decode.md](specs/dflash2-spec-decode.md) | bug | | [#1490](https://github.com/mudler/vllm.cpp/issues/1490) | `VT-MATMUL-FP8-BLOCK-CUDA` | **`tests/vt/test_ops_matmul_fp8_block_cuda.cpp` asserted in six places that it has never run against a device, and the loudest is its own header.** The suite ran UNPATCHED on `dgx:gpu0` (NVIDIA GB10, driver 580.173.02, compute capability 12.1) in an `rc` lease on 2026-08-20, at tree `7481a2eecbb26b3d5c977e8707b0384994caf136` — an ancestor of `main` — reporting `5 cases / 136 assertions / 0 failed`, `REFERENCE_TIER_LINES=0` and `TEST_RC=0`, against a device-free baseline of 41; recorded in `5870cb2bf` (PR [#1472](https://github.com/mudler/vllm.cpp/pull/1472)) and confirmed in [#1437](https://github.com/mudler/vllm.cpp/issues/1437). The header opened "THIS FILE HAS NEVER RUN AGAINST A DEVICE" and added that "no number produced here appears in any document as a measurement" — doubly false, because the 5/136/0 result appears in both the public documentation (`docs/USAGE.md` at the time, `docs/models/qwen3-8-27b.md` after [#1491](https://github.com/mudler/vllm.cpp/pull/1491) moved it) and the row's spec. The other five were G2's comment block and the four `NO CUDA DEVICE ... #1189 M5's on-hardware leg is OWED, not passed` `MESSAGE` strings in G2, G7, G8 and G9. The four messages are CORRECT in what they do — on a device-free host the case genuinely did not run, and a skip is not a pass — so the repair is that they say the case did not run HERE and name where the on-hardware result is recorded, not that they are deleted or weakened. Three caveats survive unweakened: NO token gate ([#1189](https://github.com/mudler/vllm.cpp/issues/1189) still owns `Qwen/Qwen3.8-27B-FP8` against the pinned oracle), NO speed claim of any kind, and correctness established on the SEVEN shapes actually run rather than on a class; DSV3's `kv_a_proj_with_mqa` `N=576` capability gap stands as a CUTLASS sm120 limitation. Same class as [#1396](https://github.com/mudler/vllm.cpp/issues/1396) and [#1411](https://github.com/mudler/vllm.cpp/issues/1411), which cover other anchors of the same row; no checker here compares a comment against the measurement it annotates. Listed under `## Owed` in [`vt-matmul-fp8-block-cuda.md`](specs/vt-matmul-fp8-block-cuda.md) | bug | +| [#1520](https://github.com/mudler/vllm.cpp/issues/1520) | `ROAD-V1-QUICKSTART` | **`check-doc-checkpoint`'s `LANDING_SOURCE_FILES` has no entry for the page the README hands its quickstart to, so shrinking `README.md` into a pointer is refused.** The gate refuses a README claim change that touches no landing source, and the set names `.agents/mission.md`, `CMakeLists.txt`, three `benchmarks/demo/*.json` files and the two example mains. Its message names two failures, "routine checkpoints belong in the purpose-specific docs" and "co-edited public projections never justify README churn", and both are a README that GROWS. `row/DOCS-QUICKSTART-1281` is the opposite: it adds `docs/QUICKSTART.md` and cuts the README `## Quickstart` block from three command fences to a four-line pointer, so the README loses material to the purpose-specific document. At head `1b6e458c8` `scripts/agent-preflight.sh` reports 88 gates ok, zero skips and one failure, `doc-checkpoint range`, on a branch that honestly touches no member of the set. FIXED HERE by adding `docs/QUICKSTART.md` to `LANDING_SOURCE_FILES`, on its own branch with its own spec, red-first case and three mutations, because the previous implementer on the quickstart row correctly refused to widen the set inside the change it unblocks. The widening admits ONE exact path and no class: `docs/BUILD.md`, `docs/STATUS.md` and every other page still cannot license a README claim change, and `landing_page` still permits a README edit rather than demanding one. Spec [doc-checkpoint-landing-source-quickstart.md](specs/doc-checkpoint-landing-source-quickstart.md). | bug | diff --git a/.agents/specs/doc-checkpoint-landing-source-quickstart.md b/.agents/specs/doc-checkpoint-landing-source-quickstart.md new file mode 100644 index 000000000..df8c5105b --- /dev/null +++ b/.agents/specs/doc-checkpoint-landing-source-quickstart.md @@ -0,0 +1,151 @@ +# doc-checkpoint: the quickstart page is a landing source + +Issue: [#1520](https://github.com/mudler/vllm.cpp/issues/1520) +Row: `ROAD-V1-QUICKSTART`. This change exists to unblock that row, and it lands +on its own branch, with its own gate evidence, ahead of it. It is a checker +semantics repair and not a roadmap item of its own. + +## Now + +`IMPLEMENTING`. The one-line widening, its three tests, and the mutation +evidence are on `row/FIX-DOC-CHECKPOINT-LANDING-SOURCE`. The gate evidence below +is captured on that branch. + +## Scope + +`scripts/check-doc-checkpoint.py` refuses a `README.md` claim change that does +not also touch a member of `LANDING_SOURCE_FILES`. The set names +`.agents/mission.md`, `CMakeLists.txt`, three `benchmarks/demo/*.json` files, +and the two example mains. + +In scope: add `docs/QUICKSTART.md` to that set. + +Out of scope, and deliberately not changed here: + +- `claims_changed`. The alternative repair distinguishes README growth from + README shrinkage. This change does not attempt it. See `## Why` for the + reason. +- Every other document. No prefix and no class is admitted. One exact path + joins the set. +- The `landing_page` class semantics. It continues to permit a `README.md` + change and never to demand one. +- `USER_USAGE_FILES` and `FEATURE_SURFACE_FILES`, which are untouched. + +## Why + +The gate's message states the rule it protects: + +> The README is the landing page. Routine checkpoints belong in the +> purpose-specific docs. Co-edited public projections never justify README +> churn. + +Both named failures are a README that grows to say something a purpose-specific +document already says. `row/DOCS-QUICKSTART-1281` is the opposite. It adds +`docs/QUICKSTART.md` and cuts the README `## Quickstart` block from three +command fences to a four-line pointer at that page. The README loses material, +and the material moves to the purpose-specific document. The gate reds on the +discipline its own message argues for. + +Measured at head `1b6e458c8` of that branch: `scripts/agent-preflight.sh` +reports 88 gates ok, zero skips, and one failure, `doc-checkpoint range`. The +branch touches no member of `LANDING_SOURCE_FILES`, and it honestly should not, +because nothing in `.agents/mission.md` became untrue. + +The widening is narrow and it has a direction. Every existing member of the set +is something the README quotes: the mission statement it paraphrases, the build +entry point its build line invokes, the demo measurements its numbers come from, +and the two example mains its commands run. `docs/QUICKSTART.md` is the same +relation with the direction made explicit. The README's claim about where a +reader starts changed because that page now exists and now owns the starting +procedure. The page is a source and not a projection. Nothing else in the tree +records what it says, and the README defers to it rather than duplicating it. + +This is why the set is the right place for the repair. The rule is "a README +claim needs an underlying source", and the quickstart page is one. The two +alternatives are worse: + +- Teaching `claims_changed` to allow a shrinking README treats size as a proxy + for honesty. A README can also shrink by deleting a claim that is true and + load-bearing, so the proxy admits a change the rule exists to catch, and it + makes a general function answer a question about one document. +- Accepting that the landing page cannot point at the landing document drops + half of `ROAD-V1-QUICKSTART` to satisfy a gate, which inverts the relation + between the record and the work. + +The previous implementer on `row/DOCS-QUICKSTART-1281` refused to widen the set +inside its own change, because `AGENTS.md` names making a red gate green that +way as the forbidden move. That refusal was correct, and this spec exists so the +same edit is made deliberately, with its argument and its evidence, instead of +as a convenience inside the change it unblocks. + +## Design + +One entry added to `LANDING_SOURCE_FILES`, with a comment beside it that records +the date, the issue, the relation that admits it, and the class it does not +admit. No function changes. `classify()` already turns a member of the set into +the `landing_page` class, and `errors_for()` already treats that class as +permission rather than obligation, so the entry needs no other code. + +Polarity, stated because it is the risk: this WIDENS a gate. A change that +edits `docs/QUICKSTART.md` may now also make any `README.md` claim change, +including one that grows the README. That is the same permission every existing +member of the set already carries, and it is the permission the set is for. + +## Risks + +- **The permission is not scoped to the quickstart claim.** A change touching + the quickstart page can rewrite any part of the README. Accepted, because it + is the shape of the whole set and narrowing it needs a claim-level model of + the README that no part of this checker has. Recorded under `## Owed`. +- **The entry is an exact path with no existence check.** If the page is + renamed or removed, the entry goes stale silently and the README loses its + permission with no message that says why. Accepted for now, because the same + is already true of all seven existing members, and a path-existence assertion + over the set is a separate change with its own red-first evidence. Recorded + under `## Owed`. +- **The page does not exist on `main` yet.** It arrives with + `row/DOCS-QUICKSTART-1281`. Until then the entry matches no changed path and + the gate behaves exactly as it does today. This is deliberate. The gate repair + lands first so the row it unblocks does not have to carry it. + +## Tests + +`tests/scripts/test_doc_checkpoint.py`, in `SupportSurfaces`: + +1. `test_the_quickstart_page_is_a_landing_source`. `README.md` plus + `docs/QUICKSTART.md` is accepted. **RED before** the change, with the exact + `landing source` refusal. +2. `test_the_quickstart_page_permits_but_does_not_demand_readme`. + `docs/QUICKSTART.md` on its own owes nothing. Green before and after. It pins + that the entry adds permission and not an obligation. +3. `test_an_unrelated_document_never_licenses_readme_churn`. `README.md` plus + `docs/BUILD.md`, `docs/ROCM.md` or `docs/RELEASES.md` is still refused. Green + before and after. This is the property the change must not break, and it + states it on ordinary documents, which is the class the quickstart page + belongs to by path. The existing + `test_a_coedited_projection_never_licenses_readme_churn` states the same + property on a public projection and is also untouched. + +## Gates + +- `python3 tests/scripts/test_doc_checkpoint.py` +- `python3 scripts/check-doc-checkpoint.py --commit ` on this branch +- `scripts/agent-preflight.sh` and `scripts/agent-preflight.sh --staged` +- `documentation-checkpoint` and `agent-record` in CI + +## Owed + +- The permission is document-wide and not claim-scoped. Any landing source + licenses any README claim change. Owned by this row, and the set has carried + the property since it was written. +- No gate asserts that every member of `LANDING_SOURCE_FILES` names a path that + exists. A renamed or deleted member fails silently toward refusing a README + change. Owned by this row. + +## Stop conditions + +Stop and report if adding the entry turns any existing test in +`tests/scripts/test_doc_checkpoint.py` green by absence rather than by intent, +or if a case proving that an unrelated document cannot license README churn +stops failing under mutation. Either result means the set is the wrong place for +the repair and the trigger needs a claim-level model instead. diff --git a/scripts/check-doc-checkpoint.py b/scripts/check-doc-checkpoint.py index 36501d7a3..40b071703 100755 --- a/scripts/check-doc-checkpoint.py +++ b/scripts/check-doc-checkpoint.py @@ -106,6 +106,18 @@ # README permission and obligation come only from underlying landing sources. # Co-edited public projections can NEVER justify README churn -- that rule is # deliberate and directly tested. +# +# docs/QUICKSTART.md joined the set on 2026-08-20 (#1520). Every other member is +# something the README QUOTES: the mission, the build entry point, the demo +# numbers, the two example mains. The quickstart page is the same relation with +# the direction made explicit -- the README `## Quickstart` block stopped +# carrying the commands and now points at that page, so the claim "this is where +# a reader starts" changed BECAUSE the page exists. It is a source, not a +# projection: nothing else records what it says, and the README defers to it. +# +# This admits exactly one document and no class. docs/BUILD.md, docs/STATUS.md +# and every other page under docs/ still cannot license a README claim change, +# which tests/scripts/test_doc_checkpoint.py pins directly. LANDING_SOURCE_FILES = frozenset( { ".agents/mission.md", @@ -113,6 +125,7 @@ "benchmarks/demo/footprint_gb10.json", "benchmarks/demo/qwen36_27b_c1_c32.json", "benchmarks/demo/vulkan_27b_llamacpp.json", + "docs/QUICKSTART.md", "examples/cli/main.cpp", "examples/server/main.cpp", } diff --git a/tests/scripts/test_doc_checkpoint.py b/tests/scripts/test_doc_checkpoint.py index 8971cb378..7cd0811f1 100755 --- a/tests/scripts/test_doc_checkpoint.py +++ b/tests/scripts/test_doc_checkpoint.py @@ -393,6 +393,35 @@ def test_a_link_repair_is_not_a_claim(self): def test_a_landing_source_permits_but_does_not_demand_readme(self): self.assertEqual(self.errors([".agents/mission.md"]), []) + def test_the_quickstart_page_is_a_landing_source(self): + """#1520: the page the README now defers to for starting a model. + + The README `## Quickstart` block used to carry the commands. It now + points at `docs/QUICKSTART.md`, so the claim "this is where a reader + starts" changed BECAUSE that page exists. The page is not a projection + of a claim recorded elsewhere, so a change to it is a real reason for + the README pointer at it to change. + """ + self.assertEqual(self.errors(["README.md", "docs/QUICKSTART.md"]), []) + + def test_the_quickstart_page_permits_but_does_not_demand_readme(self): + """`landing_page` never demands the README, and #1520 does not add one.""" + self.assertEqual(self.errors(["docs/QUICKSTART.md"]), []) + + def test_an_unrelated_document_never_licenses_readme_churn(self): + """The property #1520 must not break, stated on a NON-projection doc. + + `test_a_coedited_projection_never_licenses_readme_churn` covers a public + projection. This covers an ordinary document under `docs/`, which is the + class the quickstart page belongs to by path. Exactly one member of that + class is a landing source, and admitting it must not admit the class. + """ + for document in ("docs/BUILD.md", "docs/ROCM.md", "docs/RELEASES.md"): + with self.subTest(document=document): + errors = self.errors(["README.md", document]) + self.assertTrue(errors) + self.assertIn("landing source", errors[0]) +