Skip to content

LTX-2.5: 21B joint video+audio DiT and the generalized video seam - #437

Draft
localai-bot wants to merge 104 commits into
mainfrom
row/MODEL-DIFFUSION-LTX25
Draft

LTX-2.5: 21B joint video+audio DiT and the generalized video seam#437
localai-bot wants to merge 104 commits into
mainfrom
row/MODEL-DIFFUSION-LTX25

Conversation

@localai-bot

@localai-bot localai-bot commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Implements #435.

Lands LTX-2.5 (21.00B joint video+audio flow-matching DiT) and generalizes the video seam so this model class becomes additive. Developer-directed to keep the whole campaign on one PR.

Phase state

Phase Branch Implemented Fresh review Repair
L0 spec + records on this branch n/a n/a
L1 VideoEngine seam, H3 behind it, ABI v18 row/LTX25-L1-SEAM PASS + 1 MEDIUM row/LTX25-L1-FIX, re-review running
L2 DiT forward row/LTX25-L2-DIT FAIL — 2 MEDIUM in flight
L3 Gemma-4 TE + aggregation row/LTX25-L3-TEXT PASS + 1 MEDIUM in flight
L4 Conv video VAE + audio VAE + vocoder row/LTX25-L4-VAE PASS + 3 required in flight
L5 pipeline, recipes, upsampler, duration head, Embeddings1DConnector queued behind the merges
L6 NVFP4 arms (torchao) + GB10 residency
L7 e2e on dgx.casa under flock blocked: Lightricks/LTX-2.5 HF gate

Every phase gates against upstream ltx_core executed at reduced dimensions on CPU, both sides rebuilding weights from one deterministic stream, so no weight byte is checked in. Upstream revision fd4ded7f2d88d3da713abcdd4ad41ecc4a9314ca.

Measured parity (max abs diff vs upstream)

DiT forward 1.19e-07 video / 4.84e-08 audio, across split RoPE, interleaved RoPE, the float64 ladder, masks and audio-disabled. VAEs 1.16e-08 to 1.79e-06 across eight bricks. Text conditioning: hidden-state stack bit-equal, extractors 2.98e-08 to 6.52e-08. All independently reproduced by the reviewers.

What review caught that implementation did not

  • The prompt-KV cache served a stale prompt. The gate ran the forward twice with identical inputs, so it only proved "same in, same out". Two requests whose prompts differ but tokenize to the same length would render the second with the first's prompt.
  • A duplicate family name defeated the seam's never-guess guard, with std::unique hiding the collision.
  • An invisible-constant class. Four constants survive mutation with every golden green, including a norm_eps tolerating a 100x change and the BWE mel log clamp that real silence hits in production but reduced-dimension goldens never reach.
  • Upstream runs the video VAE in checkpoint dtype (bf16), our port is f32, and the golden structurally cannot catch it because the oracle casts to f32 too.
  • Upstream's DEFAULT causal=false path was entirely ungated. The L4 reviewer generated its own goldens and proved our code correct there.

Two spec errors, corrected in place

ABI "v13" was wrong: the counter was already 17, v13 shipped long ago as vllm_complete_tokens. Now 18.

The TE projections take 188160 = 3840 x 49, not 94080 = 1920 x 49. NVFP4 packs two values per byte along the last dim, so U8 header widths are half the logical ones. model.norm.weight is BF16 [3840] and BF16 is unpacked, which settles it. The general rule now recorded for L6: read a quantized checkpoint's UNPACKED tensors to establish a width.

