Skip to content
1 change: 1 addition & 0 deletions .agents/issue-index.md
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ rather than merged. `scripts/check-agent-record.py` gates both.
| [#1516](https://github.com/mudler/vllm.cpp/issues/1516) | `MODEL-MUSIC-minimax-music3-mini-max-music3-for-conditional-generation` | **The two-binary A/B guard `.agents/specs/minimax-music3.md` §16.6a drew from a VOID pair is unfalsifiable for an end-to-end pair.** `examples/CMakeLists.txt:425-426` links `minimax-music3-gen` against the SHARED `vllm::shared` (`CMakeLists.txt:2633`), so the timed program is a **72 744-byte ABI client** and the change under test lives in `libvllm_shared.so`, which no arm hashes. No `CMAKE_SKIP_BUILD_RPATH` is set, so two build directories put two RPATH strings into the client and the hashes differ whatever the source says — measured on `rc` job `c206ec87`, two clones, both files 72 744 bytes, different sha256. §16.6b reads exactly this as "the precondition this section exists to insist on"; its result stands on its BEHAVIOURAL control (`ar.depth_forward` 1414 -> 808 calls) and not on the hash. `scripts/music3-vocoder-conv-ab.sh` is unaffected: `CMakeLists.txt:2578-2579` links the STATIC `vllm`. | bug |
| [#1531](https://github.com/mudler/vllm.cpp/issues/1531) | `ENG-HF-MODEL-DOWNLOAD` | **Both sanitizer lanes died at LINK on every branch based after `a50c57d69`, so neither reported anything about the code.** `vllm_sanitize_test_shared` forwards `vllm`'s INTERFACE include directories, system include directories and compile definitions, and never forwarded its INTERFACE link libraries. Once W5 put `CPPHTTPLIB_OPENSSL_SUPPORT` on `vllm` PUBLIC, that forwarded define reached every test including the vendored httplib header while `OpenSSL::SSL` did not, and the only libssl near the link line was a `DT_NEEDED` of the shim, which GNU ld refuses to resolve through (`DSO missing from command line`). Eight targets: `test_minimax_music3_e2e_real`, `test_tls_transport`, `test_hf_hub`, `test_model_resolver`, `test_downloader`, `test_serve_hf_model`, `test_openai_conformance`, `test_openai_api_server`. Sanitizer configurations only -- the default build links `vllm::vllm`, whose PUBLIC OpenSSL propagates normally. Fixed in flow by forwarding `INTERFACE_LINK_LIBRARIES` beside the other three forwards | bug |
| [#1535](https://github.com/mudler/vllm.cpp/issues/1535) | `SERVE-C-ABI` | **The C ABI version script is ELF-only, so the Apple leg has no equivalent guarantee.** `cmake/vllm_export.map` (`global: vllm_*; local: *;`) makes every httplib symbol inside `libvllm.so` local, which is what keeps `examples/video_studio/main.cpp` safe BY CONSTRUCTION even though it links `vllm::shared` (PRIVATE `vllm`, so no `CPPHTTPLIB_OPENSSL_SUPPORT`) and compiles the vendored header in the no-TLS layout while the library holds the TLS layout. The script is applied under `if(UNIX AND NOT APPLE)` (`CMakeLists.txt:2661`) because ld64 has no `--version-script`, so on macOS the dylib exports its C++ internals and whether Mach-O weak-def coalescing can bind the two layouts together is UNMEASURED. `capi_shared_exports_only_abi` is gated on the same condition and does not cover it. Low severity, no macOS host here; found while fixing [#1531](https://github.com/mudler/vllm.cpp/issues/1531) | bug |
| [#1559](https://github.com/mudler/vllm.cpp/issues/1559) | `LTX25-DEVICE-RESIDENCY` | **The span-slack bound [#1503](https://github.com/mudler/vllm.cpp/pull/1503) landed to un-red `build-test-cpu` reds that lane itself, on an unmutated tree, and its per-record multiplier is read from the artifact under test.** `CheckCarryingPhase`'s assertion (1c) in `tests/vllm/multimodal/test_ltx2_video.cpp` asserted `span_slack <= min(kSpanSlackPerRecord * leaves.size(), 0.5 * leaf_seconds)`. Measured at `6b48edb2c` on x86_64 with `CMAKE_BUILD_TYPE` empty exactly as the lane configures it, one binary, one build directory, no mutation of any kind: **five of 53 runs RED** — three of 33 on the box as shared (loadavg 79.7-118.0), two of 10 under an added eight-way spin load (loadavg 91.7-145.9), zero of 10 pinned to two cores with `taskset` (loadavg 84.5-105.6); 424 leaf checks and 636 leaf-record observations. The reds are `decode.video` r2 at 1.161 ms over 0.75 ms, `artifacts.frames` r2 at 1.387 ms over 0.50 ms, `decode.audio` r1 at **10.032 ms** over 0.25 ms and `denoise` r2 twice at 0.410 ms and 0.963 ms over 0.25 ms. **F1: the constant sat inside its own honest distribution, and recalibration alone could not fix it**, because the `0.5 * leaf_seconds` cap forbids any useful bound on a short record — `artifacts.frames` r2 record 1 measured 1.361 ms of slack on a 4.826 ms record, and `decode.video`'s reopen-after-the-last-chunk record is 19-89 us of which 4.6-72.3% is its own two boundaries. **F2: `leaves.size()` is whatever `RecordsNamed` returned**, guarded only by `REQUIRE(!leaves.empty())` and tied to no independent number, so a defect emitting one extra leaf record enlarged its own budget by a whole constant; the slack was SUMMED as well, so a swallow concentrated in one record of a three-record leaf drew on 3x the bound. The comment claiming the sum "makes the bound STRICTER on multi-record leaves rather than looser" was FALSE, and the looseness was load-bearing — under ASan `artifacts.frames` r2 measured 3.354 ms against a 6 ms bound and passed only because that leaf has two records. **F3: the failure message read "this quantity is two instrument boundaries and does not move with the box"**, while within one build configuration on one host `decode.audio` r1 record 0 spans 25.0 us to 10032.0 us, 402x; two further comments carried the same claim and still quoted "flat 0.25 ms". FIXED IN FLOW: each leaf record is bounded separately against ONE constant of 30 ms (2.99x the worst of 636 observations, and bounded from above so the `2K` resolution floor stays under the 0.106-0.54 s `decode.video` record the two-core geometry has), `leaves.size()` leaves the arithmetic entirely, the `min` cap moves to the record so the forced-strict probe is guaranteed to red, the cap BINDING is what declares a record below the instrument's resolution — reported and held by the coverage floor (2), with a new `REQUIRE(c.min_coverage >= 0.5)` making that implication executable — and the two per-configuration constants collapse to one because the plain lane's scheduler tail is now 3x the largest sanitizer slack ever recorded. Proven: forced-strict reds 9 of 9 checked records; a 45 ms swallow injected into ONE record PASSES the old formula on `decode.video` and REDS the new one at the identical constant. What (1c) can no longer see is recorded under `## Owed` in [`ltx25-device-residency.md`](specs/ltx25-device-residency.md) | bug |
| [#1547](https://github.com/mudler/vllm.cpp/issues/1547) | `ENG-RELEASE-CONTAINERS` | **The `vulkan` lane cannot build on arm64, and the failed leg leaves the pushed `cpu` digests with no tag.** Run [32447481128](https://github.com/mudler/vllm.cpp/actions/runs/32447481128), job `publish (vulkan, linux/arm64, ubuntu-24.04-arm)`, failed at 406 seconds with `accelerator release metadata error: unsupported Linux accelerator artifact 'linux-aarch64-glibc-vulkan'`, and the re-run failed identically. `docker/Dockerfile:145-146` selects that id for every non-amd64 build while `scripts/release_accelerator_metadata.py` `ARTIFACTS` and `scripts/release_manifest.py` `_artifact_policy` both stop at `linux-x86_64-glibc-vulkan`. The blast radius is the whole publish: `manifest` declares `needs: [plan, publish]`, so one failed leg skipped the job that turns pushed digests into tags, and the `cpu` images built, validated and pushed by digest on both architectures and sit in the registry unreachable. FIXED HERE by registering the tuple rather than removing the lane. The lane is intended: `release/container-matrix.json` declares `vulkan` on both platforms at `channel: preview`, `scripts/check-container-matrix.py` refuses any lane that does not declare both, and removing the leg would mean weakening that gate for every lane. The registration is deliberately NARROW. Two registries describe this tuple and are edited; the third, `scripts/release_pipeline.py` `PRIMARY_ARTIFACT_FORMATS`, describes DOWNLOADABLE archives and is not, because `release_pipeline.py:137` requires `release/release-matrix.json` to equal it exactly and `.github/workflows/release.yml` builds no aarch64 Vulkan tarball. The channel set is `{"preview"}` and not `{"preview", "stable"}`: `.agents/roadmap_v1.md` records both arm64 container legs as unbuilt, no arm64 Vulkan leg has ever run here, and the produced manifest already records `correctness`, `runtime` and `performance` as `absent`. A test refuses `stable` by name and a second test pins the deliberate absence from the download matrix. Spec [fix-ci-container-publish.md](specs/fix-ci-container-publish.md) | bug |
| [#1548](https://github.com/mudler/vllm.cpp/issues/1548) | `ENG-RELEASE-CONTAINERS` | **The `cuda` lane built its ten-SM fat binary at `$(nproc)` on a hosted runner and the runner died under it, and no job declared `timeout-minutes`.** Run [32447481128](https://github.com/mudler/vllm.cpp/actions/runs/32447481128) died at object 512 of 787, about 35 minutes in, with `the runner has received a shutdown signal` and exit 143. Not a timeout: no `timeout-minutes` appeared anywhere in `.github/workflows/containers.yml`, so the six-hour default applied. `scripts/build-linux-accelerator-release.sh:24` sets ten device architectures, so each `.cu` is compiled ten times and one compiler process holds many times the resident set of a `cpu` or `vulkan` translation unit. MITIGATED, NOT DIAGNOSED: memory exhaustion is the leading hypothesis and it is NOT proven, because GitHub infrastructure reclamation produces the same message and the same exit code and the available logs cannot separate them. The change removes the one cause this repository controls. Parallelism is now LANE-AWARE, so the `cpu` and `vulkan` lanes are not slowed: they keep `$(nproc)` and only `cuda` takes 2. The value is measured, not guessed. `.github/workflows/ci.yml:801` already builds the SAME ten-SM fat gencode set on a hosted runner at `--parallel 2` and is green, and the 512-of-787 data point puts a halved build near two hours, which answers `.agents/specs/container-images.md:200-204` and its concern that two jobs would not finish inside a hosted runner's limits. `timeout-minutes: 300` goes on both building jobs for a separate reason: under the six-hour default a hang, a reclaimed runner and an exhausted one all report the same exit 143, so the next failure is undiagnosable. The budget LABELS it rather than policing it, and is loose because no arm64 container leg has ever built. `scripts/check-container-workflow.py` gates the SHAPE and not the number, so retuning the cap needs no checker edit, and prints the resolved cap and budget in its OK line. Spec [fix-ci-container-publish.md](specs/fix-ci-container-publish.md) | bug |
| [#1541](https://github.com/mudler/vllm.cpp/issues/1541) | — | **A REFUSING length guard at the request boundary: the #1365 fix removed the quadratic cost but added no bound.** `SPEC-BPE-QUADRATIC-MERGE` took 64 KB in one pretoken from 23,620.695 ms to 7.797 ms and moved the exponent from ~2 to ~1 (`67823aee2`, [#1539](https://github.com/mudler/vllm.cpp/pull/1539)); it did not add a LIMIT, and a linear cost against a 100 MB body is a smaller problem than a quadratic one rather than the absence of one. The only bound in the stack today is httplib's `CPPHTTPLIB_PAYLOAD_MAX_LENGTH` of 100 MB, and there is still no authentication anywhere in `src/vllm/entrypoints/`. Two binding constraints, both from `.agents/specs/bpe-quadratic-merge.md` `## Defence in depth`: it must REFUSE with an error naming the limit and never truncate, because silently shortening a prompt returns a model output for text the caller did not send; and it belongs at the request boundary rather than in `src/vllm/v1/engine/input_processor.cpp::ValidatePromptLen`, which needs the token count the expensive step produces and so cannot run before it -- placing the guard there reproduces the exact ordering that made the original defect reachable. A byte or character bound is checkable before any tokenization happens, which is the point. NOT a defect #1365 leaves behind and not fixed in that flow: the implementing branch carried no recorded remote-write authority, so its `## Outcome` named the filing as owed AT LANDING and the operator filed it at the merge. Owed under `## Owed` in [bpe-quadratic-merge.md](specs/bpe-quadratic-merge.md) | bug |
Expand Down
Loading
Loading