Recorded as owed, not discovered later

  • Speed axis PENDING, structurally: vLLM-Omni has no native 2.5 path (vllm-omni#6066) and its generic diffusers adapter is a black box (supports_step_execution=False), so it is not vLLM's production denominator.
  • Correctness vs the BINDING oracle also PENDING on -Diffusers access. Everything so far gates against the ltx_core cross-check.
  • DiffVAE refused by name, never silently downgraded to the Conv VAE.
  • Owed and declared: the VAE encoder halves, tiled decode, Embeddings1DConnector, and the bf16/NVFP4 arms.
  • No render-quality claim follows from structural e2e.

Related: #441 (ABI struct growth is source- but not binary-compatible; predates this work).

🤖 Generated with Claude Code

mudler added 10 commits August 11, 2026 23:00
…d video seam

LTX-2.5 released with weights that fit one GB10 comfortably and a text encoder
this project has already ported, so the two largest costs of a new video model
are already paid. This commits the spec BEFORE any implementation, per the
spec-before-code rule, and opens the row.

Geometry is MEASURED, not inferred: the FP8 checkpoint's own safetensors header
was read by HTTP range request (6124 tensors, 881,048-byte header, no payload
downloaded, the same technique used for H3's manifests). 21.00B parameters, 48
blocks at 386.7M, video stream 4096 (32 heads x 128), audio stream 2048 (32
heads x 64). The filename says 22b and the Diffusers card says ~19B; the
measured count is what the records use.

The structural break from MiniMax-H3 is that H3 packs every modality into ONE
sequence with per-row token tags, while LTX runs TWO streams coupled by explicit
audio<->video cross-attention. It also adds per-head gated attention on every
attention (to_gate_logits = Linear(query_dim, heads, bias=True),
attention.py:513-514, applied after the attention output at :577), which H3 has
no analogue for.

The checkpoint independently confirms the source: `ff` carries no bias while
`audio_ff` does, which is exactly ff_bias=false / audio_ff_bias=true from
model_configurator.py:78-80. That agreement, not either side alone, is what the
verify-against-both rule asks for.

The free win: get_ada_values modulates from scale_shift_table USING the timestep
(transformer.py:192-197), but the prompt path does not, and at transformer.py:441
kv_modulation reads prompt_scale_shift_table with no timestep term at all. 2.5
ships only that static [2, dim] table and no prompt-side timestep MLP, so the
cross-attention K/V for all 48 blocks is computed once per request and reused
across every denoise step. L2 gates cached-vs-recomputed bit-identical.

Three things are recorded as OWED up front rather than left to be discovered:
the speed axis lands PENDING because vLLM-Omni has no native 2.5 path
(vllm-omni#6066 open) and its diffusers adapter is a black box
(supports_step_execution=False), so it is not vLLM's production denominator;
DiffVAE is refused BY NAME rather than silently downgraded to the Conv VAE; and
no render-quality claim follows from structural e2e, which H3 taught directly.

The MODEL row ratchet moves 362 -> 363 because a row EXISTS, never to make a
transition pass. Its semantics are unchanged and
test_model_row_ratchet_is_load_bearing still proves it catches drift in both
directions; the docstring gains the new transition so the history stays legible.

Issue: #435

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…Engine (#435)

LTX-2.5 phase L1 (.agents/specs/ltx-2-5.md sections 5 and 6). The video
capability was concrete-typed on MiniMax-H3: `MiniMaxH3VideoEngine` was the
only thing the C ABI, /v1/videos and the example could reach. A second video
family (LTX-2.5, a 21B joint video+audio flow-matching DiT) would otherwise
have to be a second parallel path, which AGENTS.md "Shared seams" forbids.

Introduces `vllm::multimodal::VideoEngine` -- an abstract engine plus a
checkpoint-DETECTED family registry -- and moves H3 behind it without moving a
single output byte.

  * `include/vllm/multimodal/video_engine.h`: VideoModelParams / VideoGenParams
    / VideoResult (the generic superset), the abstract VideoEngine, and the
    registry (RegisterVideoFamily / RegisteredVideoFamilies /
    DetectVideoFamilies / LoadVideoEngine) with the self-registration idiom the
    model registry already uses (REGISTER_VLLM_VIDEO_FAMILY, one line per
    family, zero shared-array edits).
  * Family-specific fields ride in a `std::map<std::string,std::string> extras`
    -- H3's `partition`, LTX's future `pipeline_kind` / `model_version` -- so a
    new family adds no member to a struct every other family must ignore.
  * NEVER GUESS A FAMILY. Detection asks every family what the checkpoint
    HOLDS (tensor names, read header-only through the shared
    ReadVideoCheckpointTensorNames), never the file extension or path spelling.
    Zero claimants or several is a refusal naming what was seen and what is
    registered. "Only one family is registered, so it must be that one" is the
    silent mis-load this seam exists to prevent: an H3 DiT handed to an LTX
    loader does not fail, it renders noise.
  * H3 is now `MiniMaxH3VideoEngine final : public VideoEngine`, registered as
    family "minimax-h3", detected by its DUAL patch projection
    (video_patch_proj.weight + audio_patch_proj.weight -- the names all four
    loader arms bind by, minimax_h3_gguf.cpp:100-103). The H3-typed structs,
    `Load` and the H3-typed `Generate` are untouched; the generic overrides are
    ADAPTERS onto them, so there is one code path, not two.
  * The /v1/videos request mapping moved to the family-agnostic seam
    (VideoGenParamsFromRequest); MiniMaxH3VideoGenParamsFromRequest delegates
    to it, so HTTP, FFI and the registry cannot drift.

ABI 17 -> 18, purely ADDITIVE:
  * vllm_video_model_params.family -- NULL/empty (the zero value) means detect,
    which is exactly what a v12 caller already gets. An unregistered name is
    refused naming what is registered; it is never a hint.
  * extra_keys / extra_values / n_extras on vllm_video_model_params and
    vllm_video_params. `partition` becomes the documented ALIAS for the
    "partition" extra; supplying both with DIFFERENT values is
    VLLM_ERR_INVALID_ARGUMENT rather than a silent winner.
  * vllm_video_engine_family() so detection is visible to a C caller.
A v12 caller zero-fills the struct growth and is byte-identical; the existing
v12 test_capi section is unchanged and still green at 102 assertions,
including the text-checkpoint refusal that names vllm_engine_load (that hint
moved into the generic refusal, where it is equally true).

NOTE for the operator: the spec says "ABI goes to v13". v13 shipped long ago
(vllm_complete_tokens) and VLLM_ABI_VERSION was already 17 -- the spec was
reading the VIDEO SLICE's v12 label as the ABI counter. 18 is the only
self-consistent next number; the intent (additive, v12 video callers
byte-identical) is met exactly.

Gates:
  * RED first: tests/vllm/multimodal/test_video_engine.cpp fails to compile
    against the missing seam, then 10 cases / 227 assertions SUCCESS.
  * BYTE-IDENTITY: the abstract path (LoadVideoEngine -> VideoEngine::Generate)
    reproduces the committed pre-fold goldens frame-for-frame and WAV-for-WAV,
    and tests/vllm/models/test_minimax_h3_video_fold.cpp is unchanged and green
    at 6 cases / 137 assertions -- the same count as before the change.
  * test_capi 55 cases / 502 assertions SUCCESS (v12 section 102, new v18
    section 6 cases / 35 assertions).
  * Clean Release/-Werror rebuild from an empty tree: zero warnings.
  * Full ctest: 391/391 passed.
  * Mutation: forcing the H3 detector to claim every checkpoint ("we are the
    only family") turns test_video_engine RED (2 cases / 3 assertions) and the
    capi v18 section RED -- the never-guess gate bites.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…duced dims

Phase L2 of the LTX-2.5 campaign (.agents/specs/ltx-2-5.md, issue #435): the
21.00B joint video+audio DiT's parameter contract and its full dual-stream
forward, ported from Lightricks LTX-2
(packages/ltx-core/src/ltx_core/model/transformer/) and gated against those same
modules IMPORTED BY PATH and EXECUTED at reduced dimensions on CPU.

The method is MiniMax-H3's, which is what made its bricks trustworthy: both sides
rebuild every weight and every input from one deterministic FNV-1a + splitmix64
stream keyed by the parameter's own NAME, so no weight byte is checked in and the
weight CONTRACT is itself part of the gate — a name either side invents that the
other lacks changes the numbers. scripts/gen-ltx2-goldens.py needs only a sys.path
entry pointing at an LTX-2 checkout: no venv, no checkpoint, no gated download. It
asserts the resolved ltx_core is the checkout's, not an installed one.

Measured max|diff| against the oracle, over the whole forward:

  split RoPE               video 1.19e-07  audio 4.84e-08
  interleaved RoPE         video 8.94e-08  audio 4.47e-08
  float64 frequency ladder video 1.04e-07  audio 7.45e-08
  prompt + self masks      video 8.94e-08  audio 7.45e-08
  audio stream disabled    video 8.94e-08  audio 4.47e-08

Each trap the spec names is gated on its own so a failure localizes: the
frequency ladder (BIT-equal, see below), the split/interleaved/float64 cos-sin
tables, AdaLayerNormSingle, the per-head gated attention, the asymmetric
audio->video projection pair, and the ff / audio_ff bias asymmetry. The
enumeration is compared name-for-name and shape-for-shape against upstream's own
named_parameters(), and ParseLtx2DitParamsFromManifest recovers the geometry from
the SHAPES alone.

The frequency ladder is asserted BIT-equal, not close, because that is where this
port's one real defect lived. Computing rope.py's `linspace(0, 1, n)` in double
instead of reproducing ATen's float32 half-forward/half-backward walk moves two of
the eight AUDIO samples by a single f32 ulp; the ladder multiplies that up to a
1.5e-4 frequency error and RoPE turns it into 1.2e-4 in cos/sin. The video ladder
(n=5, exact step) hides it completely.

PROMPT-K/V CACHE. LTX-2.5 sets use_prompt_adaln_single=false and ships only the
static prompt_scale_shift_table, so transformer.py:441 builds the K/V modulation
with no timestep term and the text cross-attention K/V for every block is
computable ONCE PER REQUEST. That ships as the default path, and the gate asserts
cached and recomputed are BIT-IDENTICAL — then POISONS the cache and requires the
output to move, so the identity cannot pass vacuously by never reading it.

NEW SHARED SEAM. vt::Attention refuses Tq != S ("query/key/value token count must
match"), which no cross-attention can satisfy, so this adds vt::AttentionCross:
dense non-causal attention over differing query and key extents with an optional
additive score bias. Purely additive to vt; every existing self-attention call is
untouched and LTX's own self-attention still routes through vt::Attention. It
ships with a CPU kernel only — unified memory gets it through the reference tier,
a discrete CUDA device refuses by name, and the native CUDA kernel is recorded as
owed alongside the device-resident forward.

Refused rather than silently served, each naming the missing piece: any stream
dtype other than f32 (bf16/FP8/NVFP4 are L6); the prompt-K/V cache when the prompt
AdaLN MLP is on; the 19B caption-projection form (L3); keyframe absolute-position
embeddings; LTXModelType.VideoOnly / AudioOnly, whose weight contract differs.
Guidance perturbations run in their no-op configuration, which is upstream's own
perturbations=None path, and that is recorded in the header.

DOCS, and why this commit touches them. The dispatching operator scoped docs/*
out of this task and owns those records. check-doc-checkpoint --staged is RED
without them: `src/vllm/model_executor/models/` classifies as feature_surface and
`include/vllm/` + CMakeLists.txt as user_usage, so the gate demands
docs/FEATURES.md and docs/USAGE.md. Independently of the gate, FEATURES.md's
LTX-2.5 row read "SPIKE: spec committed, no forward yet", which this commit makes
false, and a public projection that has drifted is worse than a scope deviation.
The edits are therefore surgical and LTX-2.5-only: the one existing keyed row in
FEATURES.md, and one new USAGE.md section that leads with "there is no LTX-2.5
render path yet" and documents how to reproduce the gate. Flagged to the operator
for reconciliation rather than done silently.

STILL OWED, so it is not discovered later: no porting-inventory entry was added
for vt::AttentionCross. Its CPU kernel mirrors the existing AttentionKernel and
torch SDPA's is_causal=False contract, which section 9.1's recorded vt:: deviation
already covers in general, but a reviewer may want it named there explicitly.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…pstream

Phase L4 of .agents/specs/ltx-2-5.md (issue #435). Ports the DECODE half of
both LTX-2.5 VAEs and gates each brick against the upstream `ltx_core` modules
EXECUTED at reduced dimensions on CPU — the method that made MiniMax-H3's VAE
bricks trustworthy. Both sides rebuild every weight and input from one
deterministic stream, so no weight byte is checked in.

  scripts/gen-ltx2-vae-goldens.py   runs Lightricks/LTX-2 as the oracle
  ltx2_audio_vae.{h,cpp}            AudioDecoder + Vocoder (both resblock
                                    arms) + VocoderWithBWE
  ltx2_video_vae.{h,cpp}            ConvVideoDecoder, and the DiffVAE refusal
  test_ltx2_vae.cpp                 10 cases / 1120 assertions

Measured max|diff| vs upstream, f32 round-off throughout:

  audio decoder              1.78814e-06
  audio decoder (freq pad)   1.78814e-06
  BigVGAN v2 vocoder         2.23517e-08
  legacy resblock-1 vocoder  2.23517e-08
  BWE vocoder chain          1.49012e-07
  Conv video decoder         1.40071e-06
  kaiser-sinc filter         2.98023e-08
  hann-sinc resample filter  1.16415e-08

REFUSED BY NAME, never downgraded (spec section 0 item 2): the diffusion video
decoder. `Ltx2VideoDecode(kDiffusion, ...)` throws naming NADiffusionDecoder and
its missing neighborhood-attention kernel, and the test asserts the message
carries that name and that nothing decoded on the way to the refusal. A silent
fall-back to the Conv decoder would return a worse render as if it were the
requested one, and no gate this project owns could detect that. `attn_res_x` is
refused too: at this upstream revision the block cannot be CONSTRUCTED, because
_make_decoder_block passes `attention_head_dim` to UNetMidBlock3D, which does
not accept it.

TWO FINDINGS, measured rather than assumed, both now gated against upstream:

  * The audio decoder is NOT end-to-end causal. `causality_axis` governs the
    CONVOLUTIONS; its AttnBlocks attend over the whole (time, mel) map, so a
    last-frame perturbation reaches EVERY output frame. Upstream agrees. The
    convolution-only reach is gated separately with attention off, where the
    oracle says frames [5, 8] move and the port must agree.
  * The Conv video decoder is NOT end-to-end causal either, for a different
    reason: `res_x_y`'s shortcut norm is a one-group GroupNorm over (C,T,H,W)
    whose statistics span TIME. Its convolution-only reach is gated on a
    stripped block list, where the oracle says frames [3, 4] move.

HONEST GATE LIMIT, found by mutation and recorded rather than hidden: flipping
the video decoder's PixelNorm eps from 1e-8 to 1e-6 leaves every golden GREEN,
because the normalized activations are O(1) and the two epsilons differ by ~1e-7
relative. The distinction is real upstream (bare `PixelNorm()` vs
build_normalization_layer), so it is pinned by a source-anchored constant
assertion instead, which does catch that mutation.

Mutation-verified RED: zero temporal padding instead of a replicated first frame
-> 2.34534; unpatchify q/r swapped -> 1.96412. Tree restored byte-for-byte.

OWED, so it is not discovered later: the ENCODER halves (AudioEncoder + its mel
front-end, and the video encoder), the tiled decode path, and the DiffVAE row.

EXCEPTION ARGUED HERE, per AGENTS.md "Changing the rules or a checker": this
commit does not update docs/FEATURES.md or docs/USAGE.md, which
check-doc-checkpoint requires for src/vllm/model_executor/models/, include/vllm/
and CMakeLists.txt. The LTX-2.5 campaign runs several implementers in parallel
on one branch and the operator holds every record surface, so writing those two
files from a helper would collide with the DiT and pipeline phases in exactly
the shared-file way AGENTS.md's "no surface that every PR must write" warns
about. The obligation is REPORTED to the operator, not dropped; it is owed
before the campaign's PR lands, and this commit is visible debt until then.

FOLLOWING_AGENTS_PROTOCOL

Refs #435
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
L1 found this while implementing. The spec said the seam would land at "ABI
v13", which was wrong twice over: VLLM_ABI_VERSION was already 17, and v13
shipped long ago as vllm_complete_tokens. The mistake was reading the VIDEO
SLICE's own v12 label as if it were the ABI counter.

The requirement never depended on the number. What the spec actually asks for is
that the bump be purely ADDITIVE so v12 video callers keep working
byte-identically, guarded by the existing test_capi v12 section. That is
unchanged and met. Only the number moves.

Recorded as a correction in place rather than a silent edit, because the wrong
number was committed and a reader of the history should see why it moved.

Issue: #435

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
Both came out of the campaign rather than the reading, and both are the kind of
thing that produces a finite, correctly-shaped, WRONG result. Recording them in
the spec so they cannot be rediscovered the expensive way.

1.4 — text conditioning is a MULTI-LAYER aggregate, not the last hidden state.
feature_extractor.py normalizes hidden states shaped [B, T, D, L] and
concatenates ACROSS THE LAYER dimension. The real TE checkpoint confirms it: the
two caption projections take 94080 input features, and 94080 = 1920 x 49, the
model's per-layer width across its 48 layers plus one. There are two
normalization variants (per-batch masked mean/range with an 8x scale, and
per-token RMS "for V2 models") and the right one is selected from config, never
guessed. Get the variant, the mask handling, the reduction axes or the layer
order wrong and the model renders a plausible video for the WRONG PROMPT, which
no shape or finiteness check catches.

Two loader facts measured alongside it: the tokenizer ships EMBEDDED AS A TENSOR
(tokenizer_json, ~32 MB) rather than as a sibling file, so a loader that looks
for tokenizer.json fails on this checkpoint; and the TE is quantized with
torchao NVFP4, not compressed-tensors as H3's arm is, so L6 must verify the
layout rather than assume the two are the same.

1.5 — the audio VAE is NOT end-to-end causal. L4 measured this instead of
assuming it: its first causality probes failed and upstream agreed with the
failure. causality_axis governs the convolutions, but the AttnBlocks attend over
the whole (time, mel) map, so a last-frame perturbation reaches every output
frame. The Conv video decoder is not causal either, for an unrelated reason: a
one-group GroupNorm whose statistics span time. "Causal" is precisely the
property a port assumes and never checks, so both are now gated in two parts,
with upstream supplying the expected windows.

Issue: #435

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…d prompt

L2's fresh review disproved a claim this spec made before it was true. 1.2 said
the bit-identity gate meant the cache "cannot silently diverge". The distinction
it missed is the whole point of the feature:

Against a changed TIMESTEP the cache cannot diverge. That is the property the
checkpoint gives us, it is why use_prompt_adaln_single=false is a free win, and
it is real.

Against a changed PROMPT it silently could. The gate ran the forward twice with
IDENTICAL inputs, so it could only ever prove "same in, same out". The cache
carried no prompt identity and its only validity check was on SIZE. A probe that
swapped in a different prompt of equal token count found the cache did not
notice, while the ground truth moved.

What that implies is not academic. A pipeline or server reusing one cache across
two requests whose prompts differ but tokenize to the same length renders the
SECOND REQUEST WITH THE FIRST REQUEST'S PROMPT. No error, no shape mismatch, no
finiteness failure, and no gate. That is precisely the class of defect this
campaign keeps naming: finite, correctly shaped, and wrong.

The repair carries a content fingerprint and refuses by name; it is with a fresh
implementer.

Also recorded, from the same review: binding-oracle parity is PENDING for every
brick landed so far. L1-L5 gate against the ltx-core CROSS-CHECK, not against
vLLM-Omni, because -Diffusers access is still awaiting manual approval. That is
legitimate under 3 and 6, and it is what a cross-check is for, but it was
implicit and is now stated. BENCHMARKS.md recorded only the SPEED axis as
pending, which understated it; both axes are now named there.

Issue: #435

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…ated (#435)

Repairs the adversarial review findings on LTX-2.5 phase L1 (3db9233). All
four are the same defect class: a hole in the never-guess guarantee is not an
error-handling nicety here, it is a silent-wrong-render risk, because an H3
GGUF handed to an LTX loader does not fail, it renders noise.

F1 (MEDIUM) -- RegisterVideoFamily refused an empty name and a missing
detector or loader, but NOT a name already registered. The reviewer registered
a second "minimax-h3" whose detector claimed every checkpoint and whose loader
was an impostor, and got `registered listing size=1, claimants=1`: two families
under one name, the SEVERAL-claimants refusal unreachable because both
claimants carry the SAME name, and which loader runs decided by static-init and
link order. The real family won only because stable_sort preserved registration
order and its TU linked first. RegisterVideoFamily now refuses a collision,
naming it. Registrars run at static init, so that throw ends the process -- the
intended outcome, and the same one the empty-name refusal beside it already
produces: a name collision is a BUILD defect, and dying while naming it is
strictly better than rendering noise.

Once the registration refuses, the two std::unique calls
(RegisteredVideoFamilies, DetectVideoFamilies) were masking nothing, so they are
gone rather than left to look like protection. They never were: adjacent-only,
they collapsed the printed listing while leaving two entries in the registry for
resolution to choose between, and in DetectVideoFamilies a std::unique is
actively harmful, since merging a duplicate-name pair back into one claimant is
exactly what lets the SEVERAL refusal fall through into a load. Assertions state
the invariants in their place.

F3 (LOW) -- the canonical sort ran inside a function-local `static const bool`,
so it happened once, on first query. Anything registered afterwards was appended
unsorted, and std::unique then also stopped de-duplicating. No
REGISTER_VLLM_VIDEO_FAMILY registrar can hit that (registrars all run before
main), but RegisterVideoFamily is a public header function and a caller may
register at any time. Sortedness and uniqueness are now invariants of the TABLE,
established by sorted insertion at every registration, so they hold whenever
anyone registers rather than whenever someone first asks.

F2 (LOW) -- the SEVERAL-claimants branch is unreachable with one family
registered, so nothing gated it and it could rot before LTX-2.5 arrives. A
registry test does not have to wait for a real second family: the new test case
registers a throwaway one, whose detector claims ONLY when the caller sets its
extra (so its presence cannot change what any other test detects) and whose
loader is an impostor that counts its own calls. That single case gates F1, F2
and F3 together, and asserts the refusal happened INSTEAD of a load rather than
after one.

F4 (LOW) -- test_video_engine never asserted VideoResult::audio_path.
CheckAgainstGoldens read `out_dir + "/audio.wav"` off disk, so the WAV half of
the byte-identity claim rested on a filename convention: mutating
`out.audio_path = "/dev/null"` in MiniMaxH3VideoResultToGeneric left the seam
test GREEN at 10 cases / 227 assertions. It now reads the path the RESULT
reports, and pins that path, the way the frames were already pinned through
result.frame_dir.

F7 (nit) -- the empty-dit_path refusal advised "Declare the family explicitly
rather than letting the loader guess", which is a dead end for a caller who
supplied no checkpoint: the declared loader would still have nothing to open,
so following the advice produces a second, more confusing refusal. That case now
names the missing input and what would satisfy it.

Not changed: F5. The struct growth is source-compatible but not
binary-compatible, which is a property of the project's established ABI-growth
model (v2/v4/v7/v8/v9/v10/v14 all use the same zero-filling language) and not a
regression this work introduced. No ABI or behaviour change was needed for any
of the above; nothing under ltx2*, no H3 numerics, and no spec or record surface
was touched.

docs/USAGE.md: `check-doc-checkpoint --staged` classifies
`include/vllm/multimodal/video_engine.h` as `user_usage`, so the C++ consumption
section gains the video seam's resolution contract -- the refusals a caller now
meets, including the two this commit changes. That is the minimal keyed edit
that discharges the obligation; the ABI table is untouched because the ABI is.

Gates (CPU-only Release, -Werror, GCC 13.3.0):
  * RED first, verbatim, before the fix: test_video_engine 11 cases /
    247 assertions, Status: FAILURE -- `std::is_sorted(all)` false (F3),
    `a family name that is already registered must be refused` (F1), and
    `msg.find("Declare the family explicitly") == npos` reading
    `128 == 18446744073709551615` against the live message (F7).
  * GREEN after: test_video_engine 11 cases / 254 assertions, Status: SUCCESS
    (was 10 / 227).
  * MUTATION for F2 (no product defect to go red on): forcing LoadVideoEngine
    to take the first claimant (`claimants.size() == 1` -> `!empty()`) turns the
    new case RED at 5 failed assertions, and the impostor loader RUNS
    (g_impostor_loads 1, expected 0). Restored byte-for-byte.
  * MUTATION for F4: `out.audio_path = "/dev/null"` turns 3 cases RED. Note the
    doctest trap in the raw output: the total assertion COUNT DROPS 254 -> 237
    as cases throw, so the count alone reads like a smaller run, not a failure.
    Status is the signal. Restored byte-for-byte; minimax_h3_video.cpp is
    identical to 3db9233.
  * Baselines held: test_minimax_h3_video_fold 6 cases / 137 assertions,
    test_capi -tc='capi v12*' 4 cases / 102 assertions (the byte-identity
    evidence, unmoved), test_capi 55 cases / 502 assertions.
  * Clean Release rebuild from an empty tree: 1185/1185, exit 0, zero warnings.
  * Full ctest: 391/391 passed, 0 failed.
  * Debug (assert-enabled, NDEBUG off) build of the three gate binaries:
    test_video_engine 11 / 254, fold 6 / 137, capi v12 4 / 102, all SUCCESS --
    the new assertions hold. SCOPED, not full: a full Debug tree of all 1185
    targets hit ENOSPC on this box (447G volume, 622M left at the failure), and
    filling the disk breaks every other agent's gate here, so the Debug lane
    covers exactly the binaries that exercise the added assertions.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
… upstream

Phase L3 of .agents/specs/ltx-2-5.md (issue #435). LTX-2.5 does NOT condition on a
text encoder's last hidden state: it takes EVERY Gemma-4 hidden state, stacks them
on a new last axis, normalizes, concatenates ACROSS THE LAYER AXIS and projects the
flattened result twice. This ports that path and gates it against the upstream
`ltx_core` modules IMPORTED BY PATH and EXECUTED at reduced dimensions on CPU, the
method L2 and L4 used on this campaign and MiniMax-H3 before them. Both sides
rebuild every weight and input from one deterministic FNV-1a + splitmix64 stream
keyed by the parameter's own NAME, so no weight byte is checked in and the weight
CONTRACT is part of the gate. scripts/gen-ltx2-text-goldens.py needs only a sys.path
entry pointing at an LTX-2 checkout, and asserts the resolved ltx_core is the
checkout's rather than an installed one.

  scripts/gen-ltx2-text-goldens.py   runs Lightricks/LTX-2 as the oracle
  ltx2_text_encoder.{h,cpp}          both norm variants, both caption projections,
                                     the conditioning hand-off, the asset pack
  gemma4.{h,cpp}                     ForwardHiddenStates: the per-layer capture
  test_ltx2_text_encoder.cpp         15 cases / 2473 assertions

Measured max|diff| vs upstream, f32 round-off throughout:

  hidden-state stack (a permutation)              0            BIT-equal
  _norm_and_concat_padded_batch  left / right     4.77e-07 / 4.77e-07
  norm_and_concat_per_token_rms  left / right     2.38e-07 / 2.38e-07
  FeatureExtractorV1 (is_av)     left / right     6.52e-08 / 5.96e-08
  FeatureExtractorV2 video       left / right     4.47e-08 / 5.96e-08
  FeatureExtractorV2 audio       left / right     2.98e-08 / 2.98e-08
  conditioning video / audio     left / right     4.47e-08, 5.96e-08 / 2.98e-08
  additive mask, sort index, reordered mask       EXACT

A CORRECTION TO THE DISPATCH BRIEF, measured from the checkpoint header rather
than assumed. The brief read the projections' 94080 as the input feature count and
concluded hidden = 1920. NVFP4 packs TWO values per byte, so the U8 widths are
half the real ones: `q_proj.weight U8 [4096, 1920]` is [4096, 3840],
`o_proj U8 [3840, 2048]` is [3840, 4096], and `model.norm.weight BF16 [3840]` --
stored BF16, therefore unpacked -- confirms it independently. The Gemma hidden
size is 3840 and the caption projections take 188160 = 3840 x 49 inputs. The layer
count (48 + 1) was right; only the width moves.

THE CONCATENATION IS HIDDEN-MAJOR, LAYER-MINOR. `stack(..., dim=-1)` then
`.reshape(B, T, D*L)` places layer `l` of channel `d` at flat index `d * L + l`.
Layer-major is a correctly shaped, finite, PERMUTED conditioning vector, so the
stack is emitted as a golden of its own and the test also proves the layer-major
alternative is a different tensor.

VARIANT SELECTION IS GATED, NOT GUESSED. `Ltx2SelectTextFeatureVariant` mirrors
encoder_configurator.py:163-209: none of the four V2 marker keys means V1, all four
with their exact values means V2, and a partial set or a drifted value is refused
by name. Shapes cannot distinguish the two (3840 x 49 is the flat width under
both), which is exactly why the selection has to come from config. The test asserts
against upstream's OWN resolved classes and shapes, plus both refusals.

PADDING IS GATED ON BOTH SIDES. The tokenizer LEFT-pads (base_encoder.py:235), the
connector wants RIGHT-padding (embeddings_processor.py:82-84) and the extractor
sits between them, so every brick runs on a left-padded and a right-padded mask.
Both norms are asserted to zero the padded positions EXACTLY. The projected pads
are asserted NOT to be zero under V2: the norm zeroes them, so their projected value
is exactly the Linear's bias, and a port that force-zeroes projected pads diverges
from upstream on every padded row while still looking masked. V1 has no bias, so
its padded rows ARE zero, and that asymmetry is gated too.

TWO MEASURED FINDINGS, gated as measured rather than repaired:

  * `_to_binary_mask`'s predicate is `< 1e-6`, and BOTH masks upstream can hand it
    satisfy it everywhere -- `zeros_like(additive)` with learnable registers on
    (which 2.5 has, embeddings_connector.py:152) and the additive mask itself with
    them off, since -FLT_MAX < 1e-6 too. The mask EmbeddingsProcessor hands the DiT
    is therefore ALL ONES. Gated on both inputs so a port cannot "fix" it.
  * The shipped vonkaiser/LTX-2.5-FP8-NVFP4 text encoder has 1688 tensors and NO
    safetensors `__metadata__` block at all, so upstream's
    GemmaAssets.from_single_file raises on it before reading a tensor
    (gemma_assets.py:110-114). `Ltx2LoadGemmaAssets` refuses identically by default;
    a caller holding the Gemma config out of band passes require_config=false.

THE GEMMA-4 EXTENSION, kept as small as the seam allows. Our Gemma-4 returned
logits and nothing else, so `Gemma4Model::ForwardHiddenStates` was added: one
optional out-parameter on the existing ForwardBody, nullptr on every other call
site, so no shipped path changes shape or cost (the test asserts the plain forward's
logits are bit-identical with the capture on). It mirrors transformers'
`output_hidden_states=True` ORDER exactly, which is the part that fails silently:
[0] is the sqrt(hidden)-scaled embeddings, [i] is the output of decoder layer i-1,
and [L] is model.norm(output of the LAST decoder layer) -- the RAW last layer output
never appears. That last entry is proven by the invariant only the final-normed
state satisfies: the logits are exactly that state through the tied lm_head
(max|diff| 2.05e-08 over max|value| 0.167).

MUTATION-VERIFIED RED, tree restored byte-for-byte (md5 checked):
  layer order reversed in the stack -> 6 cases / 17 assertions fail;
      stack 0.899, norm V1 7.96, norm V2 2.87, V2 extractor 0.543/0.463
  variant selection ignored (always per-token RMS) -> V1 extractor 0.431 / 0.508
  gemma4 capture stores the RAW last layer -> the lm_head invariant moves from
      2.05e-08 to 0.172 over max|value| 0.0167

DTYPE. Everything is f32, exactly as L2 records for the DiT: the PARITY dtype of
this gate, not a widening of a bf16 path. Upstream resolves ONE model dtype
(base_encoder.py:41) and FeatureExtractorV2 casts the normalized tensor straight
back to `encoded.dtype`, so the bf16/FP8/NVFP4 arms are a single stream-dtype
choice, phase L6, and are OWED. Every entry point REFUSES a non-f32 compute_dtype
with a message naming the missing phase, and that refusal is gated. Reduction
accumulators are double; that is an accumulator width, not a memory format, and no
buffer this file produces is wider than f32.

OWED, so it is not discovered later:
  * `Embeddings1DConnector` (embeddings_connector.py:74-191) is NOT ported. It is
    built out of the DiT's own Attention, FeedForward and RoPE, which phase L2 owns,
    so it belongs to the change that can link against them. This stops at the
    connector's INPUT contract, which is what it gates.
  * The Gemma-4 TOWER itself is not gated against LTX's oracle here. transformers
    5.3.0 on this box carries no `gemma4_unified` in CONFIG_MAPPING, so
    `AutoModelForImageTextToText.from_config` cannot build the tower at reduced
    dimensions and there is no oracle to run. The LTX-specific delta -- which states,
    in which order, and everything downstream -- IS gated; the tower is gated against
    vLLM by its own row.
  * The quantized arm. The checkpoint is torchao NVFP4 (`weight` U8 packed,
    `weight_scale` F8_E4M3 grouped, `weight_scale_2` F32 scalar, plus a
    `torchao_nvfp4` U8 [240] marker per module), which is NOT the compressed-tensors
    layout H3's NVFP4 arm uses. Phase L6.
  * No porting-inventory entry was added for the ltx2_text_encoder anchors.

DOCS, and why this commit touches them. The dispatching operator scoped docs/* out
of this task and owns those records, but check-doc-checkpoint --staged is RED
without them: src/vllm/model_executor/models/ classifies as feature_surface and
include/vllm/ + CMakeLists.txt as user_usage. The edits are minimal and LTX-2.5
only: ONE NEW keyed row in FEATURES.md (additive, so it does not collide with L2's
edit of the existing DiT row) and one USAGE.md section that leads with "there is no
LTX-2.5 render path" and documents how to reproduce the gate. Flagged to the
operator for reconciliation rather than done silently.

Evidence. RED before: 13 cases, 3 passed / 10 failed, "assertions: 25 | 25 passed |
0 failed", Status: FAILURE -- the documented trap where a failing gate prints zero
failed assertions. GREEN after: 15 cases / 2473 assertions, Status: SUCCESS. Clean
Release -Werror CPU-only rebuild, 0 warnings; full ctest 391/391.

FOLLOWING_AGENTS_PROTOCOL

Refs #435
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…is 3840 wide

L3 caught an error I put in this spec. 1.4 recorded the caption projections as
taking 94080 = 1920 x 49 inputs, reading the checkpoint's U8 shapes as if they
were logical. NVFP4 packs TWO VALUES PER BYTE along the last dimension, so every
U8 width in that file is half the real one. The projections take 188160, and
188160 = 3840 x 49.

The tell was in the same header the whole time, and I printed it without
reconciling it: model.norm.weight is BF16 [3840], and BF16 is unpacked, so 3840
is authoritative. Three further confirmations agree. embed_tokens U8
[262144, 1920] -> [262144, 3840]. o_proj U8 [3840, 2048] -> [3840, 4096], which
is 16 heads x 256. And the projections' own biases are BF16 [4096] and [2048],
unpacked, matching the DiT's two stream widths exactly.

The layer count (48 + 1) was right; only the width moved, and nothing downstream
of the width is affected.

The general lesson, which applies again at L6: read a quantized checkpoint's
UNPACKED tensors to establish a width, never its packed ones. A packed width is
plausible, self-consistent, and wrong by exactly a factor of the packing.

Also settled by execution rather than inference: 2.5 uses FeatureExtractorV2
(per-token RMS), selected by four marker keys, with _rescale_norm applied
separately per projection over that projection's own out_features.
create_caption_projection is not on this path.

Issue: #435

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
mudler added 9 commits August 12, 2026 01:48
Repairs the adversarial review of phase L2 (issue #435, PR #437, spec
.agents/specs/ltx-2-5.md §1.2/§7). The math the review reproduced is unchanged;
what was missing is that two shipped paths had nothing holding them.

F2 (MEDIUM) — the prompt-K/V cache served a STALE PROMPT. Its only validity
check was a SIZE check, so two requests whose prompts differ but whose token
counts agree — the ordinary case for anything that reuses one cache across
requests — rendered request 1's prompt for request 2 with no shape mismatch, no
non-finite value and no error. The cache now carries an FNV-1a fingerprint over
both streams' context tensors, their geometry and their prompt masks
(Ltx2PromptIdentityOf), and a filled cache that meets a different prompt refuses
BY NAME, saying which part moved and that Ltx2PromptKvCache::Reset() rebinds the
allocation to a new request. The digest hashes bytes, so it is an identity test
and never a similarity one: a false refusal costs one recompute, a false accept
renders the wrong prompt. Against a changed TIMESTEP the cache still cannot
diverge — that property is real and untouched.

F1 (MEDIUM) — the dense [Tq, S] attention bias in vt::AttentionCross had ZERO
coverage. Upstream documents (B, T, T) as the dense form
(transformer_args.py:212-215 @ fd4ded7f), the port accepts it and vt::AttentionCross
validates it, but every existing test used the key-only broadcast, where there is
exactly one bias row and a kernel reading row 0 for every query is
indistinguishable. scripts/gen-ltx2-goldens.py now emits a DenseMask forward case
with (BATCH, T, T) masks on both streams, and a focused vt case pins two
identical queries to different bias rows. The reviewer's mutation (every query
reads bias row 0) now fails both.

F5 (LOW) — the GQA broadcast (g = h / (Hq/Hkv)) was unreachable: every LTX
attention has Hq == Hkv. Gated with an Hq=4/Hkv=2 case plus the non-multiple
refusal.

F3 (LOW) — "refuses by name" refused by NUMBER. vt::OpName gives every OpId its
canonical spelling; GetOp's refusal and the reference-tier warning now name the
op and the device (the integers are kept for grep). The defining switch is
exhaustive and default-free, so appending an OpId without naming it fails the
-Werror build — proved by deleting one case (error: enumeration value
'kAttentionCross' not handled in switch). The refusal is gated in
tests/vt/test_op_provider.cpp (message + OpName totality and uniqueness) and in
test_ltx2.cpp for kAttentionCross specifically. The same finding's second half:
Ltx2Attention routed to vt::Attention on `s == tq && bias == nullptr`, so the
DISPATCHED OP — and on a device carrying kAttention but not kAttentionCross, the
success or failure of the call — depended on the prompt length. It now routes on
`context == nullptr`, upstream's own self-attention marker (attention.py:556).
The two ops are asserted BIT-for-BIT equal on the square unbiased problem, so
this is a dispatch decision and not an arithmetic one, and all five pre-existing
max|diff| values are unmoved.

F4 (LOW) — vt::AttentionCross now has a porting-inventory entry (§9.17):
upstream semantics (torch SDPA as LTX's PytorchAttention calls it,
attention.py:97-102), what was written from scratch and why the pinned vLLM has
no equivalent, local anchor, backends, the OWED CUDA arm, tests and spec.

EVIDENCE. Every finding was RED first. The reviewer's two mutations now fail:
`brow = bias_data` gives 27/29 cases, 3 failed assertions, Status: FAILURE
(the literal form needs [[maybe_unused]] on bias_rows to compile under -Werror);
dropping the identity guard gives 27/29 cases, 7 failed assertions, Status:
FAILURE. Restored byte-for-byte after each.

Clean Release -Werror rebuild, zero warnings. ctest 391/391. test_ltx2 29 cases /
1615 assertions / Status: SUCCESS! (was 21 / 1350). test_op_provider 12 / 385 /
SUCCESS!. kLtx2ParamCount = 214. The goldens regenerate byte-identical apart from
the --out path the generator records in its own header, and the five forward
max|diff| values are exactly as before:

  split                    video 1.19209e-07  audio 4.84288e-08
  interleaved              video 8.9407e-08   audio 4.47035e-08
  float64 frequency ladder video 1.04308e-07  audio 7.45058e-08
  prompt + self masks      video 8.9407e-08   audio 7.45058e-08
  audio stream disabled    video 8.9407e-08   audio 4.47035e-08
  dense self-attn mask     video 5.96046e-08  audio 4.47035e-08   (new)

DOCS. docs/FEATURES.md and docs/USAGE.md are touched only because
check-doc-checkpoint --staged refuses a change under src/vllm/model_executor/models/
and include/vllm/ without them. Both edits are minimal and keyed: the FEATURES
row gains "key-only and dense self-attention masks" and "prompt-bound" (trimmed
twice to stay inside check-public-doc-tables' 220-char cell cap), and USAGE gains
the paragraph a caller needs to not hit the new refusal by surprise.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
Phase L1 of the LTX-2.5 campaign, reviewed twice and repaired between.

vllm::multimodal::VideoEngine with a family registry that identifies a
checkpoint by its TENSOR NAMES, never by path or extension, and refuses when
zero or several families claim one. MiniMax-H3 moves behind it unchanged. The C
ABI grows to v18 by APPENDING only.

The seam exists for one reason, stated in its own header: a checkpoint handed to
the wrong family does not fail, it renders noise. Both review rounds attacked
exactly that. The first found that RegisterVideoFamily accepted a DUPLICATE
NAME, and that the two std::unique calls then hid the collision, so the
several-claimants refusal never fired and which loader ran was decided by link
order. The repair makes sortedness and uniqueness invariants of the table and
removes both std::unique calls rather than leave them looking like protection.

Evidence carried through both rounds unmoved, which is what makes the H3 move
believable: test_minimax_h3_video_fold 6 cases / 137 assertions, and the
test_capi v12 section 4 cases / 102 assertions. That second number is the ABI
additivity evidence. test_video_engine went 10/227 to 11/254.

Reviewed by two fresh agents, neither of which wrote the code. The second
confirmed the impostor loader never runs, that nothing depended on the removed
dedup, and that the new assertions compile out under NDEBUG while the throw that
actually enforces the invariant stays live in Release.

Issue: #435

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…pinned epsilons

Repairs the adversarial review of phase L4 (.agents/specs/ltx-2-5.md, issue #435,
PR #437). The review verdict was PASS conditional on three repairs: it reproduced
all 8 max|diff| values, confirmed the goldens rebuild byte-identically from
upstream, and survived 13 of its own mutations. Nothing was wrong with the math.
The defects were on the EVIDENCE and RECORD surfaces, plus one open hole class.

All 8 originally measured values are UNCHANGED by this commit:

  audio decoder              1.78814e-06     BWE vocoder chain    1.49012e-07
  audio decoder (freq pad)   1.78814e-06     Conv video decoder   1.40071e-06
  BigVGAN v2 vocoder         2.23517e-08     kaiser-sinc filter   2.98023e-08
  legacy resblock-1 vocoder  2.23517e-08     hann-sinc resample   1.16415e-08

R1 THE GOLDENS HAD NO UPSTREAM REVISION ANCHOR, and the generator never proved
which `ltx_core` it imported. AGENTS.md requires a ported test to preserve the
upstream revision anchor; grepping for one across the generator, the goldens,
both .cpp and both .h returned nothing. The generator now resolves
`git -C <--ltx2> rev-parse HEAD` and emits it as `kLtx2VaeUpstreamRevision`,
which the suite asserts equals the SHA it pins, so regenerating against a
different checkout FAILS instead of silently replacing the oracle.

The oracle-identity hole was real, not theoretical, and is demonstrated rather
than asserted. With a decoy `ltx_core` (upstream plus one drifted constant) on
PYTHONPATH and `sys.path.insert` refactored to `sys.path.append`, the OLD
generator imported the decoy, reported success, and emitted goldens with the
IDENTICAL md5 3af38d1d9f8e741ae5c2e2f6723d2779 -- the wrong oracle, undetectable.
The new `load_upstream` aborts with the resolved path named.

R2 THE VIDEO VAE'S f32 WAS UNANNOTATED, AND UPSTREAM DOES THE OPPOSITE. The
audio tower's f32 is upstream-grounded (vocoder.py:585-595 forces float32 for the
BWE chain). The video decoder has no such justification: it runs in the CHECKPOINT
dtype, `sample.to(weights_dtype)` in and `sample.to(output_dtype)` out
(conv_video_decoder.py:283-286, 355-356). This is AGENTS.md's "a token gate cannot
catch a dtype that is too WIDE" exactly, and the golden structurally cannot catch
it because `fill_from_stream` casts every weight to f32, so the ORACLE runs f32
too. Annotated, with phase L6 named as owing the checkpoint-dtype arm. Numerics
unchanged.

R3 THE DUPLICATED 1-D PRIMITIVES ARE NOW ONE IMPLEMENTATION. ltx2_audio_vae.cpp
carried its own Conv1d, ConvTranspose1d, pad, Snake and alias-free Activation1d
because MiniMax-H3's were TU-private -- a parallel path, argued only in a source
comment. H3's are promoted to minimax_h3.h (generalized: the pad takes a
`replicate` flag, Snake takes an optional beta) and LTX now calls them; 172 lines
of duplicate deleted.

BEHAVIOUR-PRESERVING, measured against the base SHA rather than assumed:

  test_minimax_h3             79 cases / 57395 assertions   before AND after
  test_minimax_h3_video_fold   6 cases /   137 assertions   before AND after

And the seam is proven to be one seam: mutating the SHARED upsample gain
(`value *= ratio` -> `* 1.01f`) with ONE edit turns BOTH suites red (ltx2 4 cases,
h3 1 case). Before this commit that same edit could not have touched LTX at all.

R4 THE INVISIBLE-CONSTANT CLASS IS CLOSED, NOT ONE INSTANCE. The author pinned
`pixel_norm_eps`; the review found four more that survive mutation with every
golden green. All are correct against upstream, and nothing held them. Each is now
a named constant with a source-anchored assertion, and the header note says the
limit is a CLASS. Mutations, all RED after this commit:

  norm_eps 1e-6 -> 1e-4        (resnet.py:31)          RED
  mel log clamp 1e-5 -> 1e-8   (vocoder.py:515)        RED, 2 cases
  Snake eps 1e-9 -> 0.0        (vocoder.py:198, :221)  RED
  _RMSNorm2D floor 1e-12 -> 0  (attention.py:11-30)    RED

The mel clamp gets more than a constant assertion, because it is the member of
the class that BINDS IN PRODUCTION: it floors the log-mel fed to the BWE
generator, and real silence reaches it. The reduced-dimension stream could not,
measured: the raw mel minimum is ~4.4e-3 and STAYS there even for a zero input,
because the vocoder's conv biases keep the waveform off silence. A new arm
attenuates mel_basis by 1e-4 so all 384 bins saturate. It catches the mutation
NUMERICALLY, not just by constant: 4.07919e-07 -> 0.144965.

R5 act_post WAS CONDITIONAL, UPSTREAM MAKES IT UNCONDITIONAL. `self.act_post =
Activation1d(SnakeBeta(final_channels))` (vocoder.py:388) sits inside `if
self.is_amp` and takes no `activation=` argument, unlike the resblocks one line
earlier (vocoder.py:376). Reading `.beta` only when `snakebeta` made that one
activation silently reuse ALPHA as its reciprocal scale on the `activation="snake"`
arm. Fixed and gated by a new arm; upstream's own state_dict is the second half of
the proof, carrying `act_post.act.beta` while every `acts1/acts2` entry has only
`.alpha`. Reverting the fix goes RED.

R6 the header claimed the vocoder defaults mirror `Vocoder.__init__`, whose
defaults are `resblock="1"` / `activation="snake"` while ours are AMP1/snakebeta.
The DEFAULTS are right and the comment was wrong: VocoderConfigurator's BWE branch
REQUIRES both via check_config_value (model_configurator.py:59-64), so a default
mirroring `Vocoder.__init__` would be one no shipping checkpoint can use. Comment
corrected.

R7 a comment said conv_in is "ALWAYS causal upstream ... independently of
config.causal" directly above a line passing `config.causal`. The CODE is right:
`causal=True` at conv_video_decoder.py:216 selects the CausalConv3d MODULE, while
runtime one-sidedness comes from `self.conv_in(sample, causal=self.causal)` at
:307. Corrected, because as written it invited a future "fix" that breaks it.

R8 FOUR ARMS WERE UNGATED, INCLUDING UPSTREAM'S OWN DEFAULT. `causal=False` is
the declared default (conv_video_decoder.py:184) yet every video arm ran
causal=True, and the audio kNone / kWidth / kWidthCompatibility axes never ran.
Added, and each independently reproduces the reviewer's measurement:

  non-causal Conv video decoder   1.81794e-06
  audio causality_axis NONE       1.56462e-06
  audio causality_axis WIDTH      9.14559e-07
  audio WIDTH_COMPATIBILITY       7.00355e-07

The non-causal arm shares the causal arm's weights, input and noise stream, so
the padding rule is the only difference and the test asserts the two DIVERGE.
Collapsing the non-causal pad into the causal rule goes RED; so does collapsing
WIDTH_COMPATIBILITY into WIDTH, which is the subtle one -- upsample.py:44-48 does
NOT drop the first element for that axis.

R9 the tolerances sat 6-447x above what the port produces, which makes them
decoration. Replaced with two derived constants: kLtx2GoldenTol 5e-6 (~2.7x over
the worst arm, 1.81794e-06) and kLtx2FilterTol 1e-7 (~3.4x over 2.98023e-08). The
margin is for libm, not for us: our reductions accumulate in double against fixed
golden constants, so reduction order cannot reach them, but sin/exp/tanh/sqrt
differ by ~1 ulp between implementations and the vocoder composes them deeply. A
structural porting error moves these by orders of magnitude, not ulps.

GATE. Clean Release build, -Werror, ZERO warnings. Full ctest 391/391 passed.
Debug build of the affected targets green with identical counts (a full Debug
build of all 391 targets exhausted disk on this box and was scoped down rather
than worked around).

  test_ltx2_vae   10 cases / 1120 assertions  ->  16 cases / 1816 assertions
  goldens         md5 3af38d1d...  ->  e96b7a582ce7548d10ed3c40de725e3d

The new md5 is expected: the goldens gained the revision anchor and six arms.
Every PRE-EXISTING golden line is byte-identical (diff shows zero removed or
changed lines), and the file still rebuilds byte-for-byte from the generator.

DOC CHECKPOINT. b0aa475 argued an exception for docs/FEATURES.md and
docs/USAGE.md, on the grounds that the campaign runs several implementers in
parallel and the operator holds the record surfaces. This commit PAYS that debt
instead of inheriting it, with one keyed FEATURES row and one scoped USAGE
subsection stating that LTX-2.5 has no user-facing entrypoint yet -- so a reader
cannot infer a render is available -- and naming the DiffVAE refusal. The range
checker still reports b0aa475 itself, which cannot be repaired without rewriting
history; the campaign lands as one squashed PR, at which point the combined change
carries both documents.

Every mutation above restored the tree byte-for-byte, verified by md5.

FOLLOWING_AGENTS_PROTOCOL

Refs #435
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
Two findings about the METHOD, from the L2/L3/L4 review rounds. They compound,
and together they change what this campaign's evidence is evidence OF. Recording
them in 7.0 because they apply to every future brick, not just LTX-2.5.

(a) There is a CLASS of constants a reduced-dimension golden cannot see. Not one
constant, a class, confirmed independently on two phases. An epsilon, a clamp
bound or a normalize floor only becomes load-bearing in a regime the synthetic
fixture never enters. Seven are now tabulated with the mutation that stayed
green, including a norm_eps that tolerates a 100x change and a BWE mel log clamp
that the fixture cannot saturate because mel_basis is built non-negative and
well-scaled, while REAL SILENCE saturates it in production.

The repair is not a tighter tolerance, because the tolerance was never the
problem. It is a source-anchored constant assertion pinning the value to the
upstream line it came from, plus, where feasible, a golden arm whose input
actually enters the regime.

(b) Byte-identical goldens are NOT evidence the oracle was right. L4's repair
tested this rather than assuming it: with a decoy ltx_core differing by ONE
drifted constant and path precedence defeated, the generator imported the decoy,
exited 0, and emitted goldens whose md5 matched the real ones exactly.

That is (a) and (b) compounding. A drifted constant from the invisible class
produces identical goldens, so "the goldens reproduce byte-for-byte" cannot
distinguish the right oracle from a wrong one. Reproducibility proves
determinism. It does not prove provenance.

So every generator here owes TWO separate things: assert the resolved
ltx_core.__file__ lives under the --ltx2 checkout (identity), and record the
upstream revision SHA in the emitted goldens (provenance). AGENTS.md already
required the anchor; the identity assertion is what makes the anchor mean
anything.

Issue: #435

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
Phase L2, reviewed and repaired. The 21.00B dual-stream DiT forward, gated
against upstream ltx_core executed at reduced dimensions on CPU.

Parity, independently reproduced by the reviewer rather than taken on the
implementer's word: 1.19209e-07 video / 4.84288e-08 audio on split RoPE, with
interleaved RoPE, the float64 frequency ladder, the mask cases and audio-disabled
all in the same band, plus a new dense-mask arm at 5.96046e-08.

RED-first found a real defect on the first run: computing rope.py's linspace in
double instead of reproducing ATen's f32 half-forward/half-backward walk moved
two of eight AUDIO samples by one ulp, which the 5-sample video ladder hid
completely. The reviewer went further and showed the FULL FORWARD also misses it,
because the drift stays under the round-off bar; only the bit-equality ladder
assert catches it at all.

Review returned FAIL on two ungated shipped paths, both now closed. The prompt
K/V cache carried no prompt identity and its only validity check was on SIZE, so
two requests whose prompts differ but tokenize to the same length would have
rendered the second with the FIRST request's prompt, silently. It now carries an
FNV-1a identity over both streams' contents, geometry and masks, refuses naming
what moved, and offers an additive Reset(). The dense [Tq, S] attention bias had
ZERO coverage.

One methodological note worth keeping: the reviewer's original F1 mutation did
not compile under -Werror, so its 'green' run was a STALE BINARY. The repair
verified the coverage gap with a semantically identical mutation that does
compile, rather than dismissing the finding.

Issue: #435

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]

# Conflicts:
#	tests/CMakeLists.txt
…, pin the epsilons

Repairs the three findings from the adversarial review of phase L3 of
.agents/specs/ltx-2-5.md (issue #435, PR #437). The verdict was PASS with 3
findings, none blocking: the math was right and every claimed number reproduced.
This closes the contract hole and the two recorded gaps. No numerics change: all
8 measured max|diff| values are byte-for-byte what L3 recorded, and
scripts/gen-ltx2-text-goldens.py still regenerates the existing goldens
BYTE-IDENTICALLY (md5 1a803faa... before, and the new section is purely appended).

F1, MEDIUM. THE DECLARED CONTRACT WAS NEVER CHECKED AGAINST THE WEIGHTS.
`Ltx2TextFeatureConfig::aggregate_bias` was written by the selector
(ltx2_text_encoder.cpp:130, :166), asserted in the selection test and NEVER READ
by the forward, which keyed entirely on `w.bias.empty()`. `video_out_features`
fed only `_rescale_norm`; the width that actually ran came from `w.out_features`
and nothing compared the two. `const int64_t flat = config.FlatDim()` was dead.

The reviewer demonstrated both, and they ran silently:

  PROBE(a): bias-less weights under aggregate_bias=true ran SILENTLY,
            video drifts 0.0194063 from upstream
  PROBE(b): out_features mismatch ran SILENTLY, video size = 80 while
            config claimed 40
  [doctest] test cases: 16 | 16 passed | 0 failed   Status: SUCCESS!

That is phase L6's most likely mistake, not a hypothetical: the loader reads
`video_aggregate_embed.weight` (U8/NVFP4) and misses `.bias` (BF16, a DIFFERENT
dtype on a different unpack path) while the config still says bias=True. Every
conditioning row is then shifted by the missing bias and every padded row
projects to 0 instead of to the bias. Finite, correctly shaped, wrong prompt.
ltx2_text_encoder.h:57-60 already listed exactly this under "THE FOUR THINGS THAT
FAIL SILENTLY" — the header named it and the code did not enforce it.

`RequireDeclaredProjection` now refuses, BY NAME and before any work, on all
three axes: `aggregate_bias` vs `w.bias.empty()`, `*_out_features` vs
`w.out_features`, and `FlatDim()` vs `w.in_features`. The third is what the dead
`flat` becomes, so the "+1 is the embedding layer" trap is caught from the weight
side too. Only the projections that actually RUN are checked: V1 uses `video`
alone and returns it twice under `is_av` (feature_extractor.py:95-96), and V2's
audio arm exists only when the config gave it a width. Upstream cannot hit any of
these because it builds both Linears from the one config object
(encoder_configurator.py:187, 206-208); a port that resolves the config and the
tensors on separate paths can.

The same two probes, re-run verbatim against the fixed library:

  PROBE(a): REFUSED -> ltx2 text encoder: video projection: the config declares
            aggregate_bias=true but the supplied weights carry NO bias. ...
  PROBE(b): REFUSED -> ltx2 text encoder: video projection: the config declares
            out_features=4 but the supplied weights are 8 wide. ...
  CONTROL : accepted, video size = 80 audio size = 40
  probes refused = 2 of 2

No caller breaks: `Ltx2TextFeatureExtractorForward` and
`Ltx2TextEncoderConditioning` have no production call site (grep over src,
include, tests, examples), and the CONTROL line above is the honest half of the
gate — the correct weights still go through the same door, asserted for V1, V2
and both entry points.

F2, LOW. TWO INVISIBLE EPSILONS, THE SAME CLASS L4'S REVIEW FOUND. Both constants
were present and faithful to upstream and nothing held them. Measured on this
suite BEFORE the pins: `range + kEps` -> `range + 0.0f` moved norm V1's max|diff|
from 4.77e-07 to 5.24521e-06 and the gate still said SUCCESS, because 5.2e-06 is
under the suite's 1e-5 bound. `denom + kEps` -> `denom + 0.0` moved nothing.

The reason is structural, and it is why the fix is not "one more golden": an
epsilon that only changes the answer on a DEGENERATE input is invisible to any
golden built from random values. So both are now held TWO ways.

  * The VALUE, against upstream MEASURED rather than restated. The generator
    recovers each epsilon numerically from upstream by a probe whose algebra
    inverts it exactly: for V1, two valid tokens differing by exactly r make
    range_ == r and the DIFFERENCE of the two outputs cancels the mean, giving
    eps = 8r/(y0-y1) - r; for V2, a single element v gives eps = (v/y)^2 - v^2.
    No source parsing and no restating our own constant back to ourselves.
    Recovered: 9.9998279390984754e-07 and 9.9999993911447867e-07.
  * The DEGENERATE INPUT on which each is the only thing between the port and a
    division by zero, with upstream's own behaviour on that input emitted as a
    golden so the property asserted is measured and not invented.

`kLtx2TextNormV1Eps` and `kLtx2TextNormV2Eps` are now named in the header, used
by the .cpp, and carry their reachability conditions next to them, plus a header
note that the epsilon limit is a CLASS: when a fourth epsilon arrives it owes the
same pair, not a comment saying it matches upstream.

MUTATION-VERIFIED, tree restored byte-for-byte (md5 checked both ways):

  M1  range + kEps -> range + 0.0f      FAILURE, 168 assertions, the new case
                                        (7 valid tokens x 24 features, all NaN)
  M3  kLtx2TextNormV1Eps -> 0.0         FAILURE, 169 (168 + the value pin)
  M4  kLtx2TextNormV2Eps -> 0.0f        FAILURE, 27 across 2 cases
  M5b variance + kEps -> + 0.0f*kEps    FAILURE, 26 across 2 cases
  M6  encoded_mask < 1e-6f -> < 0.0f    FAILURE, 34
  M2  denom + kEps -> denom + 0.0       SUCCESS, still invisible. REPORTED, not
                                        papered over: see below.

M2 is stated in the test and the header as a LIMIT rather than a pass. That
epsilon is unobservable at the output FOR EVERY POSSIBLE INPUT, not merely for
this fixture: `denom == 0` requires a batch row with no valid token, and every
position of such a row is a pad that feature_extractor.py:44-45 zeroes, so the
NaN it prevents in the intermediate `mean` can never escape. Upstream behaves
identically, which the generator now emits as a golden
(kLtxTeNormV1ZeroLenRowIsZero). It is mirrored because upstream has it and held
by the constant assertion, which M3 proves is load-bearing. Claiming a behavioural
gate on it would have been false.

M5 in its natural form (`variance + kEps` -> `variance`) does not COMPILE:
-Werror=unused-variable. That is the exact trap this campaign was warned about,
and the harness reported BUILD_EXIT=1 and refused to run the stale binary rather
than printing a green gate from a build that never happened. M5b is the
compile-clean equivalent.

F3, LOW. `f32` ON A MODEL PATH WITHOUT A LOCAL REASON. `Gemma4HiddenStatesResult`
returns `std::vector<std::vector<float>>` downloaded from BF16 device buffers
(gemma4.cpp:571-578) while upstream runs this path in bf16 (base_encoder.py:41,
`dtype: torch.dtype = torch.bfloat16`) and its `hidden_states` tuple is bf16. The
reason existed in ltx2_text_encoder.h:62-72 and in L3's commit body, and every
LTX entry point refuses a non-f32 compute dtype rather than widening silently,
which is gated. But gemma4.h stated "host f32" as bare fact and AGENTS.md's
dtype-polarity rule wants the line next to the buffer. It is there now, naming
the CPU-reference-arm reason, upstream's bf16 dtype, the host cost (~771 MB at
49 x 1024 x 3840 x 4B where upstream holds ~385 MB) and phase L6 as the owner of
the bf16 arm. Comment only; no numerics touched.

DOCS, and why this commit touches them. The operator scoped docs/* out of this
task, but check-doc-checkpoint --staged is RED without them:
src/vllm/model_executor/models/ classifies as feature_surface and include/vllm/
as user_usage, both by blanket prefix. The edits are minimal, keyed and LTX-2.5
only: the existing FEATURES.md row for this feature moves 15/15 -> 17/17 and
gains the refusal (no new row, no collision with L2's or L4's rows, and the cell
stays under check-public-doc-tables' 220-char entry cap), and USAGE.md's existing
LTX-2.5 section gains one paragraph on the contract refusal, which is
user-visible behaviour for anyone wiring a loader. BENCHMARKS.md is untouched:
this is not a lifecycle change. Flagged for operator reconciliation rather than
done silently.

EVIDENCE.
  RED before F1: 17 cases, 16 passed / 1 failed; assertions 3340 | 3330 passed |
    10 failed; Status: FAILURE! — every failure "did NOT throw at all!", which is
    the intended reason.
  GREEN after:   17 cases / 3340 assertions, Status: SUCCESS!  (was 15 / 2473)
  All 8 max|diff| values UNCHANGED: stack 0 BIT-equal; norm V1 4.76837e-07 both
    sides; norm V2 2.38419e-07 both sides; V2 extractor 4.47035e-08 / 5.96046e-08
    video, 2.98023e-08 audio; V1 extractor 6.51926e-08 / 5.96046e-08;
    conditioning 4.47035e-08 / 5.96046e-08 video, 2.98023e-08 audio; gemma4
    lm_head invariant 2.04891e-08 over max|value| 0.166625.
  Goldens regenerate BYTE-IDENTICALLY; the revision anchor
    fd4ded7f2d88d3da713abcdd4ad41ecc4a9314ca is still present.
  Gemma-4 gate counts UNCHANGED: test_gemma4_honesty 2/6,
    test_gemma4_rocm_fp8_seams 2/10, test_gemma3_forward 3/503,
    test_tool_parser_gemma4 72/161, and test_gemma4_{vision_tower,registry_e2e,
    audio_tower,paged_engine} 1 case / 0 assertions each. All SUCCESS!
  Clean Release -Werror CPU-only rebuild from an EMPTY tree, 0 warning lines;
    full ctest 391/391, 0 failed.
  Environmental, reported as such: the first clean rebuild died with
    "No space left on device" writing /tmp/cc*.s at 100% disk. That is the box,
    not the change; it cleared and the rebuild was redone from empty.

FOLLOWING_AGENTS_PROTOCOL

Refs #435
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…435)

Phase L4, reviewed twice and repaired between. Both VAE decoders gated against
upstream ltx_core executed at reduced dimensions, max abs diff 1.16e-08 to
1.79e-06 across eight bricks, every value independently reproduced by two
reviewers.

Three things this phase established that are worth more than the numbers.

The audio VAE is NOT end-to-end causal, and it was MEASURED rather than assumed:
the first causality probes failed and upstream agreed with the failure.
causality_axis governs the convolutions, but the AttnBlocks attend over the whole
(time, mel) map. The Conv video decoder is not causal either, for an unrelated
reason: a one-group GroupNorm whose statistics span time. Both are now gated in
two parts, with upstream supplying the expected windows.

Byte-identical goldens do NOT prove the oracle was right. The repair tested this
instead of asserting it: a decoy ltx_core differing by ONE drifted constant, with
path precedence defeated, produced goldens with an IDENTICAL md5. The generator
now asserts the resolved ltx_core.__file__ is the checkout's and records the
upstream revision. Identity and provenance are separate obligations and this
phase needed both.

The shared-seam finding took the harder route. Rather than documenting the
duplication as an exception, H3's 1-D primitives were promoted to the shared
header and 172 lines of LTX duplicate deleted. It is genuinely one seam now,
proven by mutating a shared primitive with ONE edit and watching BOTH suites go
red, where at the base SHA that same edit could not reach LTX at all. H3's own
gates measured identical at both SHAs by the reviewer: 79 cases / 57395
assertions, and 6 / 137.

docs/FEATURES.md conflicted on the shared LTX-2.5 row, which is the collision the
L4 reviewer predicted. Resolved per AGENTS.md by taking the target row wholesale
and reapplying the scoped edit, so both phases' claims survive in one row rather
than either eviction winning. Both CMake lists resolved as unions.

Two MEDIUM findings from the re-review stay OPEN and are owed on this PR: a DIRTY
upstream tree still defeats the revision anchor (rev-parse reports the committed
SHA regardless of uncommitted edits), and the audio decoder's own norm_eps is an
unpinned member of the invisible-constant class its sibling pins.

Issue: #435

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…put that proves it

Closes the one MEDIUM finding the scoped re-review of L3's repair returned FAIL
on (issue #435, phase L3 of .agents/specs/ltx-2-5.md). The rest of that repair is
untouched and re-verified below.

THE DEFECT. `Ltx2NormAndConcatPaddedBatch` computed `denom + eps` in double.
Upstream computes it in float32, and not by choice: `sequence_lengths` is an
int64 tensor (feature_extractor.py:30), `* d` keeps it int64 (:34), and torch
promotes an int64 tensor plus a python float to the DEFAULT dtype, so the add at
:35 happens in f32. Measured against the pinned oracle at fd4ded7f:

    torch: (int64 18) + 1e-6 -> dtype=torch.float32, 18.000001907348633
    our double:               18 + 1e-6 =            18.000001000000001
    upstream mean = f32(9.0/18.000001907348633) =    0.49999994039535522
    our      mean = f32(9.0/18.000001000000001) =    0.49999997019767761

One f32 ulp. This is AGENTS.md's dtype-polarity rule in its exact stated form:
too WIDE is still numerically finer, so tokens match, every random golden passes
and nothing goes red. `range_ + eps` at :41 then multiplies that ulp by 8/eps =
8e6 whenever a (batch, layer) slice is constant, which turns it into 23842x the
suite's own kTol.

THE GATE WAS DEFINED DOWN. scripts/gen-ltx2-text-goldens.py ran upstream on
exactly the falsifying input, had the whole output tensor in `const_out`, and
reduced it to `kLtxTeNormV1ConstantSliceFinite = 1`. Both a float32 and a float64
denominator are finite, so the assertion could not see the defect. Two further
degenerate cases were reduced the same way. That is the reason this commit is
mostly test and generator: the port defect is two lines.

RED FIRST. Emitting the arrays with the dtype still unfixed:

  test_ltx2_text_encoder.cpp:938: MESSAGE: ltx2 text norm V1 constant slice max|diff| = 0.238419
  test_ltx2_text_encoder.cpp:939: ERROR: CHECK( worst < kTol ) is NOT correct!
    values: CHECK( 0.238419 <  1e-05 )
  test_ltx2_text_encoder.cpp:1002: MESSAGE: ltx2 text norm V1 near-constant max|diff| = 0.238419
  test_ltx2_text_encoder.cpp:1003: ERROR: CHECK( worst < kTol ) is NOT correct!
    values: CHECK( 0.238419 <  1e-05 )
  [doctest] test cases:   1 |   0 passed | 1 failed | 16 skipped
  [doctest] assertions: 861 | 859 passed | 2 failed |
  [doctest] Status: FAILURE!

GREEN after mirroring the denominator: those two read 0, and so does the
one-valid-token case. 17/17 cases, 3350/3350 assertions, Status: SUCCESS!

WHAT CHANGED IN THE PORT. `denom` becomes int64, as upstream's is, and the add
and divide happen in f32. The min/max become f32 too: they ARE f32 values, so
`hi - lo` is then upstream's single f32 rounding instead of an f64 subtraction
rounded twice.

The f64 SUM accumulator STAYS, and is now annotated with the measurement rather
than left bare. Upstream's `masked.sum` is an f32 reduction but a blocked one, so
no straight loop reproduces its order. Measured on this fixture against upstream:

    f64 accumulate   2.38e-07 (left)  4.77e-07 (right)
    f32 accumulate   4.77e-07 (left)  2.38e-07 (right)

A naive f32 accumulate wins on one mask and loses on the other, which is noise,
not a mirror. Accumulating exactly and rounding once is the closest
single-rounding approximation to any order, so it is the deliberate escape.

THE THREE FALSE CLAIMS. ltx2_text_encoder.h:143-148, the test's section 3 and the
generator's docstring each asserted that `denom + eps` is "UNOBSERVABLE at the
output for every possible input". It is not. It is unobservable on an all-pad row
or an all-zero mask, where :44-45 zeroes every position first. All three now say
that, name the falsifying input and its two numbers, and record that on a
realistic Gemma workload `range_` is O(1) so the same perturbation lands around
2e-12. A public header that overstates an invariant is worse than one that says
nothing, because the next reader trusts it.

Also fixes the off-by-one at ltx2_text_encoder.h:139: upstream defines `denom` at
feature_extractor.py:34 and adds `eps` at :35.

MUTATION. `denom + kEps` -> `denom + 0.0` was Status: SUCCESS before this change,
which is what the old comment's "moved nothing at all" recorded. Against the
arrays it now fails three gates, at 0.476837 (constant slice), 0.715256 (one
valid token) and 0.476837 (near-constant). Tree restored byte-for-byte
afterwards, md5 6ccebc95657cb91613e486152bc1925f.

NOT REGRESSED. The generator reproduced every pre-existing golden BYTE-IDENTICALLY
(219 insertions, 0 deletions), so the upstream anchor is intact and no prior value
drifted. The epsilon value pins are unchanged at 9.9998279390984754e-07 and
9.9999993911447867e-07. F1's `RequireDeclaredProjection` refuses by name on all
seven out-of-tree probes and the control is still accepted; A/B'd against a
library built from the pre-change source, the probe output is byte-identical.
gemma4.h is not in the diff, and its eight gates read 2/6, 2/10, 3/503, 72/161
and 1 case / 0 assertions x4, all SUCCESS.

Of the eight max|diff| values, six are unchanged and the two the reviewer
predicted improve: norm V1 (left) 4.76837e-07 -> 2.38419e-07, V1 extractor (left)
6.51926e-08 -> 5.96046e-08. Nothing got worse. docs/FEATURES.md carries the
extractor number, so it moves 6.5e-08 -> 6.0e-08.

Full gate: 391 tests, 389 passed under -j 4; test_serve_low_tools and
test_engine_core_proc failed on contention and both pass serially.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
Phase L3, three review rounds. The multi-layer feature aggregation, both
normalization variants, the two caption projections, mask and pad handling, and
the embedded tokenizer/asset pack.

The architectural finding first: LTX does NOT condition on the encoder's last
hidden state. feature_extractor.py normalizes [B, T, D, L] and concatenates
ACROSS LAYERS, so the projections take 3840 x 49 = 188160 inputs. The operator's
brief said 94080 = 1920 x 49, reading the checkpoint's NVFP4-packed U8 widths as
logical; L3 caught it. Two values per byte, so every packed width is half. The
BF16 tensors in the same file settle it.

Round 1 PASSED with three findings: the declared weight contract was never
enforced, two epsilons were invisible, and an f32 lacked its reason. Round 2
fixed those but FAILED re-review, and that failure is the one worth recording.

The port computed denom + eps in DOUBLE where upstream promotes int64 + python
float to FLOAT32 (feature_extractor.py:34-35). One f32 ulp in the mean, amplified
by 8/eps = 8e6 wherever the range collapses. It survived because the generator
RAN upstream on the falsifying input, had the full output array, and reduced it
to a single boolean, so the test asserted only isfinite. Emitting the array shows
0.238418579 against upstream's 0.476837158 -- 23,842x the suite's own tolerance,
on a case the test already constructed. That is exactly the too-WIDE dtype
AGENTS.md says a token gate cannot catch, hiding behind an oracle narrowed to a
bool.

Round 3 mirrors upstream's arithmetic width and emits arrays. The re-reviewer
checked BITS rather than tolerance: 0 differing f32 bits against upstream on all
three degenerate inputs, where the old code differed by 72. Two pinned values
improved as predicted and none regressed.

One judgement kept rather than swept: the f64 sum accumulator stays, because a
naive f32 loop wins on one mask and loses on the other -- noise, not a mirror,
since upstream's masked.sum is a blocked reduction no flat loop reproduces. The
measurement is annotated beside it. The re-reviewer independently confirmed that
torch.sum over the same gathered values also fails to reproduce upstream's order,
which is the stronger datum.

docs/FEATURES.md conflicted again on the shared row. L3 branched before L2 and L4
landed, so its side carried a STALE DiT row plus a genuinely new text row.
Resolved per AGENTS.md by keeping the target row wholesale and reapplying only
the scoped addition, so no phase's claims were evicted by an older snapshot.

Open and owed, not dropped: the V2 per-token-RMS path carries the same too-wide
class (it squares in f64 where upstream squares in f32) and wants measuring at
shipped widths rather than a blind narrowing, since the fixture runs D=6 against
a shipped 3840.

Issue: #435

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
mudler added 6 commits August 12, 2026 04:49
Phase L5 of .agents/specs/ltx-2-5.md, issue #435: the flow-matching schedule,
the noiser, four diffusion steps, guidance, the patchifiers, the recipe table,
the latent spatial x2 upsampler, the duration head, and the Embeddings1DConnector
that was orphaned between L2 and L3.

Every brick is gated against the UPSTREAM module executed at reduced dimensions
on CPU, with both sides rebuilding weights and inputs from one deterministic
FNV-1a + splitmix64 stream, so no weight byte is checked in. Measured max abs
diff per brick, worst arms: schedules 2.80e-06, upsampler 1.19e-06, connector
7.75e-07, diffusion steps 5.96e-08, duration head 0 (pooler 8.94e-08),
patchifiers and perturbations bit-exact. 33 cases / 1512 assertions.

WHERE THE VALUES COME FROM, because the two references disagree. vLLM-Omni is
the binding oracle and its recipe table stops at 2.3, so the three rows this
adds -- one_stage 2.4, one_stage 2.5, distilled_two_stage 2.5 -- take their
values from Lightricks ltx-pipelines, which is the spec's designated cross-check.
The SHAPE of the recipe model stays vLLM-Omni's, and its refusal on an unknown
(kind, version) pair is mirrored exactly rather than relaxed: a plausible but
wrong sigma schedule renders a video instead of failing. The two references also
ship DIFFERENT default negative prompts; both strings are kept, each row takes
its own source's, and the disagreement is a gated value rather than a preference.
Recorded in .agents/porting-inventory.md §9.18.

THREE PROJECTION GUIDERS ARE REFUSED, and the refusal is a measurement.
CFGStarRescalingGuider, LtxAPGGuider and LegacyStatefulAPGGuider all multiply
projection_coef's rank-2 (B, 1) result straight into the latent, which torch
right-aligns onto the latent's last two axes: the expression composes at rank 2,
raises at every rectangular rank >= 3 -- i.e. at every real (B, C, F, H, W) video
latent -- and on a coincidentally square shape silently indexes an axis that is
not the batch. No ltx-pipelines entry point constructs any of the three. The
shape matrix that measurement produced is itself a golden, so upstream repairing
the shapes fails this gate rather than going unnoticed.

THE GENERATOR REFUSES A DIRTY UPSTREAM TREE. Spec §7.0(b) established that
byte-identical goldens are not evidence the oracle was right; the revision anchor
is what makes them interpretable. An anchor read from a tree with uncommitted
edits stamps a clean SHA on goldens that SHA does not produce, which survives a
bisect and misdirects it, so both --ltx2 and --vllm-omni must be clean. The
oracle-identity assertion (resolved ltx_core.__file__ under --ltx2) is kept from
L2/L4.

TWO FINDINGS RECORDED RATHER THAN PAPERED OVER.

(a) The duration head's fixture had to be WIDENED, and that is a gate property.
Its output is exp(...) through an attenuating chain, so at the shared 0.05
parameter scale its both / video-only / audio-only arms collapsed to within
2.98e-06 of one another -- BELOW this suite's round-off bound. A gate that cannot
separate its arms would accept an implementation that ignored one of the two
streams. Measured spreads: 0.05 -> 2.98e-06, 0.2 -> 2.3e-03, 0.35 -> 4.9e-02.
The fixture uses 0.35 and the separation is now asserted, so a future change that
collapses it fails loudly.

(b) The concat ORDER of the two streams is NOT observable, and that is upstream's
property, not a hole. A mutation reversing it left every golden green;
AttentionPooler is cross-attention with no mask and no positional encoding over
the token axis, so it is permutation invariant. Measured on upstream: a reversed
concat and a random permutation each move the pooled output by 2.98e-08, while
giving the audio stream the VIDEO modality embedding moves it by 4.80e-03. What
tags a stream is the embedding, and both facts are now gated.

INVISIBLE-CONSTANT CLASS (spec §7.0(a)). Each constant this phase introduces
carries a source-anchored assertion, and the two whose regime is reachable also
carry a golden that ENTERS it: kLtx2CfgPpAlphaEps binds at step 0 where sigma is
exactly 1.0, and kLtx2ProjectionCoefEps binds on an all-zero project_onto. The
unreachable ones -- kLtx2Res2sSigmaUpClamp, kLtx2UpsamplerNormEps,
kLtx2ConnectorRmsNormEps -- are pinned against their upstream line and said to be
unreachable rather than claimed as covered.

DTYPE. f32 throughout, which is upstream's OWN width on these paths (the noiser
lerps in .float(), every diffusion step casts to torch.float32, the guider opens
with cond.float()). The two schedulers do NOT agree on width and both are
mirrored: LTX2Scheduler is float32 tensors with a Python-double shift term,
LinearQuadraticScheduler is double throughout and narrows once at the end. The
one deliberate NARROWING is Embeddings1DConnector.learnable_registers, which
upstream stores in bfloat16; keeping it at f32 would be wider than upstream and
only the padded positions would move, so the rounding is explicit and gated on
its own golden.

DOCS. docs/FEATURES.md and docs/USAGE.md are edited because
check-doc-checkpoint --staged refuses otherwise: the checker classifies any
src/vllm/model_executor/models/ and include/vllm/ change as feature_surface and
user_usage. The edits are minimal and keyed -- the existing LTX-2.5 row and the
existing LTX-2.5 sections -- and they say what is now gated and what is still
refused, not that a render exists.

Refused by name and recorded as owed: the temporal x2 upsampler, LoRA fusion,
multishot, int8-convrot, CFG/multi-GPU parallelism, VideoEngine wiring (L7), the
Beta scheduler (it inverts a Beta CDF through scipy and no pipeline constructs
it), the upsampler's dims=2 arm, and the three projection guiders above.

Unchanged baselines: test_ltx2 29/1615, test_ltx2_vae 16/1816, test_minimax_h3
79/57395, test_minimax_h3_video_fold 6/137, test_video_engine 11/254,
test_capi 'capi v12*' 4/102. Full ctest 394/394 on a clean Release -Werror
CPU-only build with zero warnings.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
L3 landed after this branch's base (0cb654a), so the two share three keyed
surfaces: CMakeLists.txt, tests/CMakeLists.txt and docs/FEATURES.md. Each is
resolved by taking the TARGET branch version wholesale and reapplying this
branch's scoped edit, per AGENTS.md §Records, rather than accepting an automatic
three-way merge of a keyed record. Concretely:

  CMakeLists.txt / tests/CMakeLists.txt  L3's text-encoder entries kept, L5's four
                                         pipeline entries appended after them.
  docs/FEATURES.md                       L3's new text-conditioning row kept; the
                                         LTX-2.5 DiT row takes L5's text.
  docs/USAGE.md                          auto-merged, both sections verified
                                         present and intact.

ONE KEYED CELL CORRECTED, because the merge makes it false. L3's text row said
"`Embeddings1DConnector` and the quantized arm are owed". L5 ships the connector,
so the cell now reads "`Embeddings1DConnector` landed in L5; the quantized arm is
owed". Leaving it would have recorded an owed item that is not owed, which is
exactly the drift a keyed table exists to prevent.

Re-gated on the MERGED tree, not on either parent: clean Release -Werror CPU-only
build with zero warnings, full ctest 395/395. Unchanged baselines hold:
test_ltx2 29/1615, test_ltx2_vae 16/1816, test_minimax_h3 79/57395,
test_minimax_h3_video_fold 6/137, test_video_engine 11/254, test_capi 'capi v12*'
4/102, plus L3's own test_ltx2_text_encoder 17/3350 and L5's
test_ltx2_pipeline 33/1512.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
… same defect

7.0 gains a third finding, from L5's review, and it is the sharpest instance
this campaign has produced.

L5's linspace mirror -- the two-sided walk that lands the last sigma on EXACTLY
0 -- was declared load-bearing in a comment and was NOT GATED AT ALL. Swapping
it for a naive forward walk left 33 cases and 1512 assertions green. That is not
cosmetic: for 23 of the first 198 step counts the naive walk misses exact zero,
and at steps=41 a 5.96e-08 terminal survives the sigma==0 guard, takes the shift
transform, and displaces last_non_zero, moving the WHOLE schedule by 0.1 so the
denoise loop never reaches zero noise. A plain --steps 41 renders confidently and
wrongly.

It hid because the fixture exercises steps in {8,6,5,1,4,7}, every one of which
the broken walk happens to get right.

Two more from the same phase, both caught before landing. The duration head's
three arms collapsed to within 2.98e-06 at the fixture's scale, BELOW the
round-off bound, so an implementation ignoring one input stream would have
passed. And a guider-refusal probe matrix omitted the B=1 row, so a claim that is
false at batch 1 -- the ordinary single-request shape -- was recorded as a
golden.

The generalization is what makes this worth a spec section. (a) is a CONSTANT the
fixture never drives into its active regime; (c) is an INPUT the fixture never
drives into the regime that discriminates. Same failure, different axis. A golden
proves only what its inputs can distinguish, so for every brick the question is:
what input would tell a correct implementation from a plausible wrong one, and
does the fixture contain it? Sweeping a parameter costs almost nothing and is
what turns a golden from a witness into a gate.

Issue: #435

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…ctually carries

Materializes the SHIPPED LTX-2.5 checkpoints onto the contracts phases L2 and
L3 committed: the FP8 DiT, an NVFP4 DiT, and the torchao-NVFP4 Gemma-4 text
encoder with its embedded tokenizer pack.

NO NEW QUANT SCHEME. The text encoder is torchao, not compressed-tensors, and
the difference was verified rather than assumed: every quantized module carries
a `torchao_nvfp4` U8[240] marker reading `{"format": "torchao_nvfp4",
"block_size": 16, "is_swizzled_scales": true, ...}`. The encoding is the modelopt
W4A16 one we already have, and `weight_scale_2` is a MULTIPLIER — confirmed
numerically on the real file, not inferred: q_proj's scale_2 is 1.35e-4 with a
group-scale maximum of exactly 448.0, so 6*448*1.35e-4 = 0.363 is a plausible
amax, where the compressed-tensors DIVISOR convention would imply 1.99e7. The
one delta is that the group scales are stored in the cuBLAS block-scaling-factors
layout, so `Ltx2UnswizzleNvfp4BlockScale` inverts the permutation vLLM's own two
producers apply and hands the result to an UNCHANGED `DequantNvfp4ToBf16`.

MEASURED, AND IT CONTRADICTS THE SPEC. The shipped FP8 DiT carries four module
families phase L2 does not port, and two of them falsify committed assumptions:
`prompt_adaln_single` / `audio_prompt_adaln_single` exist only when
`use_prompt_adaln_single` is TRUE (model.py:222-226), which is the opposite of
spec section 1.2 and ltx2.h:115-117 — so the prompt-K/V cache's premise, that
the prompt modulation carries no timestep term, does not hold for this
checkpoint; and `keyframes_abs_pos_embedding` contradicts ltx2.h:47-49. The two
`*_embeddings_connector` towers were already recorded as owed. None is dropped
silently: the load is REFUSED by name and an explicit opt-in still reports every
one of them. Reconciling the spec is the operator's; this change reports.

DTYPE. bf16 is the default, which is the checkpoint's own model dtype; the F32
scale_shift tables stay F32 because the FILE stores them F32. `widen_to_f32` is
opt-in and exists for one caller, the f32 parity forward L2 declared.

Also fixes `BindLtx2DitWeights`, which ltx2.h:228-232 promised would throw BY
NAME and did not — "a required tensor is missing from the weight map" cannot
tell a caller which of 4078 parameters it forgot. Red first, at
tests/vllm/models/test_ltx2_loader.cpp.

Gated three ways, none of them substitutable:
  * the SHIPPED manifests, captured from the files' own headers with no payload
    read (6124 and 1688 tensors). Every non-scale name is accounted for:
    4078 contract + 258 connectors + 12 prompt-AdaLN + 1 keyframes = 4349.
  * a few hundred of their own bytes, with the expected values decoded by TORCH
    — an fp8-e4m3 implementation that is not ours. The DiT's FP8 head matches
    bit for bit; the torchao path's per-row group-scale probe is within half a
    bf16 ulp.
  * synthetic files for whole-model materialization, the by-name refusals, and
    the load-time device staging.

Two mutations, tree restored byte for byte: perturbing the unswizzle index
failed 4 cases / 9 assertions including the real tile; deleting the unswizzle
from the dequant path failed 3 cases including the real-bytes probe (which was
strengthened to reach every row after the first mutation showed row 0 alone is
invariant under the permutation).

OWED, recorded in .agents/porting-inventory.md section 9.18: the swizzle oracle
is a pinned TRANSCRIPTION, not a running one — vLLM is not importable on this
host — though the generator diffs its transcription against the checkout and
refuses on drift; Lightricks' first-party NVFP4 DiT is behind an un-accepted HF
gate (403) and was not downloaded, so that arm is synthetic-only; and the
torchao arm of the Gemma TOWER is not wired, because ltx2_text_encoder.h
declares no tower contract.

Full ctest 393/393. Baselines unmoved: test_ltx2 29/1615, test_ltx2_vae 16/1816,
test_ltx2_text_encoder 17/3350, test_minimax_h3 79/57395,
test_minimax_h3_video_fold 6/137, test_video_engine 11/254, test_capi v12 4/102.

Issue: #435
Spec: .agents/specs/ltx-2-5.md (phase L6)

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
… here

L6 loaded the real checkpoint and disproved the headline claim of this spec,
of issue #435 and of the PR. I verified it against the checkpoint myself before
correcting anything.

The claim was that 2.5 sets use_prompt_adaln_single=false, so the
cross-attention K/V carry no timestep term and can be computed once per request
and reused across all denoise steps. The shipped
ltx-2.5-22b-distilled-transformer-fp8 checkpoint carries 12 tensors that only
exist when that flag is TRUE, including
prompt_adaln_single.emb.timestep_embedder.linear_1 at [4096, 256] -- and 256 is
the sinusoidal timestep width. model.py:223-227 builds the module only when
cross_attention_adaln and use_prompt_adaln_single. So the K/V DO carry a
timestep term here and caching them would be wrong.

The mistake is precise and worth naming: I quoted transformer.py:441 as proof of
"no timestep term at all" and stopped two lines early. :442-443 add one whenever
prompt_timestep is not None, and the comment immediately above them spells out
both branches.

What made it convincing was that three separate true facts pointed the same way.
model_configurator.py:74-76 really does document KV-cacheable checkpoints as
setting the flag false. The checkpoint really does carry the static
prompt_scale_shift_table, 96 of them. Line 441 really has no timestep. None of
the three says the flag is false for THIS checkpoint, and the tensor that
settles it was never looked for -- the header dump that would have shown it was
filtered with 'adaln_single' not in k.

NO SHIPPED DEFECT, and the reason is worth recording. L2's implementer read
upstream's conditional correctly even though my brief handed it the wrong
conclusion, and wrote a refusal at ltx2_dit.cpp:672 that fires by name before any
block runs. The cache is correct-and-inapplicable rather than silently wrong, and
stays gated bit-identical and prompt-bound for any checkpoint that does set the
flag false.

The lesson is the one 7.0 keeps teaching from a new angle: a claim assembled from
three true facts is not thereby true. The decisive test here was one grep against
the checkpoint, and it went unrun because the conclusion already looked
supported.

Corrected in the spec, the roadmap portfolio row, the model-matrix row and
docs/FEATURES.md. Retracted in place rather than quietly edited, because the
wrong claim was committed, published in an issue and a PR, and reported.

Issue: #435

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…on a TRUE premise

Closes the two MAJOR findings from the adversarial review of phase L5, plus its
two MINOR ones. Issue #435. Phase L5 of .agents/specs/ltx-2-5.md.

F1 -- THE linspace MIRROR WAS UNGATED, AND `--steps 41` RENDERED WRONG.
`LinspaceF32` walks the second half backwards from `end`, which is the only
reason the terminal sigma is exactly 0. Nothing tested that: replacing it with a
naive `start + step * i` forward walk left the whole suite green, because the
fixture's step counts (8, 6, 5, 1, 4, 7) are all counts the naive walk happens
to get right. 24 of the first 198 counts are not. At steps=41 the residual
5.96e-08 survives the `sigma != 0` guard, takes the shift transform, and becomes
the stretch anchor, so the WHOLE schedule moves: measured max|diff| 0.146356 and
a terminal of 0.1 instead of 0. Adds golden arms at steps=41 and 47 (the first
two affected counts above 1) and a sweep asserting exact-0 termination over
steps 1..200, so the property is gated by the arithmetic rather than by which
counts someone thought of. RED first: the naive walk now fails 2 cases /
27 assertions. `LinspaceF32` is the only construction of this kind in the phase;
`Ltx2LinearQuadraticSchedule` terminates on a literal 1.0 and is structurally
exact.

F2 -- THE GUIDER REFUSAL WAS RECORDED ON A FALSE PREMISE, IN SIX PLACES.
The claim was that `projection_coef`'s rank-2 (B, 1) result "raises at every
rectangular rank >= 3, i.e. at every real (B, C, F, H, W) video latent". Measured
against upstream, that is false. torch right-aligns (B, 1) onto the last two
axes, so the real predicate is `B > 1 && shape[-2] not in {1, B}`. At B = 1, the
ordinary single-request latent, it composes AND is numerically correct because
(1, 1) is a scalar; (2, 128, 8, 2, 16) composes too. Where it composes with
B > 1 it is silently wrong, applying the per-batch coefficient along axis -2.
The `norm(dim=[-1,-2,-3])` in the threshold arms is a SEPARATE rank >= 3
constraint. The probe matrix now carries B=1 and shape[-2]==B rows, the `square`
predicate is gone (it was a mis-generalization of those two axes), and the test
asserts the real predicate in BOTH directions.

The REFUSAL ITSELF STANDS, on the premise that is true and was verified
independently: nothing upstream constructs these three. CFGStarRescalingGuider,
LtxAPGGuider and LegacyStatefulAPGGuider appear in the whole LTX-2 tree only at
their own class statements (guiders.py:31, 78, 129); every pipeline builds
MultiModalGuider from MultiModalGuiderParams (utils/constants.py:49-68). That is
an unported arm refused by name and recorded as owed, which AGENTS.md permits.
Corrected at all six sites: the generator, the test, ltx2_pipeline.cpp,
ltx2_pipeline.h (which the review did not list but carried the same text), and
.agents/porting-inventory.md 9.18(b), which keeps the correction visible rather
than quietly rewriting it. Recording a wrong finding as a golden is exactly what
spec 7.0(b) exists to prevent.

F3 -- TWO CONSTANTS DOCUMENTED AS PINNED HAD NO ASSERTION. `grep -rn` over
tests/ returned zero references for both kLtx2ConnectorRmsNormEps and
kLtx2BlurKernelSize. Both are now compared against values the generator READS OFF
upstream's own signatures (utils.py:7, blur_downsample.py:14) rather than retyped
literals, so upstream moving either fails the gate. Mutating them 1e-6 -> 1e-4
and 5 -> 7 now fails 3 cases / 8 assertions. Both header comments corrected to
say what actually gates them.

F4 -- DTYPE ANNOTATIONS, AND A CORRECTION TO THE L5 COMMIT BODY. That commit said
the upsampler and duration head are "f32 throughout, which is upstream's OWN
width on these paths". That is not accurate. Five sites compute in double as
REDUCTIONS, which the suite's f64-reduction convention covers (L3 precedent,
ltx2_text_encoder.cpp:259-269) but which were unannotated; each now carries a
site note. Two more, `Silu` and `GeluTanh`, are POINTWISE and are NOT covered by
that convention at all: they are computed WIDER than upstream's f32, the polarity
AGENTS.md warns a value gate cannot catch. Annotated as visible debt rather than
narrowed, because narrowing moves goldens and owes its own red-first change.
Same class as #445.

A NEW MAJOR DEFECT FOUND WHILE GATING F1, REPORTED AND DELIBERATELY NOT REPAIRED.
The steps 1..200 sweep exposed `Ltx2SigmaSchedule(1, ...)` returning {-nan, 0}
where upstream returns {0.10000002, 0}. Root cause measured: upstream's shift is
a PYTHON SCALAR divided by a tensor (schedulers.py:43-45) and torch evaluates
scalar/tensor as `scalar * reciprocal(tensor)`, yielding 0.99999994 at sigma == 1
rather than 1.0. At steps == 1 that one-ulp residue is the only non-zero sigma and
so is the entire stretch anchor; this port computes the same expression in f32,
gets exactly 1.0, and divides 0/0. The `OneStep` golden already carries upstream's
correct value and did not catch it because `MaxAbsDiff` drops NaN (`d > worst` is
false for NaN). Both are left untouched on purpose: mirroring torch's
reciprocal-multiply changes every sigma on every arm, and fixing the helper turns
the suite red on that defect, so the pair owes its own spec, issue and fresh
review rather than a drive-by edit in a review-repair branch. This is the stop
condition the task named. The sweep gates finiteness for steps >= 2 and carves
out steps == 1 explicitly, so the defect is recorded in the tree instead of only
in a report, and the file header no longer claims it mirrors width everywhere.

Evidence: CPU-only Release build, exit checked on every build, no output
discarded. test_ltx2_pipeline 35 cases / 2358 assertions / Status: SUCCESS
(was 33 / 1512). Unchanged: test_ltx2 29/1615, test_ltx2_vae 16/1816,
test_ltx2_text_encoder 17/3350, test_minimax_h3 79/57395,
test_minimax_h3_video_fold 6/137, test_video_engine 11/254,
test_capi 'capi v12*' 4/102. Full ctest -j 4: 395/395, no flakes.
Goldens regenerated against LTX-2 fd4ded7f and vllm-omni a4ea67a2, both trees
verified clean before and after; zero drift in any pre-existing golden value.
The generator's provenance refusals re-exercised: wrong path, dirty --ltx2 and
dirty --vllm-omni all still exit 1.

docs/FEATURES.md and docs/USAGE.md are touched only because doc-checkpoint
classifies any edit under src/vllm/model_executor/models/ and include/vllm/ as
feature and usage surface; the entries are minimal and keyed.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
#449)

Every LTX-2.5 and MiniMax-H3 golden comparison, and both DeepSeek-V4 forward
gates, reduced to `max|got - want|` written one of two ways, and BOTH are
NaN-blind:

  form A  if (d > worst) worst = d;                 // NaN is never > anything
  form B  worst = std::max(worst, std::abs(...));   // std::max(a,b) is
                                                    // `a < b ? b : a`, and
                                                    // `a < NaN` is false

So an all-NaN brick compared against entirely correct goldens reported
`max|diff| = 0.0` and passed every bound. The instrument could not see the one
defect class it exists to catch. On LTX-2.5 phase L5 it concealed a real
`Ltx2SigmaSchedule(1, ...)` returning `{-nan, 0}`, reported green.

This replaces the six local copies with ONE shared helper,
tests/support/max_abs_diff.h, where a non-finite operand on either side is a
FAILURE: `MaxAbsDiffScan` reports the offending index and returns +infinity,
which fails every `< tol` bound, and `MaxAbsDiff` additionally raises a doctest
failure naming the index and both values, so the `> tol` "these must differ"
callers in the DeepSeek-V4 suites cannot read a NaN as a difference either.
`vllm_cpp_add_test` now puts tests/ on the include path so any suite can reach
tests/support/; no header name under tests/ collides with one under include/ or
src/.

RED first, twice.

1. The helper's own gate. Built against the OLD reduction body, tests/support/
   test_max_abs_diff.cpp reported `test cases: 7 | 3 passed | 4 failed`,
   `assertions: 33 | 16 passed | 17 failed`, `Status: FAILURE!`. With the guard:
   `7 passed | 0 failed`, `33 | 33 passed | 0 failed`, `Status: SUCCESS!`.
   The wrapper's raise is gated too, by the test_max_abs_diff_nan_raises CTest
   entry: the case is skipped in the normal run (a raised failure would count as
   one) and forced on there under WILL_FAIL, so it must exit non-zero.

2. End-to-end on a real suite. Forcing Ltx2AdaLayerNormSingle's modulation to
   all-NaN against its correct golden: with the old reduction test_ltx2 printed
   `29 passed | 0 failed`, `Status: SUCCESS!`; with the guard it prints
   `28 passed | 1 failed`, `Status: FAILURE!`, naming index 0, got = nan,
   want = 0.0129515. The mutation was reverted byte-for-byte (md5 checked).

WHAT THE HARDENING UNCOVERED: nothing on this branch. Every affected suite is
byte-for-byte green before and after, at identical case and assertion counts:
test_ltx2 29/1615, test_ltx2_vae 16/1816, test_ltx2_text_encoder 17/3350,
test_minimax_h3 79/57395, test_minimax_h3_video_fold 6/137, all `Status:
SUCCESS!`. The shipped MiniMax-H3 gate is unaffected. The two DeepSeek-V4 suites
gain 8 assertions each (26 -> 34, 29 -> 37): the shared wrapper REQUIREs equal
sizes where the local copy silently compared only the shorter prefix, so each of
their four call sites now runs two extra passing REQUIREs. Full `ctest -j 4`:
396/396, 0 failed.

The `Ltx2SigmaSchedule(1, ...)` arm the issue predicts would go red is NOT on
this branch: test_ltx2_pipeline.cpp and Ltx2SigmaSchedule arrived with L5
(742e38a) on row/LTX25-L5-PIPELINE, which row/MODEL-DIFFUSION-LTX25 does not
contain. That file carries the same NaN-blind form and needs the same edit when
L5 lands; its OneStep arm should then go red, and that is the point.

The reduction is pervasive beyond the six files fixed here: an audit of tests/
finds the same unguarded `std::max`/`>` shape at roughly 112 further sites in 43
other files, including 26 in-body comparisons inside test_minimax_h3.cpp itself
and the whole tests/vt/ paged-attention, NVFP4, MoE and Tenstorrent surface.
tests/vt/test_ops_mla_attn.cpp, test_ops_mla_prefill.cpp and
test_ops_mla_chunked_context.cpp already REQUIRE non-NaN inline and are the
in-tree precedent this helper generalizes. Those remaining sites are deliberately
NOT touched here: this change is scoped to the helpers issue #449 names, and
sweeping them belongs in its own row.

No golden reached through this helper legitimately holds Inf or NaN. LTX-2.5's
`additive_mask` carries -FLT_MAX, which is finite and compared exactly, not
through here; the gate pins that a saturating-but-finite magnitude still
compares rather than being refused.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
mudler added 11 commits August 13, 2026 08:12
…d the sweep proving nothing (#435, #598)

Six review findings on the L9a nibble-order change. The implementation is
sound and the correctness argument holds; every one of these is an accuracy or
coverage defect in what the change CLAIMS.

F1 -- a safety guarantee that is false, stated to users. Three places said any
other marker/shape combination is "refused by name". It is not. A marker-less
NVFP4 checkpoint whose weight_scale is stored LINEAR [N, K/16] has, for every
geometry with N % 128 == 0 and G % 4 == 0, a shape numerically IDENTICAL to the
cuBLAS-padded framing. Ltx2ResolveNvfp4Producer returns kNvfp4Prequant for it,
the loader then unswizzles scales that were never swizzled AND reads high-first,
and the result is finite, correctly shaped, correctly scaled, WRONG. The refusal
branch is unreachable for that entire class.

That is not an exotic file. LINEAR [N, K/16] is what ModelOpt, llm-compressor
and compressed-tensors all write -- vLLM's own readers allocate exactly that
shape at modelopt.py:1335-1345 and
compressed_tensors/schemes/compressed_tensors_w4a4_nvfp4.py:73-76 (pin
555967922) -- and none of the three emits a .torchao_nvfp4 sidecar. So the
marker's absence excludes torchao and NOTHING ELSE.

The decision is still right, because there is no better evidence in the file,
and that was checked rather than assumed: the shipped DiT's __metadata__ carries
exactly config, gemma_source_checkpoint, model_version and license -- no
quantization_config, no producer key, no nvfp4/torchao/quant substring anywhere
in the config, and no tensor name mentioning the quantizer over all 7876 tensors.
Unlike MiniMax-H3, whose community checkpoint DID name its converter, there is
nothing here to key on. So the gate is NOT weakened; the sentence is corrected,
in ltx2_loader.h, docs/USAGE.md and the spec's risk table, and the residual
hazard becomes a tracked condition at spec section 3.1.1 beside the existing
H3 reversal condition.

F2 -- the ten-gate "byte-identical" evidence is half vacuous, and two live
gates are blind. Instrumented DequantNvfp4ToBf16 with a call counter and re-ran
mutation M3 (flip the shared default to kHighFirst) across all ten:

  RED     test_nvfp4_dequant 6 calls, test_gguf_nvfp4 6, test_ltx2_loader 294
  GREEN   test_qwen3_forward 30 calls, test_minimax_h3 44 calls / 57,395 asserts
  GREEN   the other five make ZERO calls on a default run

Three of ten can see a nibble-order change. Five never execute the function, so
their identical counts are evidence of nothing about it. Two execute it live and
still pass -- and one of those is the project's OTHER high-first family, gated by
exactly the statistic this spec proves is blind. If H3 is ever routed through the
new kHighFirst while MiniMaxH3Nvfp4HighNibbleFirst() stays default-ON, the two
compose into a double flip and nothing in the tree fires. Opened #598 for a
nibble-sensitive H3 gate, linked from the roadmap issue table and the spec.

F3 -- a recorded number the gate does not produce. Section 7 recorded the
wrong-order arm at 0.00514, which matches no row of its own table and no line
of the gate. The committed gate reports corr -0.00239115 / rel 1.41856. The
control on the same sentence, 0.00362, was exact. Section 5.1 also named "the
loader refuses the shape" as THE red-before for a change with two independent
halves; a throw can only ever demonstrate the layout half, so both reds are now
stated separately with the value each produces.

F4 -- a comment contradicted by four call sites. nvfp4_dequant.h said the order
is "never inferred and never defaulted per call site". It IS defaulted, and
deliberately: minimax_h3_nvfp4.cpp:112, minimax_h3_device.cpp:1311,
qwen3_5.cpp:1298 and dense_nvfp4_gemm.h all rely on it. The seam that genuinely
has no default is Ltx2DequantNvfp4ToBf16. Comment corrected to say which is
which and why.

F5 -- the correlation tolerance was loose in one direction and unbounded in the
other, RE-BOUNDED strictly stronger. rel_rms is a PREDICTED QUANTITY (the
disagreement two different quantizations of the same base weights must show,
measured 0.100672), not an error budget. `rel <= 0.15` alone admitted a +10%
uniform group-scale error, and Pearson correlation is scale-INVARIANT -- corr
reads 0.994968 to every printed digit for every multiplier -- so nothing else in
the gate could catch it. It also had no floor, so an arm that reproduced the FP8
oracle exactly scored rel 0.0 / corr 1.0 and passed every correlation assertion.

Replaced by a band: 0.085 <= rel <= 0.115, plus corr <= 0.998. Proven strictly
stronger by A/B on the SAME binary path, only the bound differing:

  x1.09 group-scale error inside DequantNvfp4ToBf16, rel 0.1411
      old `rel <= 0.15`   GREEN  45/45  Status: SUCCESS!
      band               RED    CHECK( 0.1411 <= 0.115 ) is NOT correct!
  the FP8 oracle handed to the gate as its own answer
      old bounds         every CORRELATION assertion passes; only the
                         incidental absmax equality fires
      band               RED on the result itself: rel >= 0.085 AND corr <= 0.998

Both mutations are now permanent arms of the gate rather than one-off logs, in
the same style as the wrong-nibble arm: the gate asserts that a x1.10 scale
error moves corr by less than 1e-6 (measured 7.35e-11) while pushing rel out of
the band, and that the oracle-against-itself lands outside it too.

F6 -- record the limit honestly. Section 1.1 claimed "three mutually consistent
and independent witnesses". torchao is neither installed nor vendored on this
box (import fails; no mx_formats/kernels.py on the filesystem), so its two lines
are upstream source only, not executable here. And vLLM's break_fp4_bytes is
reached only from dequantize_to_dtype, which serves the ModelOpt and
compressed-tensors paths -- vLLM's torchao path (torchao.py:290-318) delegates
to torchao.quantization.quantize_ and never calls it. So vLLM witnesses ModelOpt,
not torchao's writer. Section 1.1 now tabulates what each witness proves and how
it was verified. The default is unchanged; nothing moves either way.

Gates (Release, CUDA=OFF, BUILD_EXIT=0, no ENOSPC/BFD in any build log,
df 84% throughout). ctest -N 409, full ctest 409/409 passed, 0 failed, 1 skipped
(test_voxtral_e2e). The ten NVFP4 gates, nine unchanged and one moved:

  test_nvfp4_dequant     5 / 69        test_ops_nvfp4_matmul   4 / 1
  test_gguf_nvfp4       14 / 2352      test_ops_moe_grouped    6 / 3
  test_qwen36_weights    7 / 45        test_ops_nvfp4_fp4     22 / 919
  test_qwen3_forward     7 / 1557      test_ltx2_device       13 / 498
  test_minimax_h3       79 / 57395     test_ltx2_loader       24 / 4809

test_ltx2_loader 4793 -> 4809 is the +16 from the re-banding and its two
built-in mutation arms; it is the suite this change adds assertions to. Tree
restored byte-for-byte after every mutation.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…icts (#560)

This PR exists to stop constants carrying a wrong reachability verdict, and it
shipped three of its own. The deliverable is an accurate record, so an inaccurate
record here IS the defect. Every claim below was re-measured on this tree before
the text it falsifies was touched; nothing about the norm_eps arm or the upstream
revision pin changes.

TWO CONSTANTS LISTED AS INVISIBLE ARE NUMERICALLY GATED. The pin case opened with
"Each of these was mutated with every golden staying green", which is false for
both encoder entries. Mutating the FIELD DEFAULTS, which is what every arm runs
because no arm overrides them:

    Ltx2ConvVideoEncoderConfig::norm_eps       1e-6 -> 1e-4
      RED 4.38839e-05 vs the 5e-6 band, on 2 goldens
      ("the video ENCODER (*_res family)", "the video encoder CROPS a frame
       count that is not 1 + k*factor")
    Ltx2ConvVideoEncoderConfig::pixel_norm_eps 1e-8 -> 1e-6
      RED on 4 goldens: 1.02744e-05, 1.02744e-05, 8.10623e-06, and
      0.000175595 on "(strided convs, per_channel, reflect)"

The cause is the one this PR already established for the decoder, reaching the
other half through the SAME LINE. The encoder shares ResnetBlock3d --
ltx2_video_vae.cpp:1051,1056 call what the decoder calls at :693,700 -- so it
reads norm3 at :405 for exactly the reason F-1 gave. Forcing :405 to 1.0 reds
those two encoder goldens at 0.150858, which is what IDENTIFIES norm3 as the
reader rather than inferring it: norm_layer is kPixelNorm on both encoder arms,
so neither ApplyNorm nor conv_norm_out (:1081-1087) enters a GroupNorm branch.
Arm B has no res_x_y and so no norm3, and stays green -- the coverage is real but
partial, which is why the pins stay.

Coverage was BETTER than recorded, not worse, and that is still a defect: a list
whose membership claim is wrong in the safe direction is a list nobody can trust
in the unsafe one. The class statement is now per-entry, quantified, and says the
mutation was run, because this case has carried a wrong verdict twice.

THE NEW ARM FALSIFIED A LINE THIS PR LEFT STANDING. ltx2_video_vae.h recorded
`Ltx2ConvVideoDecoderConfig::pixel_norm_eps 1e-8 -> 1e-6 green` under "EVERY
golden staying green". With section 5d present that mutation REDS at 1.69305e-04:
the low-scale latent built to make norm_eps a first-order term made its neighbour
one too. The fixture that closed one hole closed another, and the line claiming
otherwise survived the change that refuted it.

THE ENCODER HALF GETS THE SAME NOTE AS THE DECODER. ltx2_video_vae.h gained a
full "norm3 is the reason this is LIVE on a PixelNorm checkpoint too" note;
ltx2_video_vae_encoder.h still said only "a field here only so the gate can pin
it". True, and incomplete for the identical code path. One line cannot be live
for one caller and dead for the other.

THE QUALIFIER F-8 ADDED IS NOW GATED. The refusal test checked only
VAE_ENCODER_COMFY_KEYS_FILTER and default_image_crf, so deleting the `crf == 0`
qualifier again would not go red. Upstream `preprocess` returns the image
untouched at crf == 0 (media_io/decode.py:427, in :413-435), so "re-compresses
before encoding" is only true of a nonzero resolved CRF; naming the round trip
without its exception overstates what is unported. Proven RED by removing the
qualifier from the message: 16 passed / 1 failed, the one being the new CHECK.

ONE BAND, ONE DEFINITION. gen-ltx2-vae-goldens.py hardcoded `10 * 5e-6` while the
suite applies kLtx2GoldenTol. Two definitions of one number in two languages: a
widened C++ band would leave the generator certifying arms against a band nobody
uses. It now PARSES kLtx2GoldenTol from the suite and dies unless it finds exactly
one definition. And docs/USAGE.md:335 had grown to 119 chars inside a 79-column
paragraph; re-wrapped, no wording changed.

Gate on this tree, CPU-only Release, clean rebuild: BUILD_EXIT=0, no ENOSPC or
BFD line, ctest -N 401, ctest -j4 400/401 with test_engine_core_proc the known -j
flake, PASS on a serial re-run. test_ltx2_vae 36 cases / 3039 assertions (comment
-only, unchanged from before). test_ltx2_video 17 cases / 173 assertions, up from
172 by the added CHECK.

Issue: #560 (campaign #435)

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
… can see scale

Reviewed PASS at dbf8a52 after one FAIL round: all six findings closed, with
the reviewer reproducing every load-bearing number rather than accepting the
report.

The state change in the docs row is real: the first-party NVFP4 file now LOADS,
so the row's "first-party NVFP4 does not" clause is retired. Fifth hand
reconciliation of this one keyed row (#595).

What the round actually bought:

The loader's "refuses by name" guarantee was FALSE for the class that matters --
a marker-less checkpoint with LINEAR [N, K/16] scales, which is what ModelOpt,
llm-compressor and compressed-tensors all write, is shape-identical to the
cuBLAS-padded framing whenever N%128==0 and G%4==0. It would have unswizzled and
read high-first: finite, correctly shaped, correctly scaled, wrong, and it
renders. There is no better discriminator -- the file's __metadata__ carries no
producer key -- so the DECISION stands and the three false sentences, one of them
user-facing, were corrected instead.

And the correlation gate could not see a scale error at all. Pearson is
scale-invariant by construction: a uniform x1.09 defect moves corr by 7.35e-11,
so the corr>=0.99 floor had no power over the defect class it looked most
authoritative about, and rel_rms carried the load one-sided at <=0.15, where
x1.10 measures 0.150094 and failed by 0.06% -- by luck. Now a measured BAND,
0.085 <= rel <= 0.115 plus corr <= 0.998, verified strictly stronger: at x1.05
the band reds where the old ceiling passed green.

Carrying one non-blocking finding forward rather than silently: the "too-good"
arm at test_ltx2_loader.cpp:1200-1208 is TRUE BY CONSTRUCTION -- `perfect` is a
copy of the oracle, so it prints CHECK( 0 < 0.085 ) whatever the code does. A
tautology wearing a gate's label, in the fix for exactly that class. The real
guard at :1175 is proven live; the arm is owed removal or relabelling.

Issue: #435, #598

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…ird stale refusal goes away

The last hop of the LTX-2.5 campaign. Two branches had each built half of it and
neither could see the other:

  * L10 made the Gemma-4 tower RUN — the embedded tokenizer reaches a prompt
    string, the torchao-NVFP4 tower materializes onto `Gemma4Weights`, all 49
    hidden states come out within the oracle's own bf16 noise floor, and both
    caption projections turn them into the 4096/2048 conditioning streams.
  * L9c put the `Embeddings1DConnector` on the render path with the checkpoint's
    OWN weights.

L10's `encoder_path` refusal said the connector weights were "still among the
modules `Ltx2LoadDitFromSafetensors` refuses (ltx2_loader.h:96-99)". On the
merged tree that was FALSE — `ltx2_loader.cpp:417` already recorded them as
loaded elsewhere by L9c. That is the THIRD refusal in this campaign whose stated
reason went stale, so the header comment it cited is corrected in the same
change rather than left to mislead a fourth reader.

WHAT NOW HAPPENS. `encoder_path` loads the tower, the tokenizer and both caption
projections; `Ltx2SelectTextFeatureVariant` resolves the V1/V2 shape from the
DiT's own transformer config; and a request's `prompt` is tokenized, encoded,
projected, run through the connector and handed to cross-attention, per request.
`has_encoder()` is true. `ltx2-gen` grows `--encoder`, `--encoder-config` and
`--prompt`, so the capability is reachable through the ABI rather than only from
a test.

ONE GENUINE GAP, refused rather than defaulted: the only shipped LTX-2.5 text
encoder carries NO `__metadata__` at all, so the Gemma config is an INPUT. It
comes from the checkpoint's `__metadata__["gemma_config"]` when present and from
the new `encoder_config_path` extra when not; neither source is a refusal, both
sources is a refusal. `layer_types`, `global_head_dim`,
`num_global_key_value_heads` and `attention_k_eq_v` each resolve a DIFFERENT
tower out of a byte-identical tensor set, which is the same polarity
`dit_config_path` already has.

TWO THINGS RECORDED AT THE CODE rather than left for a reader to rediscover.
`Ltx2TextEncoderConditioning` and `Ltx2ConnectorCreateEmbeddings` are two ports
of overlapping halves of `embeddings_processor.py:70-117` and BOTH carry the
right-pad sort, so composing them sorts an already-sorted stream; that is the
identity because a stable argsort of a 0/1 key is idempotent, and the engine now
ASSERTS the precondition instead of relying on the claim. And the tower runs on a
CPU queue even on the device arm, because everything in `ltx2_text_encoder.h` is
f32 by declaration — stated as owed, not hidden.

THE INSTRUMENT, and why it can see the difference. `Ltx2VideoEngine::last_conditioning()`
reports an FNV-1a digest and an absmax over the exact f32 buffers
`Ltx2ModalityInput::context` pointed at, after the connector and immediately
before the denoise loop. A frame statistic was deliberately NOT used: L9c's
reviewer found a scene and a colour field INDISTINGUISHABLE to the existing frame
analyzer (neighbour |dx|/sd 0.093 vs 0.033) and needed contact sheets. A digest
is a function of the bytes rather than a summary of them, so it has no such blind
spot; the absmax is what separates "the tower ran" from "the tower returned
zeros", which would otherwise satisfy a difference check for the wrong reason.

GATE. tests/vllm/multimodal/test_ltx2_video.cpp 24 -> 29 cases, 365 -> 485
assertions, on a reduced-dimension text encoder written in the SHIPPED format:
bf16 tower with the mixed sliding/full geometry and no `v_proj` on the full
layer, torchao-NVFP4 caption projections with a PADDED swizzled scale, the
tokenizer and HF sidecars stored as tensors, and no `__metadata__`. The fixture's
DiT config also gains the three V2 marker keys it was missing — it carried only
`caption_proj_before_connector`, which is the PARTIAL set upstream refuses, so it
gated no variant selection at all. The three added values are read from the
first-party NVFP4 DiT's own metadata.

RED before GREEN: against the pre-L13 engine the new cases do not compile —
`kLtx2EncoderConfigPathExtra`, `Ltx2ConditioningTrace` and `last_conditioning`
do not exist — which is the honest statement that the surface could not be
expressed. Mutation evidence, each applied alone and the tree restored
byte-identically (sha256 verified):

  M1  tower encodes a CONSTANT instead of `gen.prompt`
      -> 3 RED: both digests equal across two prompts, and the frames equal
  M2  prompt path skips `RunConnector`
      -> 3 RED in "goes through the CONNECTOR": same prompt, same tower, same
         DiT weights, only the connector differs, and it stopped mattering
  M3  drop the missing-gemma-config refusal
      -> 2 RED. Worth recording: an EARLIER version of that subcase asserted
         only that the message named `encoder_config_path`, and M3 left it GREEN
         — the load still failed, but with "cannot open " from a fallthrough
         reading the empty path. A refusal firing for the wrong reason is
         exactly what this phase exists to stop shipping, so the assertion was
         strengthened to the discriminating clauses before being called a gate.

NOT gated, and named rather than claimed unreachable: the additive-mask
right-pad guard. I did not construct a probe that reaches it, and per this
campaign's own rule a mutation that moves nothing is not evidence of
unreachability.

Full gate on this worktree, CPU Release build, x86_64: BUILD_EXIT=0, no
"No space left"/"BFD assertion" in the build log, 61G free on /. ctest -N 408,
`ctest -j8` 408/408 passed 0 failed (1 skipped: test_voxtral_e2e). Focused:
test_ltx2_video 29/485, test_ltx2_loader 20/2371, test_ltx2_text_encoder
23/3583, test_ltx2_pipeline 37/2382, test_ltx2 29/1615, test_video_engine
11/254, test_capi 55/505 — all SUCCESS.

`scripts/agent-preflight.sh --staged` passes `doc-checkpoint --staged` and
`now-current --staged`. Its `doc-checkpoint range` failure is INHERITED: all
three commits it names (b0aa475, d67f812, aa6aa0e) are ancestors of the
base SHA 67a7b1c and the same failure reproduces on the untouched base.

Issue #435.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
… list (#560)

Round 3 closed every repair from round 2 and failed on one new instance of the
same defect: a record calling a constant unreachable when a golden reds on it.
One entry over, the list still said green.

THE BWE MEL LOG CLAMP IS NOT INVISIBLE. ltx2_video_vae.h:108-110 carried

    kLtx2BweMelLogClamp                    1e-5 -> 1e-8   green

under "these three left EVERY golden green". Reproduced on this tree before
touching the text, by mutating ltx2_audio_vae.h:212:

    test_ltx2_vae.cpp:1400: CHECK( err <= kLtx2GoldenTol ) is NOT correct!
      values: CHECK( 0.144965 <= 5e-06 )
      logged: saturated-clamp BWE max|diff| = 0.144965
    36 cases: 34 passed, 2 failed | 3039 assertions: 3037 passed, 2 failed
    exit code 1

The second failure is the constant assertion at :1279. Restored byte-for-byte
afterwards, md5 fe861901ef8f18fbbc9e6caedf513d1b before and after.

The saturating arm that reds it, "ltx2 vae: the BWE mel log clamp is gated where
it actually binds", landed at 93329b1 -- and `git log -S "left EVERY golden
green"` returns only d45bcb5, so the phrase was written over an arm that
already existed. Two places in the tree already said so: this same header 26
lines later, and test_ltx2_vae.cpp:1274-1278 ("until the saturating arm below").
The list is the surface a reader trusts, so the list is what was wrong.

The entry is moved out with the number that proves it, exactly as round 2 moved
pixel_norm_eps. What made it look invisible is SCALE, not the constant's nature:
the ordinary arm's raw mel minimum is ~4.4e-3 and never approaches the floor, so
the reachable arm attenuates mel_basis by 1e-4 until every bin lands under it and
asserts the saturated-bin count rather than assuming it.

THE SAME FALSE CLAIM SAT AT THE CONSTANT'S OWN DEFINITION. ltx2_audio_vae.h:206
declared it "the member of the invisible-constant class" and stated the 1e-5 ->
1e-8 mutation "leaves every tensor golden green". Both sentences shipped in
93329b1, the very commit that added the golden refuting them. Fixing the list
while leaving the declaration would have left round 4 the identical finding one
file over, so it is corrected here. Its upstream citation was also off by one --
the clamp is vocoder.py:515, not :516; :516 is the `return`. Verified at the
pinned checkout, which is what test_ltx2_vae.cpp:1273 already cited correctly.

THE CRF CITATION POINTED AT THE WRONG EARLY RETURN. test_ltx2_video.cpp:668 read
"media_io/decode.py:413-435, the early return at :427". At LTX-2 fd4ded7f,
`if crf == 0:` is :425 and `return image` is :426; :427 is
`if min(image.shape[0], image.shape[1]) < 2:`, a different early return for
degenerate image size. The range and the behavioural claim were both right, so
only the pinpoint moves -- but this is the worst place to be off by two, because
a reader following it lands on the size guard and concludes the crf == 0 claim is
unsupported. Now cited as :425-426 and naming :427-428 as the guard it is not.

That size guard is also a second case where upstream does NOT re-compress, and
docs/USAGE.md:334 claimed the round trip happens "whenever the resolved CRF is
not 0" with no other exception. Qualified there too.

A SHARED LINE IS NOT AN ARGUMENT FOR LIVENESS. ltx2_video_vae_encoder.h:130-132
argued the encoder's norm_eps is live because "It is ONE line in the port for
both halves ... so it cannot be live for one and dead for the other". The
conclusion holds -- both halves were measured live -- but the inference does not,
and round 3's :405 -> 1.0 probe is the counterexample: :405 sits behind the
`input.channels != out_channels` guard at :400, so even entering ResnetBlock3d is
not reaching it. `res_x` passes `x.channels` as `out_channels` at :1051 and the
guard is false; encoder arm B never enters ResnetBlock3d at all, since all four
of its blocks are plain strided CausalConv3d (:1060-1068). Rewritten to rest on
the per-arm measurement, and to say what test_ltx2_vae.cpp:1327 already says --
the coverage is real but PARTIAL, which is what the pin is still for.

Comment-only in the headers plus one doc qualifier; no constant, golden, band or
executable line changes, and the assertion counts are unchanged by construction.

Gate on this tree, CPU-only Release: BUILD_EXIT=0, no ENOSPC or BFD line,
ctest -N 401, ctest -j8 401/401 CTEST_EXIT=0. test_ltx2_vae 36 cases / 3039
assertions exit 0; test_ltx2_video 17 cases / 173 assertions exit 0 -- both
identical to the pre-edit baseline measured on the same build dir.

`doc-checkpoint range` still fails on b0aa475 and d67f812. Both are
pre-existing L4 and L7+L8 branch commits, both flagged identically before any
edit in this change, and neither is touched here; it is a campaign-integration
item, not this repair.

Issue: #560 (campaign #435)

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…survive measurement (#435)

Eight findings from the L10 fresh review. Six close as written; two close
differently, because the thing they prescribed does not work and the oracle says
so. Both are recorded here rather than quietly worked around, since an
implementer who accepts a prescription that fails is the failure this protocol
exists to catch.

────────────────────────────────────────────────────────────────────────────────
F3 — THE PRESCRIBED FIX IS REFUTED; THE ROPE TABLE IS THE INSTRUMENT

The finding is real: `g.rope_partial_full = 1.0` (full rotary on the full-
attention layers instead of the config's 0.25) left the suite green at 23 cases
/ 3583 assertions. Reproduced here before touching anything.

The prescription was "a fixture whose global_head_dim/seq keep the rope
contribution above the floor". MEASURED against the oracle, per state, as
signal = max|bf16 @0.25 - bf16 @1.00| over floor = max|f32 - bf16|:

    committed        head_dim  8/16  seq  8    worst signal/floor  1.095
    wider full head  head_dim 16/32  seq  8                        0.258
    longer seq       head_dim  8/16  seq 24                        0.764
    wider + longer   head_dim 16/32  seq 24                        0.523
    wider + longer   head_dim 16/32  seq 32                        0.650

Enlarging the fixture makes it WORSE. bf16 accumulation noise grows at least as
fast as the rope contribution, so no reachable fixture size separates them: the
hidden states are the wrong instrument, not a badly sized one.

The right instrument is the table. `BuildProportionalRopeCache`'s host
computation is split out and exported as `Gemma4ProportionalRopeCosSin`, the
generator emits the oracle's own `Gemma4UnifiedTextRotaryEmbedding` cos|sin for
the full-attention layer type (section 6), and the new case compares them in
f32 with nothing accumulating. Measured agreement 1.267e-07 against a 1e-6
bound, plus an EXACT structural check that pairs at and beyond
`int(partial*head_dim//2)` are cos=1, sin=0 and that the pairs below it really
rotate.

    RED  under the mutation: 202 assertions fail, worst 0.56533 vs 1e-6, exit 1
    GREEN restored:          26 cases / 4115 assertions, exit 0

────────────────────────────────────────────────────────────────────────────────
F2 — THE VALUE GATE AND THE LOADER, IN CI; AND M6 IS NOT WHAT IT LOOKED LIKE

`Ltx2EncodePromptToConditioning`, `Ltx2LoadGemmaTowerFromSafetensors` and all
four documented refusals were reachable from exactly ONE place — the opt-in
24 GB case — so none had CI coverage.

They do now. The reduced tower fixture, which is already held to a running
oracle, is written out as a real .safetensors under the CHECKPOINT's tensor
names, loaded back, and compared to the fixture byte for byte; then a tokenizer
whose added tokens spell the oracle's own token ids drives the whole prompt path
and its conditioning is held to the committed LEFT-PADDED oracle run at a floor
propagated through the identical projection.

    concat order q,k,v -> q,v,k          RED  14 assertions, exit 1
    PLE refusal disabled                 RED   1 assertion,  exit 1
    missing-v_proj refusal disabled      RED   1 assertion,  exit 1
    module dtype F16 read as bf16        RED   1 assertion,  exit 1
    norm vector F16 read as bf16         RED   1 assertion,  exit 1
    conditioning at 0.565x / 0.688x of its propagated floor

Now the part that did not survive. The review called `positions[i] = i` "the
exact defect the surrounding comment warns about". It is not a defect at all.
Rotary embedding is RELATIVE and the pads are masked out of attention, so
shifting every position by the pad count cancels. MEASURED in the oracle, same
8 tokens told 12..19 and told 0..7:

    f32   max|diff| 5.11e-05 over max|value| 14.35   3.6e-06 relative
    bf16  max|diff| 1.09                             0.65-1.70x the dtype floor

f32 round-off, and at bf16 the rounding of different absolute angles. So the
comment at ltx2_text_encoder.cpp — "a port that renumbers from zero rotates
every query by the wrong angle" — was an overclaim, and so was its twin in the
left-pad case. Both now carry the measurement. The numbering is still mirrored,
because transformers derives positions from `cache_position` and fidelity is the
reason; arithmetic is not. The new case does red under the renumbering, at 1.10x
the audio floor, and says in its own comment that the narrow margin is a
property of the defect rather than of the gate.

────────────────────────────────────────────────────────────────────────────────
F4 — THE GENERATOR'S LEGS WERE COUPLED, AND NOT WHERE IT LOOKED

`run_tower` did `inner.to(dtype)`, which converts IN PLACE, so every leg after
the bf16 one ran downstream of it. Each leg now runs on a `copy.deepcopy`.

The mechanism is narrower than "bf16-rounded weights": MEASURED on this
transformers build, the parameters round-trip unchanged, and it is the rotary
embedding's non-persistent `inv_freq` BUFFERS that do not — 9.36e-05 on the
full-attention table, 9.77e-05 on the sliding one. Regenerating moved 12 of the
13 padded f32 states (state 12 by 1.03e-02 on values of 2.705) and every entry
of the pad-equivalence vector, while sections 2, 3 and 3b are byte-identical —
which is exactly the partition the in-place conversion predicts. The header's
claims about sections 4 and 5 are corrected to match.

────────────────────────────────────────────────────────────────────────────────
F5, F7, F8, F9

F5  337 -> 329, and pinned exactly rather than `> 300`. The count is arithmetic
    and now says so: 40*7 + 8*6 + 1. A lower bound is satisfied by a loader that
    quietly took a third of the layers from a bf16 fallback.

F7  The rationale was inverted. Upstream calls `self.tokenizer(text, ...)` —
    `__call__` with its default `add_special_tokens=True` — so upstream DOES run
    the post-processor and we do not. Identical on this checkpoint because its
    `special_tokens` map is empty, measured. "THE TWO REFERENCES DISAGREE" also
    overstated it: both let the post-processor run, and only the explicit BOS
    prepend differs. Both corrected.

F8  `kv.dtype` on the production prompt path was f32 where upstream resolves
    bf16 and where the attention itself runs bf16. Narrowed, not annotated. It
    was never wrong — it was WIDER, which is why nothing could see it: with the
    cache back at f32 the new conditioning gate reproduces 0.0617859 / 0.0394362
    byte for byte. Half the cache bytes, and it stops taking `Gemma4AttnBlock`'s
    two-cast-buffers-plus-CastF32 arm on every layer.

F9  The dropped `docs/FEATURES.md` edit is reapplied onto the campaign's
    rewritten row, truthfully: "Text tower RUNS" alongside the `encoder_path`
    refusal, which another change owns and this one does not touch. Row 533
    chars, cells 60/28/217/215.

    `docs/USAGE.md` is owed too, and the debt turned out to be real rather than
    procedural: line 372 still said "the Gemma-4 12B text tower is not ported",
    which is false and which the paragraph 85 lines below it already
    contradicted. One document, two answers about one model. Corrected to state
    that the tower runs and to defer to that paragraph for what still blocks a
    prompt. The `encoder_path` passage itself is untouched — it belongs to the
    change that owns F1.

────────────────────────────────────────────────────────────────────────────────
NOT CLOSED HERE, AND OWED

F1 and F6 are out of scope by instruction — another implementer owns whether the
`encoder_path` refusal can be lifted now that L9c landed the connector weights.

The spec is operator-owned, so this reports rather than edits it. Two things it
needs. First, §4.2's open question stands and should not be narrowed by anything
above: the shipped NVFP4 tower's output is still never compared to an
independent oracle, so "all 49 hidden states within the oracle's bf16 noise
floor" is proven for the SYNTHETIC reduced tower with bf16 weights and not for
the quantized one that ships. PR #571 built the independent-oracle correlation
technique that would close it. Second, the position-numbering claim appears in
the spec in the same overclaiming form corrected here.

────────────────────────────────────────────────────────────────────────────────
GATE

    cmake -S . -B bld -G Ninja -DCMAKE_BUILD_TYPE=Release -DVLLM_CPP_BUILD_EXAMPLES=OFF
    cmake --build bld -j 12                    BUILD_EXIT=0, no ENOSPC/BFD, df 88%
    ctest -N                                   409 tests
    ctest -j 8 --output-on-failure             409/409 passed, exit 0
    ./bld/tests/test_ltx2_text_encoder         26 cases / 4115 assertions, exit 0
                                               (baseline was 23 / 3583)

`scripts/agent-preflight.sh` fails `doc-checkpoint range` on commits b0aa475,
d67f812 and aa6aa0e. All three are ancestors of the branch head this work
started from and none is touched here.

Issue: #435

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…that was only a witness

Review findings S1, S2, S4-S7 on `43aa5837`. The reviewer's verdict on the code
was that it is the strongest of this campaign and that the docs cell over-reads
it; nothing here redesigns anything.

S1 (BLOCKING) — A PUBLIC DOC ASSERTED A RENDER NO RUN SUPPORTS. `docs/FEATURES.md`
read "e2e at 320x192/25f from a TYPED PROMPT via Gemma-4: coherent scene, valid
MP4+WAV". Both halves were attached to a run that did not happen. The 320x192/25f
arm is L9c's, and this record's own L9c section says it plainly: the conditioning
was `--prompt-valid-rows 24` over SYNTHETIC N(0, 0.2), 104 of 128 rows were the
connector's trained `learnable_registers`, and "It is not a depiction of a
prompt." L10's real-checkpoint run produced conditioning only, no frames. L13's
own gate is fixture-only, CPU Release.

OPTION (b) TAKEN — state what happened, do not manufacture the run. The arithmetic
is the reason, not squeamishness: L9c's 320x192/25f arm bottomed out at 68.2 GiB
MemAvailable on a 119 GiB box that REBOOTS rather than OOM-kills, the tower is a
further ~24 GB of host bf16 (ltx2_video.cpp:846), and at the time of writing
dgx.casa's `$HOME/gpu.lock` was held by another session's `ctest` with root at 99%
(62 GiB free). Risking the box for one number, with other agents live, is not a
trade this finding asks for. The cells now say the render was register-conditioned
and that a prompted one is OWED.

S2 — `docs/STATUS.md` still said "the Gemma-4 tower is owed, so no prompt encodes
yet", which this PR made false. Corrected without growing the page: the new cell
is 216 chars, under the 220 that `oversized_cells` counts, so the ratchet is
untouched.

S4 — THE COMPOSITION'S VALUE ORACLE IS OWED, and is now recorded where a reader
meets the instrument. `last_conditioning()` is a WITNESS, not a gate: the
reviewer's R6 (video conditioning x1.5 after the connector) and R7 (conditioning
rows REVERSED) each passed all 485 assertions with exit 0. A digest detects
CHANGE; nothing at this level pins VALUES. The per-brick oracles are real and
untouched; the two JOINS - `Ltx2ConnectorCreateEmbeddings` and the `Generate`
composition - have none, and both mutations live in exactly that gap.

Recorded rather than closed, with the closure specified and its one prerequisite
VERIFIED so the next implementer does not have to: upstream's counterpart is
`EmbeddingsProcessor.process_hidden_states` (embeddings_processor.py:97-117), in
the same package `gen-ltx2-pipeline-goldens.py` already executes at section 10,
and that generator reproduces its committed output BYTE-FOR-BYTE on the pinned
upstream (md5 53e2a6aba8885d7d58302ad0b7b09eb4 both sides, LTX-2 clean at
fd4ded7f, vllm-omni at a4ea67a2), so a section can be added without disturbing
anything already gated.

S5 — A DATA RACE ON THE API THE HEADER ADVERTISES, fixed rather than documented.
`last_conditioning()` read `impl_->trace` without the mutex `Generate` holds. It
now returns BY VALUE under that mutex; a reference could not be made safe, since
the lock is released before the caller reads. The second half is real too: the
trace is filled before the denoise loop, so a `Generate` that throws later left a
healthy-looking trace for a render that never completed. New `completed` flag,
set at the single successful return.

Gated in BOTH directions rather than asserted, on a REAL refusal - keyframe /
reference conditioning is refused after the trace is written, so a prompted
request carrying a reference image fills the trace and then fails:

  * drop `completed = true`            -> 3 cases RED, exit 1
  * set it at trace-fill time (pre-fix) -> the new case RED, exit 1

Tree restored byte-identically after each (sha256 22342f84...c546 before and
after).

S6 — TRUE VALUES, NOW RECORDED. The four V2 markers were correct but nothing in
the repo carried the header they came from, so the next reader needed the 18.72 GB
checkpoint mounted. The observed `__metadata__["config"]["transformer"]` is now
recorded with its path, byte size and revision, at the fixture and in the record.
All four present, none drifted; `text_encoder_norm_type: PER_TOKEN_RMS`
corroborates independently and the selector deliberately does not read it.

And a CAUSE CORRECTED. The fixture said an earlier partial marker set "gated no
variant selection at all". `Ltx2SelectTextFeatureVariant` DOES refuse a partial
set (ltx2_text_encoder.cpp:184-192). It never fired because no production path
CALLED the selector before L13 - the keys and the first caller landed in the same
commit.

S7 — ONE GUARD PRESENTED AS A POSITIVE IS UNGATED. The right-pad precondition
guard gets the same sentence the mask-value guard already had. No reachability is
claimed: no probe was built that fails to reach it, and a mutation that moves
nothing is not evidence of unreachability.

ONE SELF-CORRECTION worth naming, since it is this campaign's own failure mode. I
first replaced "+~24 GB text tower" with an on-disk figure, believing the number
ungrounded. It is grounded - 12B params at bf16, stated at ltx2_video.cpp:846 and
in docs/USAGE.md - and the resident figure is the useful one for a memory cell.
Reverted.

GATE. CPU Release, clean configure, BUILD_EXIT=0, build logs clean of
`No space left` / `BFD assertion`, df 53-67G free throughout.
`ctest -N` 414 registered; full `ctest -j4` 414/414 passed, 0 failed, exit 0
(test_voxtral_e2e skipped). test_ltx2_video 29/485 -> 30/499 (the one new case),
test_ltx2_loader 20/2371, test_ltx2_text_encoder 23/3583, test_ltx2_pipeline
37/2382, test_capi 55/505 - all unchanged and all SUCCESS with exit 0 read
separately from the summary.

`scripts/agent-preflight.sh --staged` passes `doc-checkpoint --staged`,
`now-current --staged` and `check-public-doc-tables`. Its `doc-checkpoint range`
failure is INHERITED and re-verified here: b0aa475, d67f812 and aa6aa0e are
each `--is-ancestor` of the base SHA 67a7b1c.

Issue #435.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
, #604)

An exhaustive sweep of every reachability claim in the tree measured 25 and found
six false, at sites no earlier round on this branch enumerated. The pin list in
test_ltx2_vae.cpp that rounds 1-4 kept repairing is correct in every entry and is
untouched. Nothing here weakens a bound, adds tolerance or deletes a gate: the
suites keep their exact case and assertion counts.

Every number below was reproduced on this tree before the text it falsifies was
edited, one mutation per leg, each leg preceded by a FORCED rebuild of the
pristine tree proved green and followed by a restore verified back to the
pre-mutation md5. Binary md5s were compared pre vs mutant on every leg and
differed on all ten, which is the discriminator for the ninja-mtime leak that
would otherwise let one leg's mutation survive into the next.

1. Ltx2ConvVideoDecoderConfig::pixel_norm_eps. test_ltx2_vae.cpp said 1e-8 ->
   1e-6 "leaves every golden green". It REDS "the video decoder's norm_eps is
   gated where it BINDS" at CHECK( 0.000169305 <= 5e-06 ). ltx2_video_vae.h has
   recorded this correctly since d45bcb5; the test file contradicted its own
   header, so the test file is what moves.

2. "Unlike the decoder pair". Both halves of that pair are reachable. The audio
   decoder's pixel_norm_eps 1e-6 -> 1e-4 REDS 5 goldens across three arms --
   0.0120053, 0.00461239, 0.00302449, 0.00245912, 0.0120053 -- and the video half
   reds per (1). All four PixelNorm epsilons are numerically gated.

3. kLtx2UpsamplerNormEps, claimed invisible at BOTH ltx2_upsampler.h and
   test_ltx2_pipeline.cpp. At the class's OWN 100x bar, 1e-5 -> 1e-3 REDS all
   three arms of "the latent spatial upsampler reproduces upstream": PixelShuffle
   0.0289409, Rational2 0.0347079, Rational1p5 0.0649014.

4. kLtx2UpsamplerNormGroups, called a member of the same class. 32 -> 16 REDS the
   same three arms at 0.63738, 0.633718, 0.874346.

5. kLtx2ConnectorRmsNormEps, claimed inert at BOTH ltx2_connector.h and
   test_ltx2_pipeline.cpp on the reasoning "the fixture's rows are never
   near-zero". That is not what rms_norm does with it: the epsilon is added to the
   MEAN SQUARE, so it perturbs every row. 1e-6 -> 1e-4 REDS 5 connector arms --
   Split 0.0558581, Interleaved 0.104284, Float64 0.140343, NoRegisters
   0.000542641, GatedNoBias 0.0892045.

6. kLtx2BlurKernelSize, called reachable "only through a default upstream never
   passes explicitly". A default upstream never overrides IS the shipped width,
   which ltx2_upsampler.h:98 already said -- the two records disagreed and the
   test file held the wrong one. 5 -> 3 REDS the upsampler's Rational1p5 arm at
   0.689782, and only that arm, because BlurDownsample runs on the rational `den`
   (ltx2_upsampler.cpp:439) and 1.5 -> {3, 2} is the one covered scale with
   den != 1.

7. kLtx2Res2sSigmaUpClamp -- a REASONING error, not a fixture gap, and the one
   worth reading. Both ltx2_pipeline.h and test_ltx2_pipeline.cpp argued "eta <= 1
   keeps sigma_up <= sigma_next, so the clamp never binds". <= includes ==. `step`
   forms sigma_up = sigma_next * eta (ltx2_pipeline.cpp:339), so at eta = 1 the
   two are equal and `min` takes sigma_next * 0.9999 on EVERY step -- the clamp is
   not a fallback, it is the only thing keeping the residual off zero exactly
   there. A 1% move, 0.9999 -> 0.99, REDS the Eta1 arm the suite already runs, at
   0.086 (index 0) and 0.130563 (index 1); EtaHalf stays green because 0.5 *
   sigma_next is below the clamp, and Eta1 index 2 stays green because sigma_next
   == 0 returns the denoised prediction unchanged (:181-182). The corrected note
   states the boundary, not just the verdict.

8. kLtx2TextNormV1Eps / kLtx2TextNormV2Eps. Two blurbs in ltx2_text_encoder.h
   ("invisible to any golden built from random values", "Reachable only when...")
   contradicted the CORRECT detailed note 14 lines above one of them, which
   already warns of exactly this. Both epsilons are additive on an O(1)
   denominator against a 1e-5 band. V1 1e-6 -> 1e-4 REDS
   "`_norm_and_concat_padded_batch`, both padding sides" at 0.000524044 and
   "FeatureExtractorV1" at 7.53999e-05 / 6.61612e-05. V2 likewise REDS
   "`norm_and_concat_per_token_rms`" at 0.00232971, carrying into
   "FeatureExtractorV2" and the hand-off at 0.000344872 / 0.000259042 /
   0.00039053. The blurbs now agree with the note.

9. The class prose itself. ltx2_video_vae.h:106-107 said the tensor comparison
   "accepts any value at all -- including 0.0, and including one 100x off". False
   even of its own remaining members: kLtx2RmsNorm2dEps at 1e-12 -> 1.0 REDS "the
   video ENCODER (*_res family)" and "the video encoder CROPS a frame count that
   is not 1 + k*factor", both at 0.000525832. The per-entry verdict (1e-12 -> 0.0
   green) stands and is unchanged. "Never BINDS at the shipped value" and "is not
   read" are different statements, and only the first was ever true.

Per #604 the standard is now explicit in the prose: only a probe that FAILS TO
REACH proves unreachable, a mutation that happens not to move anything proves
nothing, and every corrected claim therefore names its magnitude and its arm.
Magnitude escalation to the class's own 100x bar is what exposed (3), (5), (6)
and (9); a mere 1% exposed (7).

Every constant stays PINNED. Reachability by a golden and a source-anchored pin
are not substitutes: a regeneration that moves a constant and its expected tensors
together passes every value comparison, and only the pin compares against
upstream's own signature. The corrected text says that instead of claiming the
pin is the only gate.

docs/USAGE.md gains the operator-facing half of the same finding, in the pipeline
golden regeneration recipe: which constants a regenerated ltx2_pipeline_goldens.inc
now carries, and why the pin cases are still not redundant.

GATE, CPU-only Release, VLLM_CPP_CUDA=OFF, 20 cores:
  BUILD_EXIT=0, no "No space left" or "BFD assertion" in any build log, df 87%.
  ctest -N            399 tests
  ctest -j 8          398/399 passed; test_engine_core_proc failed and PASSES
                      serially (known -j flake), so the gate is green.
  test_ltx2_vae            36 cases / 3039 assertions, exit 0
  test_ltx2_pipeline       35 cases / 2358 assertions, exit 0
  test_ltx2_text_encoder   17 cases / 3350 assertions, exit 0
Counts are byte-identical to the pre-edit baseline, which is the correct result
for a comments-and-records change: nothing was added, removed or relaxed.

The pre-existing `doc-checkpoint range` failure on b0aa475 and d67f812 is
NOT repaired here. It reproduces identically at the untouched head ef83d94
(`check-doc-checkpoint.py --base origin/main --head ef83d94`), predates this
work by 56 commits, and belongs to the L4 / L7+L8 phases rather than to this
scoped repair.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
S8, the one blocking finding of the re-review. `docs/USAGE.md` still described
the pre-L13 world in two places, and this PR is what falsified them.

`:487` claimed "the Gemma-4 text tower is still not ported"; `:499-510` restated
that a prompt is refused because the connector weights sit among the modules the
DiT loader refuses, so "`encoder_path` is still refused" and "`has_encoder()` is
still false". At this head `im.has_encoder = true` on the `encoder_path` branch
(`ltx2_video.cpp:893`), and the connector families load under their own contract
(`ltx2_loader.cpp:416-427`). The file also contradicted itself: `:372`, added by
this PR, opens "A typed prompt works."

Provenance, since a later reader should be able to re-check the cause rather
than trust the repair: `:487` arrived at `e48c86253` (L9c) and `:499` at
`ab6671394` (L10), BOTH TRUE when written; `43aa58377` in this PR made them
false and left them standing.

The "renders a scene, not YOUR scene" material is RE-ATTRIBUTED, not deleted. It
is still true of the L9c render and of the embeds path, so it now says which run
it describes: `--prompt-embeds` with `--prompt-valid-rows 24` over synthetic
N(0, 0.2) rows, no tower on the path, 104 of 128 connector rows the connector's
own trained `learnable_registers`. What it must stop being is a property of the
`--encoder` + `--prompt` command L13 rewrote the example into, because that is
the S1 defect in the other direction: NO prompted render has been run in either
direction, so the page now claims nothing about what that command renders --
not that it puts a fox on the screen, and not that it fails to.

Two accuracy repairs in the same sweep:

- The `Ltx2ConditioningTrace` header said both composition mutations "passed all
  485 assertions ... on this exact head". 485 was `43aa58377`'s count; this head
  is 499, so a comment whose whole purpose is precision named a number no run of
  it could produce. RE-MEASURED here rather than transcribed, because a reviewer
  report is an input and not a gate result: video conditioning scaled x1.5 after
  the connector, and the conditioning rows reversed, each applied alone, each
  recompiled and relinked (verified in the build log), the tree restored
  byte-for-byte and re-verified green between legs. BOTH still pass, at 30 cases
  / 499 assertions, exit 0. The verdict did not move; the COUNT had drifted.

- `last_conditioning()` was documented as safe to call from a server thread
  while another renders. True as to safety, but `Generate` holds that same mutex
  for the whole render, so the caller blocks for minutes rather than getting a
  stale-but-immediate answer. Stated.

One sibling found by sweeping the whole file rather than fixing the instance in
front of me, which is what #604 says has failed four rounds running. The AUTO
duration comment said the head "needs the encoded prompt this engine cannot
produce" -- a fifth refusal-reason that went stale while its refusal stayed
correct, since L13 produces exactly that. The real reason is now recorded: no
duration head is ever constructed here, and `duration_head_path` is accepted in
`kKnownLoadExtras` while no code reads it, so the extra is inert. Named in
`docs/USAGE.md` too, where a reader would otherwise supply it and silently get
the recipe default.

NOT PAID, and named rather than left to be found: `.agents/benchmark-record.md`'s
L13 section carries the same superseded 485/485 pair. Correcting it is not free
-- `check-doc-checkpoint` classes any benchmark-record edit as a measurement and
demands `docs/STATUS.md` + `docs/BENCHMARKS.md`, and those are the surfaces the
re-review passed and told this repair not to disturb, with STATUS at its
`oversized_cells` ratchet. Manufacturing an edit to a blessed surface to turn a
gate green is the thing this protocol forbids, so it is reported instead.

Gate (CPU Release, no CUDA): BUILD_EXIT=0, 0 warnings, no `No space left` /
`BFD assertion`, disk 87%. `ctest -N` 414 registered; full `ctest -j8` 413 pass
/ 1 skip, the single failure `test_engine_core_proc` a known `-j` flake that
passes serially. `test_ltx2_video` 30 cases / 499 assertions, exit 0.
`agent-preflight.sh --staged` doc-checkpoint and now-current both ok; the
`doc-checkpoint range` failure is pre-existing on this branch (`b0aa475a3`,
`d67f8125e`, `aa6aa0ecd`) and untouched here.

Refs #435, #604.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…, #604)

A precision nit in the note 4f1ec6e added, in the one place it matters: the
deliverable of this branch is an accurate record, so a loose sentence in it is
the same defect one size down.

The blur-width entry read "1.5 -> {3, 2} is the one supported scale of the three
with den != 1". Read as written that says the SUPPORTED-SCALE MAP has one entry
with a non-unit denominator, which is false -- 0.75 -> {3, 4}
(ltx2_upsampler.cpp:296) has one too and would reach kLtx2BlurKernelSize just as
well. What is actually true is narrower: of the three arms the suite runs
(PixelShuffle at 2.0 non-rational, Rational2 at 2.0 -> den 1, Rational1p5 at 1.5
-> den 2, per ltx2_pipeline_goldens.inc:1335, :1568, :1801), only Rational1p5 has
den != 1, so only it reaches the constant. That is ARM COVERAGE, and 0.75 is an
uncovered scale rather than a nonexistent one.

Stating it the loose way would have left a reader believing the map cannot grow
another reachable arm, which is exactly the kind of inference #604 asks these
notes to stop making. The corrected text names 0.75 explicitly so the gap is
visible rather than argued away.

Comment text only, in one test file.

GATE, CPU-only Release, VLLM_CPP_CUDA=OFF:
  BUILD_EXIT=0, no "No space left" or "BFD assertion", df 85%.
  ctest -N     401 tests
  ctest -j 8   100% tests passed, 0 failed out of 401   CTEST_EXIT=0
  test_ltx2_pipeline   35 cases / 2358 assertions, exit 0
Counts unchanged from 4f1ec6e and from the pre-edit baseline.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…easured

Reviewed across four rounds plus one exhaustive sweep. The sweep is what
finally worked: rounds 1-4 each repaired the pin list in test_ltx2_vae.cpp and
stopped, so the same defect class survived at five sites nobody had enumerated.
Enumerating all 25 claims and mutating each found six false in one pass. All six
are now corrected, each carrying the magnitude and arm it was measured at.

The best of them is a reasoning error rather than a fixture gap.
kLtx2Res2sSigmaUpClamp was documented as "never binds on a well-formed schedule,
so no value comparison can see it". Ltx2Res2sStep forms sigma_up = sigma_next *
eta, so at eta = 1 the min takes sigma_next * 0.9999 on EVERY step -- the clamp
is the only thing keeping residual = sqrt(next^2 - up^2) off exactly zero, and a
1% change reds two goldens on an arm the suite already ran.

Docs conflict resolved to the eps side, which is a strict superset: it adds the
CRF-and-2-pixel qualifiers its own upstream verification licensed, and the
sentence distinguishing "the VAE encoder landed in L11" from "the engine can
reach it". I verified that second claim against the tree rather than taking it,
because a sentence of exactly that shape has gone stale five times in this
campaign; the refusal at ltx2_video.cpp:836 makes the same distinction, so the
doc matches the code.

Issue: #435, #560, #604

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
mudler added 9 commits August 13, 2026 10:38
…ck came from

`vllm::Pool()` is a process-wide free list keyed by BYTE SIZE CLASS ONLY. The
device is not in the key, so a block allocated through one backend is handed to
a `DBuf` running on another. One fault, two symptoms, selected by direction: a
`cudaMalloc` block reaching a CPU-backend forward SIGSEGVs host-side (and
`compute-sanitizer` is clean, because the fault is not on the device), while a
host block reaching a CUDA forward returns a UNIFORM `0x7fff0000` quiet NaN --
computed and propagated, not garbage read.

Three arms already separate the cause from its neighbours: `VT_POOL_BYPASS=1`
(free list removed) is 13/13 green, a per-case `DevicePool` is 13/13 green, and
`VT_POOL_EXACT=1` (reuse kept, size-class rounding removed) is STILL RED. So it
is cross-device reuse, not over-allocation, and not the pool's existence.

Spec only; no implementation in this commit, which is the point of committing it
first. It carries scope, the upstream anchors read at the pin (vLLM's allocation
handle carries the device as field 0; torch's cache is per-device by
construction), the design, what was rejected and why, the RED-first tests, the
gates and the baselines that must not move, the risks and the stop conditions.

Refs #516

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…rough DBuf

The gate for #516, and it is RED at this commit deliberately: the fix lands in
the next one, so git itself records that the test was seen failing rather than
written to fit a change that had already been made.

    test cases:  4 |  2 passed | 2 failed | 0 skipped
    assertions: 15 | 10 passed |  5 failed
    Status: FAILURE!   exit=1

The decisive assertions are not the pointer comparison but the ownership ones:
`b.Owns(on_b)` is FALSE and `a.Owns(on_b)` is TRUE -- device 1 did not merely
receive an equal pointer, it received a block that device 0's allocator made.

It allocates through `dense_attn::DBuf`, the seam every production forward draws
scratch from, so it holds the path the LTX-2.5 device suite crashes on rather
than a paraphrase of it. No GPU, no checkpoint, no NAS, milliseconds: two fake
backends stand in for two devices, the technique test_backend_multidevice and
test_reference_tier already use.

Two of the four cases pass now and must KEEP passing. Reuse on one device
returns the identical block, and two byte sizes in one class still share a
block. Without them a "fix" would be indistinguishable from VT_POOL_BYPASS=1,
which also separates the devices -- by reinstating the per-op cudaMalloc/cudaFree
sync storm the pool exists to remove.

Every case uses its OWN size class, so no case can be decided by what another
left in a free list, including under --order-by=rand. Two test-side properties
are load-bearing: a fake backend never returns a block to the C allocator (these
cases compare pointer identity ACROSS a free), and no fake backend is destroyed
before exit (the pool is keyed on backend identity, and a reused address would
let one case's pool answer another case's question).

Refs #516

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…l "the pool"

Turns the RED-first gate green: 8 cases / 26 assertions SUCCESS, from 2 of 4
cases failing at f4be8a4e2.

The device is now STRUCTURAL, not a field a caller has to remember. A
`DevicePool` is bound to one backend at construction, `Pool(b)` resolves the pool
for a device, and the no-argument `Pool()`/`AuxPool()` are GONE -- "the pool"
without a device was the defect, so it is no longer expressible. `vt::Backend*`
is the device identity, since the registry hands out exactly one Backend* per
Device{type,index}; that puts the device in the key with NO new virtual on
vt::Backend, so not one backend implementation is touched.

Lookup sits on the hottest allocation path in the tree -- a DBuf resolves its
pool on every construction -- so a thread-local last-(backend,pool) memo makes
the steady state a single pointer compare. No hash, no lock, on the hit path.

Every pool operation VERIFIES its backend and throws. Deliberately not an
`assert`: the gate builds are Release/NDEBUG, where an assert compiles out and
the silent cross-device hand-off returns. The only way to reach the throw is an
`ActivePoolScope` aimed at another device's pool, which is exactly the mistake
this row makes impossible to make quietly.

`DBuf::ReleaseShared()` replaces 31 copy-pasted shared_ptr deleters that closed
over a byte count ALONE. Those named neither the device nor the pool, so they
returned another device's block -- and, separately, an AUX-STREAM block -- to the
main pool. That second bug was live on every path that used the idiom. Each site
goes from three lines to one, and the backend-less `Put` overload is removed with
its last caller.

Two more instances of the same ambient-device assumption, found while fixing it
and repaired here rather than left to be rediscovered: the decode-graph
`PersistentDecodeInputPool` was a process-wide static, and `ResolveDevicePool
Policy` memoized whichever device asked FIRST and applied its residency cap to
every later one. Both are now per device. Byte-neutral today (every platform's
`device_pool_cap_bytes` is 0), which is why it is safe to do here.

The two per-caller workarounds for this bug are REMOVED, not kept: the
`ActivePoolScope` around the LTX-2.5 bf16 CPU arm (the only test in the tree that
reaches the SILENT direction) and the per-arm pools in the DeepSeek-V2 CUDA-vs-CPU
case. Both are again detectors instead of callers that were scoped away from the
hazard, and each carries a comment saying not to re-add the scope: it would pass
whether or not the pool is correct.

Mutation-proven, each restored byte-for-byte afterwards. Drop the device check ->
only the refusal case fails (7/8). Also collapse the pool table to one pool ->
4 of 8 fail, exactly the two direction cases plus Drain plus the refusal. Make
ReleaseShared use the device's main pool instead of the buffer's own -> only the
scoped-pool case fails. The two "still a pool" cases (reuse returns the identical
block; two sizes in one class share a block) pass throughout, so this is not
VT_POOL_BYPASS wearing a fix's clothes.

NO docs/FEATURES.md OR docs/USAGE.md UPDATE, AND HERE IS THE ARGUMENT FOR IT,
attached to the diff it excuses because this protocol has no waiver registry.
`check-doc-checkpoint.py` classifies any edit under `src/vllm/model_executor/
models/` as `feature_surface` and any edit under `include/vllm/` as
`user_usage`, so it asks this commit for both. Nothing here is either. No
feature, model, backend or quantization surface changes; no command, C API,
config key, install step or workflow changes. The 24 model TUs are touched by a
mechanical three-lines-to-one call-site rewrite, and the header change is an
internal allocator seam that `include/vllm.h` does not expose. Writing filler
into two public projections to satisfy a path prefix would make them less true,
not more. AGENTS.md states the same rule in prose the other way -- "Editing
src/, include/, or tests/ on its own owes none of these" -- and says the checker
and the prose are deliberately not kept in sync; this is one of the places they
disagree. The gate also already fails on this branch's base for the same reason
at b0aa475 and d67f812, so this is not a new red. A reviewer who does not
accept the argument should not merge it.

Refs #516

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…, and what is still unattributed

What neither the code nor git records: what was measured, what was rejected, and
why each default is set the way it is.

Both symptoms were reproduced at the RED commit on GB10 and both are gone at the
fix. The SIGSEGV direction: `--rand-seed=7` exit 139 with the trap it carries --
44 assertions, 0 failed, beside a crash. The SILENT direction: the shipped 21B
FP8 DiT returning `REQUIRE(std::isfinite(v))` FAILED, which needed the opt-in
fixture actually satisfied, so the checkpoint was proven READABLE first -- with
the NAS down that case SKIPS and the suite reports SUCCESS, an environmental
failure wearing the shape of a repair. After: 13/13 and 6176 assertions in every
ordering, with no per-case pool scoping left anywhere in the file.

#486 was a hypothesis and is now a measurement, in both directions: at the RED
commit `test_minimax_h3` SIGSEGVs with the pool on and is 79/79 under
`VT_POOL_BYPASS=1`; at the fix it is 79/79 with the pool ON.

The nine dgx full-suite failures are recorded as UNATTRIBUTED rather than
explained away. The dgx BEFORE arm could not be run -- the box was at 99-100%
disk, so two 31 GB trees would not fit -- and two bounded `flock -w 2700` waits
for the shared GPU lock expired without acquiring. One of the nine IS resolved:
`test_capi` reproduced on the CPU host, where this change cannot cause it, and is
8-of-8 green standalone with per-run times spanning 0.78 to 339.88 s. The other
eight get a named next step and the script to run it, not an adjective.

Also records the ENOSPC re-verification the operator asked for (no build log
contains `No space left`; local gates re-run chained to their build, ninja "no
work to do" first, so nothing here is a stale binary), the measured blast radius
(42 of 402 binaries instantiate a DevicePool; exactly one instantiates more than
one on a single-backend host), the rejected designs, and two things left open on
purpose: why a host block yields a uniform quiet NaN on GB10 rather than running
correct-but-slow, and `MoeAuxStreamFor` keying on device INDEX alone -- the same
family, unreachable today because its only call site is gated on
`SupportsAuxStream()`.

Refs #516

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…ew findings (#516)

A fresh review returned FAIL on the LANDING STATE while endorsing the fix
itself. This closes all six findings. The code the reviewer endorsed --
the device key, `ReleaseShared`, both workaround removals and
`test_device_pool` -- is unchanged in behaviour.

F1 (HIGH). The branch was based on `row/MODEL-DIFFUSION-LTX25` @ `aac24761`,
which is not an ancestor of `origin/main`, and `git merge-tree` CONFLICTED in
`device_pool.h`. Since that merge base, main changed the same file in
`49539559d` / `8fa2ecdbb` (Windows contracts, #117) with three changes the
reviewed header lacked: `__builtin_clzll` -> `std::bit_width`, an
`std::overflow_error` guard in `ClassOf`, and `static SizeClassForTest`. A
resolver taking the row's side -- the heavily rewritten side -- would have
silently reverted the portability fix and the overflow guard, and
`origin/main:tests/vt/test_cpu_isa_x86.cpp` calls `SizeClassForTest` NINE
times including `CHECK_THROWS_AS(..., std::overflow_error)`, so it would not
have compiled. The four commits are rebased onto `row/MODEL-DIFFUSION-LTX25`
@ `2d437d5a9`, which now contains main, and `device_pool.h` was resolved BY
HAND: all three of main's changes sit ON TOP of the device-keyed rewrite, not
instead of it. `git diff row/POOL-DEVICE-KEY..HEAD -- device_pool.h` is exactly
those three hunks and nothing else. `test_cpu_isa_x86` is 6 cases / 8242
assertions / SUCCESS.

The row keeps its base. `tests/vllm/models/test_ltx2_device.cpp` does not exist
on `main` at all and it is the only test exposing the SILENT-NaN direction, so
deleting its workaround -- which the row requires, because a list of remembered
callers is what this fault was -- needs LTX-2.5 to land first.

F2 (MEDIUM). The row had no record surface, and merging would have made an
existing record FALSE. `#516` is now in the issue table of
`.agents/roadmap_v1.md`; the spec carries a `## Now`; `docs/STATUS.md` carries
the paragraph under "Backend detail"; and `porting-inventory.md` §L8, which
still said the shared `DevicePool` "is DEVICE-BLIND ... repairing it is owed as
its own row", now says what actually happened. `docs/BENCHMARKS.md` is
deliberately not written: this row claims no measurement on any axis.

F3 (MEDIUM). Recorded in the spec's §11 with the dgx BEFORE/AFTER pair, the
disk and lock state at both ends, and what remains unattributed.

F4 (LOW) is CORRECT and the assertions are reworded. Enumerated at the base
commit: none of the nine `Release()` sites (`gemma4_moe.cpp:1197,1541`,
`qwen3_5.cpp:6324,6520,6820,7100,7134,8034,8065`) is inside or under any of the
four `ActivePoolScope` regions (`laguna.cpp:2574`, `qwen3_5.cpp:5468,8644,8964`),
which are leaf-ward of all of them. The aux-pool half was LATENT, not live, and
`device_pool.h`, `dense_device_glue.h` and spec §4 D4 now say so. `ReleaseShared`
stands on its own merits and is untouched.

F5 (LOW). Both debug lanes are GREEN, which matters because §10 hands
`VT_POOL_BYPASS=1` to the next reader as the cheap discriminator: a suite that
reds under the lane it recommends costs that reader an hour deciding whose red
it is. A case whose subject is REUSE now states what the ACTIVE lane does, and
the size-class case states sharing by default and SEPARATION under
`VT_POOL_EXACT` -- which is spec §5 T1.3's second clause, promised since the
spec was written and asserted nowhere until now.

F6 (LOW). The per-device-type memoization made `platforms::GetPlatform` a
per-type call, so an unregistered platform now throws where it used to inherit
the first device's cap. Correct, and it had no test; it has one. The
`cached[...]` index gains the bound `platforms::Index()` already applies to the
same value, in both mirrored copies.

Nit: spec §5 T1 said the fakes sit on the `kXPU` slots; the test uses `kCPU`
indices 0/1 and is right, because `kXPU` has no registered platform and every
pool case would have measured the platform registry instead. The spec is
corrected and `kXPU` now earns exactly the one case that is about that throw.

New mutation evidence, on this tree:
  * bound-check + refusal removed (`ResolveDevicePoolPolicy` defaults an
    unregistered platform to cap 0) -> 8 passed / 1 failed, the T1.7 case only
  * `VT_POOL_EXACT` made inert in `ClassOf` -> 8 passed / 1 failed under
    `VT_POOL_EXACT=1`, 4 assertions, the size-class case only
  * `Bypass()` forced false -> 4 passed / 5 failed under `VT_POOL_BYPASS=1`
Tree restored byte-for-byte after each (md5 verified).

CPU host, RESOLVED tree, CLEAN rebuild: `BUILD_EXIT=0`, zero warnings under
`-Werror`, zero `No space left`/`BFD assertion`, `ctest -N` 412, full `ctest`
412/412 passed exit 0. `test_device_pool` 9 cases / 30 assertions SUCCESS
(24 under bypass, 31 under exact, all SUCCESS). Every §6 baseline is where it
was except `test_ltx2_vae` 16/1816 -> 33/2602, which is `6c9374ebc` on the
CAMPAIGN branch (the VAE encoders) and not this row -- this row does not touch
that file. That drift is exactly what F1 predicted a stale base would hide.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
The previous repair (56a917c) fixed the two blocks it was pointed at and then
proved completeness by grepping for `still not ported`, `` `encoder_path` is
still refused `` and `` `has_encoder()` is still false ``. All three returned
nothing -- but those were the phrasings it had just written, so the search could
only confirm itself. Searching the vocabulary of the CLAIM instead of the
sentence found six more instances of the same false statement, in three
docs/USAGE.md sections that were never swept.

The file asserted both "A typed prompt works." (:372, added by this PR) and
"there is no text encoder" (:1817). Both cannot be true.

CLOSED, each against the code site that makes it true:

1. :1816-1821, a bolded present-tense block whose six sub-claims are all false at
   this head. `ltx-2.5` is one of exactly two registered video families
   (REGISTER_VLLM_VIDEO_FAMILY, ltx2_video.cpp:1529); --encoder loads the tower
   and sets has_encoder (ltx2_video.cpp:893); both VAEs and the pipeline layer
   ship (ltx2_video_vae.cpp, ltx2_audio_vae.cpp, ltx2_pipeline.cpp); /v1/videos
   registers family-agnostically through LoadVideoEngine; and ltx2-gen renders,
   documented at :436-450 of this same file. It arrived at 3d89f6f -- the first
   LTX commit, where it was true -- and was never revisited as L3 through L13
   built each of the six pieces it denied.

2-3. :1920 heading "(no render path yet)" and :1924-1925 "There is still no
   render path, so these are library entry points and not a command". Those
   loaders are exactly what the render path drives: --dit / --video-dit reaches
   Ltx2StreamDitToDevice / Ltx2LoadDitFromSafetensors at ltx2_video.cpp:576-577,
   and --encoder / --video-encoder reaches Ltx2LoadTextEncoderFromSafetensors at
   ltx2_video.cpp:851.

4-5. :1963 heading "(no render path yet)" and :1965 "There is no LTX-2.5 render
   path. This section documents one brick." It is one brick OF the shipped path.

6. :1927-1932 said the DiT loader refuses FIVE families, "and the two
   *_embeddings_connector towers", "which still reports every one of them in
   Ltx2DitCheckpoint::unported". There are THREE. UnportedFamilies filters the
   connectors at ltx2_loader.cpp:439 via LoadedElsewhere, and RefuseUnported's
   own message says so in capitals at ltx2_loader.cpp:461-464 -- the checker's
   message is the authority on what it enforces. This is the identical claim the
   previous repair retired 400 lines earlier, left standing precisely because the
   sweep was built from the text that had just been fixed.

Completeness was proved this time from the claim's vocabulary and its subject
rather than from the repaired sentences: no render path, no text encoder, no VAE,
no pipeline, will not work, one brick, not a command, unported, refuses,
embeddings_connector, not ported, is refused, still no, yet, library entry point,
layout and forward, asking the video engine -- over docs/, README.md, examples/
and both --help surfaces a user sees. 189 hits read.

REPORTED, not fixed, because fixing half of it is worse than reporting it: this
branch bumped VLLM_ABI_VERSION 17 -> 18 and added vllm_video_engine_family
(36 VLLM_API declarations, was 35) at 3db9233, and left docs/USAGE.md:1464-1465
and README.md:189 and :388 all saying "17" and "35". origin/main is self-
consistent at 17/35, so this PR is what falsified them, and docs/STATUS.md:119
already says v18 -- the tree disagrees with itself today. The USAGE half alone
would pass check-doc-checkpoint, but check-readme-structure refuses the README
half without a landing-source edit, and no landing-source edit is legitimately
owed here: examples/server/main.cpp:15's "published as vllm_server_main at ABI
v17" is a statement about WHEN that symbol shipped, verified correct at
c1716fd. Manufacturing an edit to a blessed surface to turn a gate green is
what this protocol forbids, and correcting one of two surfaces that carry the
same number would leave a reader unable to tell which is right. The owed change
is three lines: 17 -> 18 and 35 -> 36 at those three sites, together.

Gate, CPU Release, x86_64, this worktree, no CUDA:
- CONFIGURE_EXIT=0, BUILD_EXIT=0, 0 compiler warnings; build log clean of
  "No space left" and "BFD assertion"; disk 79G -> 64G free, 71G after cleanup.
- ctest -N: 414 registered.
- full ctest -j8: 413 passed, 1 skipped (test_voxtral_e2e), 1 failed
  (test_engine_core_proc) -- the known -j flake, which PASSES serially:
  "1/1 Test #195: test_engine_core_proc ... Passed".
- test_ltx2_video: 30 cases / 499 assertions, exit 0 -- unchanged from this
  head's recorded counts, as a documentation-only change must be.
- check-doc-checkpoint --staged: OK. check-public-doc-tables: OK.
  The preflight "doc-checkpoint range" failure is INHERITED and re-verified:
  b0aa475, d67f812 and aa6aa0e are each an ancestor of the base 67a7b1c.

This is instance sixteen in the campaign #604 tracks, and the second in this file
and this PR.

Refs #435, #604.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…ures attributed (#516, #486, #614)

Spec §11. The review's F3 said this row "must not land on a CUDA-unattributed
gate": every direct symptom of #516 needs a GPU, both removed workarounds guard
CUDA cases a CPU host never executes, and §10 had nine dgx failures with NO
BEFORE arm because the box was at 99-100% disk with a single 31 GB build tree.

The pair now exists: both arms clean-built from the SAME base, back to back on
one box, `ctest -j 1`, all three MANDATORY confirmations
printed for each and zero `No space left` in four logs.

  BEFORE  aa6aa0e, no fix   10 failed of 449   lock 08:26:13Z-09:22:00Z
  AFTER   this branch          9 failed of 450   lock 09:40:20Z-10:34:02Z
                                                 (13m45s bounded wait, not forced)

THE DENOMINATORS DIFFER BY ONE BECAUSE THIS ROW ADDS A TEST. 449 -> 450 is
test_device_pool existing in the AFTER arm and not the BEFORE one; it is not
drift, and 10-of-449 read against 9-of-450 without that is off by one test. On
the 449 both arms share: 10 failures before, 9 after, and exactly ONE leaves.

  test_minimax_h3    ***Exception: SegFault 11.73s  ->  Passed 19.06s
  test_device_pool   (does not exist)              ->  Passed

The other nine are the SAME set in both arms, and each is now matched to an
issue rather than left as a name: #233 (test_serve_low_tools, test_linear_method,
test_glm4_moe_lite_paged_engine), #248 (test_capi, test_qwen3_apc_e2e,
test_minicpm3_paged_engine, test_llama_paged_engine), #305 TENTATIVELY
(test_ops_gdn), and #614, filed by this row, for test_internlm2_paged_engine,
which had no issue anywhere. So all nine are MEASURED pre-existing rather than
argued. This row does not fix them and does not adopt them.

test_capi IS NOT THE TIMING FLAKE §10 CALLED IT, and the correction matters.
§10's flake evidence -- 8/8 under --repeat until-fail, wall times 0.78s to
339.88s -- came from the CPU HOST, where the test fails without crashing. On dgx
it SEGFAULTs, in BOTH arms, in 1.95s and 1.97s, under ctest -j 1. A sub-2-second
segfault is not a three-orders-of-magnitude timing spread, and #248 says so in as
many words. Pre-existing either way, but it goes back to #248 as a crash rather
than into a flake story it does not fit. Whether the two arms' crashes are the
SAME crash is NOT established: neither LastTest.log survives (both 34 GB trees
were deleted to keep a 98%-full box safe) and these runs were plain ctest -j 1
with no --output-on-failure, so the recorded evidence is the signal, the index
and the duration.

It also re-confirms #486 in BOTH directions on ONE box, 14 minutes apart, same
binary recipe, same lock: SEGFAULT with the pool device-blind, Passed with it
device-keyed. §10 asserted that from two separate sessions; it is now one paired
measurement.

Both 34 GB build trees were deleted after their arm. The box was at 98-99%
throughout and ended at 94 GB free.

The pair was taken at base aa6aa0e; the branch is now rebased onto 310fa16,
fifteen commits later, and the CPU gate was re-run in full there (415/415, clean
rebuild, zero warnings). Chasing a moving campaign branch with a five-hour paired
CUDA gate does not terminate, so §11 names the base the pair was taken at and
states what would invalidate it: none of the fifteen intervening commits touches
device_pool.h, dense_device_glue.h, the DBuf deleters or any pool accessor, and a
tree-wide sweep for a device-less Pool()/AuxPool()/ActivePool() comes back empty
on the new base.

§11 also records what §10 must no longer be read as saying: every number in it
was measured on a tree missing main's last 201 commits, and none of it is
carried forward. `## Now` is updated to match -- the nine are closed against
this row, and the two things that remain unestablished (the ATS/quiet-NaN
mechanism, and `MoeAuxStreamFor`'s index-only key) are named rather than
quietly dropped.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
This campaign moved VLLM_ABI_VERSION 17 -> 18 and added a 36th export
(vllm_video_engine_family) back in L1, and never updated the surfaces that
quote those numbers. They are correct on origin/main and FALSE on this branch,
which is the worst possible split: a reader diffing the two would conclude the
README was right and the header wrong.

Fixed together, because a number carried on several surfaces must move on all of
them at once or a reader cannot tell which is authoritative:
  README.md:189        ABI v17, 35 functions          -> v18, 36
  README.md:388        VLLM_ABI_VERSION 17, 35        -> 18, 36
  docs/USAGE.md:1392   VLLM_ABI_VERSION 17, 35        -> 18, 36
  docs/FEATURES.md:290 vllm_server_main (ABI v17)     -> (ABI v18)

examples/server/main.cpp:15's "at ABI v17" is deliberately NOT touched: it is a
WHEN-SHIPPED statement, verified correct at c1716fd, and rewriting it would
turn an accurate historical note into a false present-tense one.

How this was found is the part worth keeping. An implementer swept docs/ for
stale claims with 17 patterns and read 189 hits -- thorough work that found the
README/USAGE pair. It missed FEATURES.md and a second USAGE passage because its
patterns were phrasings ("no render path", "not ported"), and these say "ABI
v17" and "35 exported". A one-line grep for the SUBJECT -- the version number
itself -- found the rest immediately.

That is the same lesson as the self-confirming grep, one level up: searching for
how a claim is WORDED finds the instances you already imagined. Searching for
what the claim is ABOUT finds the ones you did not.

No source file changed, so ctest was not re-run; check-public-doc-tables and
check-readme-structure both pass.

Issue: #435, #604

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…k came from

Reviewed PASS at 2098683 after one FAIL round. #516 and #486 are the same
bug, and the fix caught a live instance of itself on this very branch.

The defect: one process-wide free list held blocks from every backend that ever
used it, so a block allocated by device 0 could be handed to device 1. CUDA->CPU
was a SIGSEGV; CPU->CUDA was SILENT, a uniform 0x7fff0000 all-NaN, which no token
gate can see. A DevicePool is now bound to one backend at construction and the
no-argument Pool()/AuxPool() are REMOVED, so "the pool" without a device is no
longer expressible.

That removal is what made the difference. ltx2_video.cpp:1154 called
ActivePool()->Drain(backend) -- the device-less spelling, draining every retained
block through one backend regardless of which allocator made it, in a stage whose
own comment says it runs on the host. It arrived with L9c, is an ancestor of the
dgx measurement base, and was live in both arms. minimax_h3_pipeline.cpp:559
carried it identically. A free-list keyed by device would NOT have caught either;
deleting the spelling turned both into compile errors.

The dgx pair settles the attribution that a prior review had to leave open:
BEFORE 10 failed of 449, AFTER 9 of 450 -- denominators differ because this row
adds test_device_pool, which passes. On the 449 shared tests exactly one moves:
test_minimax_h3 SegFault 11.73s -> Passed 19.06s. The other nine reproduce on the
base, so they are measured pre-existing rather than labelled unattributed, and
each is now matched to an issue -- including #614, filed because nothing tracked
it.

Two things the row declined to do, both right. It did not carry the recorded
test_capi timing-flake label onto a SEGFAULT that appears in BOTH arms; whether
the two crashes are the same crash is recorded as NOT ESTABLISHED, because the
logs went with the deleted build trees. And it did not re-run a five-hour paired
CUDA gate to chase a moving branch: it pinned the pair's base and named the
condition that would invalidate it, which the reviewer then re-verified against
this head.

Issue: #516, #486, #614

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
mudler added 5 commits August 13, 2026 11:23
…#435)

The last round corrected the post_processor rationale in the HEADER and left the
SOURCE saying the opposite thing, twelve lines above the `Encode` call it
annotates. The two made contradictory predictions from the same premise: the
header said a future post_processor makes us WRONG, the source said it keeps us
RIGHT. F7's whole content was "the rationale was inverted", so half of it was
still open.

VERIFIED AGAINST UPSTREAM, not taken on trust. The reviewer could not reach the
anchor; this was read at /home/mudler/_git/LTX-2 pin fd4ded7f:

    packages/ltx-core/src/ltx_core/text_encoders/gemma/tokenizer.py:37-43

        encoded = self.tokenizer(
            text, padding=False, truncation=True,
            max_length=self.max_length, return_tensors="pt",
        )

That is `__call__` with its DEFAULT `add_special_tokens=True`, so upstream DOES
run the post_processor. The HEADER had the direction right; the SOURCE was the
wrong one, and it is the source that is corrected here.

A THIRD claim in the same comment was also false. "Doing both would double the
BOS" is not true: upstream's own guard at :45 (`not input_ids or input_ids[0] !=
bos_id`), mirrored at ltx2_text_encoder.cpp:712, absorbs a leading BOS from
either call. The real exposure is a post_processor that adds anything ELSE, and
the comment now says that instead.

SIBLING SWEEP, built from the SUBJECT (post_processor, BOS, add_special_tokens,
Encode) rather than from the sentences being fixed, since a grep built from the
new text only confirms itself. Two more hits, both corrected:

  * gen-ltx2-prompt-tokens-goldens.py:86 annotated its
    `add_special_tokens=False` as transcribing ":38-43" -- the same conflation,
    in the generator that produces the committed goldens. Anchor corrected to
    :37-43 and the deliberate flag flip is now stated.
  * ltx2_text_encoder.h:421 called the BOS prepend "unconditional", which
    contradicts test_ltx2_text_encoder.cpp:2398 ("i.e. conditional") and :45
    itself. It is conditional, and the guard is why.

────────────────────────────────────────────────────────────────────────────────
TWO COMMENT OVERCLAIMS, PROVED BY THE REVIEWER'S MUTATION

Replacing `Ltx2ComputeRightPadOrder`'s stable partition with the identity
permutation reds two OTHER cases (22 assertions) and leaves the new conditioning
case entirely green. `out.conditioning` and `want_f32` both reach `sort_index`
and `additive_mask` through the SAME function over the SAME `out.mask`, so a
defect there cancels and those ~40 assertions cannot fire. "Held EXACTLY" was
an assertion true by construction wearing a gate's label.

This is NOT a coverage hole and no test changes. Both are genuinely gated by
"ltx2 text: additive mask, right-pad ordering and the binary mask" and "ltx2
text: the encoder -> conditioning hand-off", which compare against committed
upstream goldens rather than against a second call of the code under test. The
comment now says what its assertions do establish (the mask is threaded through
unaltered, and the mask itself is held to the golden) and names the two cases
that actually gate the ordering.

────────────────────────────────────────────────────────────────────────────────
TWO COVERAGE LIMITS RECORDED, NOT FIXED

  * The loader case's "the q|k|v concat ORDER" claim holds for the LTX path
    ONLY. `Ltx2LoadGemmaTowerFromSafetensors` uses its own `TowerConcat`
    (ltx2_text_encoder.cpp:943-945); `gemma4_weights.cpp:281-295` is a SEPARATE
    implementation this suite never loads, and mutating it leaves every case
    here green. That path owes its own gate.
  * The rope-table instrument covers the FULL-ATTENTION arm only. The sliding
    layers' `default` rope at theta 1e4 has no equivalent f32 instrument and is
    reached only through the hidden states, where the same bf16 noise-floor
    argument works against resolving a config-carried angle defect.

────────────────────────────────────────────────────────────────────────────────
DOCS

Comment-only in src/include/tests, so AGENTS.md owes nothing here -- but
check-doc-checkpoint is path-derived and demands FEATURES.md (from
src/vllm/model_executor/models/) and USAGE.md (from include/vllm/). The prior
repair at 9fbc682 paid it the same way. Both edits are GENUINE rather than
gate-appeasement: they record the tokenization divergence this commit just
verified, which is a real user-facing caveat -- our prompt tokenization mirrors
upstream only while the checkpoint's post_processor stays empty. USAGE.md:454
and :473 are left alone; they are inherited from the base branch and belong to
PR #600's lane.

The FEATURES.md note is folded into an existing paragraph rather than added as a
new one, because check-public-doc-tables budgets prose paragraphs (21) as well
as table cells (220 chars) and rows (600), and the LTX row's cell is already at
217.

CODE IS BYTE-IDENTICAL. The only non-comment line in the diff is a trailing
comment on an unchanged statement.

GATE, CPU, Release, VLLM_CPP_CUDA=OFF:
  BUILD_EXIT=0, no "No space left" / "BFD assertion", df 86% used
  test_ltx2_text_encoder: 26 cases / 4115 assertions, Status SUCCESS, exit 0
    (matches the declared baseline exactly)
  ctest -N: 414 (the brief said 409; this configure enumerates 414 at the
    unmodified head, and a comment-only diff cannot register a test)
  ctest: 414/414 passed, 0 failed, exit 0, first pass under -j 8, no flaky
    re-runs needed
  binary md5 unchanged across the post-docs rebuild (8b48f39b...)

check-doc-checkpoint "range" still reports b0aa475, d67f812 and aa6aa0e.
All three are ancestors of 9fbc682, inherited, and not repairable from here
without editing #600's lane.

Issue: #435, #604

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
Reviewed PASS at 4e5d4a2 after two FAIL rounds, both on the record surface
rather than the code. The final review read 571 hits from subject-built patterns
and cross-checked every vllm_* symbol in the public docs against include/vllm.h
and every repo path cited in USAGE.md, with no real misses.

What lands: the chain from a prompt string through tokenizer, Gemma-4 tower,
caption projections and the connector to Ltx2ModalityInput::context, closed with
no gap; the last_conditioning() trace with its race fixed and gated in both
directions; and the honest bound on all of it.

The bound is the part worth reading. last_conditioning() is a WITNESS, not a
gate: scaling the conditioning x1.5 or REVERSING its rows still passes every
assertion, so it detects change rather than correctness, and the two joins have
no numeric oracle. That is recorded at the code, in the append-only record, and
in the public docs, which now say a change detector is not a quality measure.

Three conflicts. docs/USAGE.md's first was two DIFFERENT sections git aligned
badly -- the pipeline-goldens regeneration note and the Gemma-4 tower gate --
so both are kept. Its second took L13's text, because the campaign side still
said "there is still no render path", which stopped being true; but L13's "an
NVFP4 DiT" became "both NVFP4 DiTs", since L9a landed first-party NVFP4 after
L13 branched.

docs/FEATURES.md is the same keyed row for the SIXTH time (#595), and again
neither side was a superset: the campaign knew both VAE encoders and all three
NVFP4 arms loading, L13 knew the prompt path and that the 320x192/25f scene was
REGISTER-conditioned with a prompted render still owed. L13's "first-party NVFP4
does not load" was stale on arrival. Composed to what is true of the merged tree.

Issue: #435, #604

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
Merging L13 produced a tree that did not compile:

  ltx2_text_encoder.cpp:796: error: 'Ltx2DequantTorchaoNvfp4ToBf16' was not
  declared in this scope; did you mean 'Ltx2DequantNvfp4ToBf16'?

L9A renamed that seam and gave it a mandatory `producer` argument. L10/L13
branched before it and still called the old name. Different files, so the
textual merge was clean and `git merge-tree` reported no conflict -- which is
exactly why merge-tree returning clean is not evidence that the result builds.

The seam then behaved as designed. `producer` is deliberately NOT defaulted
(ltx2_loader.h:323-325): a default would let a caller who never thought about
the question silently get the torchao reading for an nvfp4-prequant file, which
is the failure that seam exists to refuse. This call site had already run
ParseLtx2TorchaoNvfp4Marker one line above, so it can state kTorchao as
established rather than assumed, and the comment now says so.

Two things about the failure itself. The build error was the ONLY signal: the
run reported "100% tests passed, 0 tests failed out of 408" against a registered
count of 415, because ctest correctly did not run and the harness grepped a
stale log from an earlier run. A tally that disagrees with `ctest -N` is not a
pass, it is a stale artifact -- the harness now deletes the log first and prints
"BUILD FAILED - ctest NOT run, no tally to report" rather than a number.

Re-gated clean: BUILD_EXIT=0, zero warnings, enospc 0, ctest 415/415 exit 0,
registered 415 -- tally and registration agreeing, which is the check the
mismatch above was trying to make.

Issue: #435

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
, #604)

The re-review found `test_ltx2_text_encoder.cpp:635` citing
`ltx2_text_encoder.cpp:943-945` for "the LTX tower loader's own `TowerConcat`".
Lines 943-945 are the `q_proj` `TowerModule` load. The concat calls are :951 and
:953; the helper is defined at :835. The substantive claim was measured and is
true, and only the number was wrong -- which is the worst shape for this defect,
because a reader who follows the anchor concludes a TRUE claim is unsupported.

Fixing one number and stopping is what let the class survive three review
rounds, so every `file:line` this branch ADDS over `row/MODEL-DIFFUSION-LTX25`
was resolved against the tree it points into. Extracted mechanically by SHAPE
off the added lines of `git diff origin/row/MODEL-DIFFUSION-LTX25...HEAD`
(`name.ext:NN`, `name.ext:NN-MM`, bare `:NN` / `:NN-MM`, "line(s) NN", "SS N"),
not by grepping the sentences already known to be wrong -- a grep built from
text you just fixed only confirms itself.

19 citations added, in 6 files. 19 resolved. 8 wrong, at 6 comment sites.

  site                                    cited                     is
  ------------------------------------------------------------------------
  test_ltx2_text_encoder.cpp:635          ltx2_te.cpp:943-945       q_proj load
  test_ltx2_text_encoder.cpp:1959         rope_utils.py:187-245     ends at 254
  test_ltx2_text_encoder.cpp:1992         rope_utils.py:233         blank line
  gemma4.h:260                            gemma4_unified.py:257-274 prev fn tail
  gemma4.h:260                            rope_utils.py:187-245     ends at 254
  gen-ltx2-gemma-tower-goldens.py:378     gemma4_unified.py:214-218 call, no
                                                                    lookup
  gen-ltx2-gemma-tower-goldens.py:378     rope_utils.py:187-245     ends at 254
  ltx2_text_encoder.cpp:1055              gemma4.cpp:300-312        cuts the cast

The three `modeling_rope_utils.py:187-245` sites are one anchor repeated. The
function is `_compute_proportional_rope_parameters`, :187-254, and all three
sentences name its ZERO PADDING -- which is `torch.zeros(nope_angles, ...)` at
:246, ONE LINE past the cited end. Following the anchor is following it to the
`torch.cat(` that opens two lines earlier and stopping before the argument that
matters. Corrected to :187-254, with :246 named where the padding is the claim.

`modeling_rope_utils.py:233` is a blank line. `rope_angles = int(rope_proportion
* head_dim // 2)`, which the comment quotes, is :234.

`modeling_gemma4_unified.py:257-274` opens on the PREVIOUS function's `return`
(:257) and stops before `forward`'s own (:275). The `emb = torch.cat((freqs,
freqs), dim=-1)` the sentence mirrors is :271, so the anchor does contain it,
but both ends land in the wrong construct. Corrected to the whole method,
:259-275, with :271 named.

`modeling_gemma4_unified.py:214-218` is the CALL, `rope_init_fn(self.config,
**rope_init_fn_kwargs)`. The sentence claims the class "routes `rope_type:
proportional` to `_compute_proportional_rope_parameters`", and the routing is
`ROPE_INIT_FUNCTIONS[rope_type]` at :207, outside the range -- a reader at
:214-218 cannot see what `rope_init_fn` resolves to, so the claim reads
unsupported. Widened to :206-218.

`gemma4.cpp:300-312` opens on the weight-less V `RmsNorm` at :300 and closes on
the `} else {` at :312, which EXCLUDES the `vt::CastF32` pair at :313-314 that
the sentence is about ("run a CastF32 on every K and V it wrote"). The
`kv.dtype != adt` arm is :306-315. Corrected, with the two `DBuf`s and the casts
named separately, because those are the two costs the sentence charges.

The eleven that resolve as written, checked one by one, not assumed: LTX-2
`tokenizer.py:37-43` (three sites, the `self.tokenizer(...)` call), `:44-46`,
`:45`, `:12-15`, `gemma_assets.py:335-386`
(`build_text_encoder_tensors_from_gemma_root`, :335 to its `return` at :386),
`base_encoder.py:41`; diffusers `pipeline_ltx2.py:339` (literally
`add_special_tokens=True`); ours `gemma4_weights.cpp:281-295`, which does span
all three qkv arms as the previous round reported. Two non-line anchors added by
the F7 commit -- the two test-case NAMES it cites as the ones that gate the
ordering -- exist verbatim at :1115 and :1166.

PINS. LTX-2 at `fd4ded7f`, tree clean. diffusers at `3a2f35d4`. transformers
5.12.1 at `/home/mudler/recon-cpu/venv`, the interpreter the tower generator
actually ran under; both files are md5-IDENTICAL to `/home/mudler/_git/
transformers` @ `7d06b1a5`, so the numbering above is not an artifact of which
install was read.

F10's anchor. `:951-953` and not `:835`, because the sentence is the LTX half of
a contrast whose other half is `gemma4_weights.cpp:281-295` -- assembly SITES,
not a helper definition -- and because the qkv concat ORDER is what the case
gates and what the previous round's mutation (`q,k,v` -> `q,v,k`, 14 assertions
RED) perturbed at :951. `:835` is named alongside it so the helper is still one
hop away.

DOCS. The code is byte-identical; this is comments and two documents.
`check-doc-checkpoint` is path-derived and demands `FEATURES.md` (from
`src/vllm/model_executor/models/`) and `USAGE.md` (from `include/vllm/`), which
is the same bill `9fbc68256` and `ddfcb516a` paid. Both edits are genuine.

`USAGE.md` still opened its LTX-2.5 gate section with "**There is no LTX-2.5
render path yet** ... no text encoder, no VAE, no pipeline and no `/v1/videos`
route for it -- asking the video engine for LTX-2.5 will not work." Every clause
is false, and the SAME DOCUMENT contradicts all of them: `ltx2-gen` renders end
to end at :412, `--video-family ltx-2.5` pins the family on the server at :435,
and the text tower is this row. Rewritten to say what the section is for. The
refusal list that follows is left byte-for-byte alone: it is inherited text, it
is not part of this finding, and `ltx2.h:38` and `:47-49` do support the two
clauses of it I checked.

`FEATURES.md` pointed at "`ltx2_text_encoder.cpp` names the line that would have
to change" -- an unresolvable pointer, in a commit about unresolvable pointers.
It now names `Ltx2TokenizeGemmaPrompt`. A symbol, deliberately, because a line
number in a public document has nothing that can keep it true. Folded into the
existing paragraph: the 700-char prose cap and the 220-char cell cap make an
addition an EVICTION of someone else's content, and the LTX row's two cells are
already at 217 and 215.

`docs/USAGE.md:454` and `:473` untouched -- #600's lane.

GATE -- CPU, Release, `VLLM_CPP_CUDA=OFF`, `build-f10`, deleted after.

  cmake --build build-f10 -j 16     BUILD_EXIT=0; 0 hits for
                                    'No space left|BFD assertion'; df 85%
  ctest -N                          414
  ctest -j 8 --output-on-failure    414/414 passed, 0 failed, exit 0
  ./build-f10/tests/test_ltx2_text_encoder
                                    26 cases | 4115 assertions | 0 failed
                                    Status: SUCCESS, exit 0
                                    (baseline 26 / 4115 matched exactly)

First pass under `-j 8`; no suite needed a serial re-run. `doc-checkpoint
--staged` and `now-current --staged` both ok. `doc-checkpoint range` still
reports `b0aa475a3`, `d67f8125e` and `aa6aa0ecd` -- the identical three failures
this worktree recorded BEFORE any edit, all ancestors of `9fbc68256`, inherited
and not repairable from here.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
…swept out

Reviewed PASS at 131328e after three FAIL rounds. The last one is the reason
to read this: told to fix ONE wrong file:line, the implementer swept every
citation the branch adds -- 19 of them -- and found EIGHT wrong at six sites.
Fixing the instance would have left seven.

Three of the eight are one anchor repeated. modeling_rope_utils.py:187-245 was
cited three times as the authority for that function's ZERO PADDING, which is at
:246 -- one line past the cited end, so the range stops inside the torch.cat(
argument list immediately before the argument that IS the whole claim. Our own
gemma4.cpp:300-312 has the identical shape: it closes on `} else {`, leaving the
vt::CastF32 pair at :313-314 that the sentence charges outside the range. A range
that stops just short of its own subject is worse than a missing citation,
because it looks checked.

The reviewer then re-extracted the citations independently and confirmed the
sweep missed none, resolved all eight corrections itself at the pins, verified
the transformers files are md5-identical between the venv and the clone so the
numbering is not install-specific, and proved code identity by comment-stripping
and hashing rather than by eye.

Three conflicts, none of them a union.

docs/USAGE.md's first: the base says "A typed prompt works" because L13 landed
it; L10 still opened "There is no prompt", stale on arrival. Took the base's
framing but KEPT L10's tokenization-divergence paragraph, which is unique to it
and still true -- upstream tokenizes through __call__ with add_special_tokens
defaulting True and so runs the post_processor, while this port calls plain
encode and prepends BOS; identical only because the shipped post_processor's
special-token map is EMPTY, measured on the file rather than assumed.

Its second and docs/FEATURES.md both took the base wholesale: the base's parity
paragraph is a strict superset carrying anchors, the ltx2.h refusal list and a
provenance note, and L10's row still said first-party NVFP4 does not load (L9A
landed it) and described an encoder_path refusal L13 lifted.

Issue: #435, #604

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
mudler and others added 2 commits August 13, 2026 12:18
Second and last absorption of main (the first was 192 commits at 5b598fc).
Eleven commits, one conflict, and it is the same append-only log as last time:
.agents/benchmark-record.md, where both sides appended distinct sections at the
same anchor. Unioned with main's first and both verified present by content
rather than by the merge exiting zero.

Nothing else collided. Notably the Nemotron rows, the DSA top-k gating and the
Windows Invoke-Checked fix all landed on main during this campaign without
touching an LTX file.

Issue: #435

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
Eight more commits landed on main while the dgx gate ran. None touches an LTX
path: the closest is bd3b755's GDN output_gate_type, which changes qwen3_5.cpp
and hf_config, not vt/cuda, not device_pool, not ltx2_*. So the CUDA verification
taken at 105e785 still covers this work, and the eight were gated by their own
PRs. That is the same pinned-base-plus-invalidation-condition reasoning the pool
row used, applied honestly rather than re-run for its own sake.

Five conflicts, all append-collisions between two branches doing unrelated work:

  docs/USAGE.md          the LTX-2.5 section vs a new GDN output_gate_type
                         section -- different subjects, both kept
  server_main.cpp        my --video-family registry check vs main's
                         --enable-auto-tool-choice check -- two independent
                         validations, both kept
  model-matrix.md        six new recipe-architecture rows vs the LTX-2.5 row,
                         no key collision, unioned
  check-agent-record.py  both provenance comments kept; the union left TWO
                         "MODEL" pin entries, collapsed to one
  test_agent_record.py   both narratives kept

The architecture-count pin is the interesting one. Both branches bumped the SAME
number from the same base -- mine 362->363 for LTX-2.5, main 362->369 for seven
recipe rows -- so neither value is right after a merge and the arithmetic is not
the check. I set a hypothesis and let `check-agent-record.py` be the authority on
it: it reports MODEL=370, which is 362 + 7 + 1. My own grep of the table said
366, which is what happens when you count rows with a pattern that is not the one
the checker counts with.

Issue: #435

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants