Skip to content

feat(LTX25-DFR-PIPELINE): the DFR canvas, the slots it invents, and the loop that still does not run (#986) - #996

Merged
localai-bot merged 11 commits into
mainfrom
row/LTX25-DFR-PIPELINE
Aug 16, 2026
Merged

feat(LTX25-DFR-PIPELINE): the DFR canvas, the slots it invents, and the loop that still does not run (#986)#996
localai-bot merged 11 commits into
mainfrom
row/LTX25-DFR-PIPELINE

Conversation

@localai-bot

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

Copy link
Copy Markdown
Collaborator

DFRPipeline's BASE is ported and reachable: --pipeline-kind dfr resolves upstream's padded keyframe canvas, places generated keyframe slots on its segment grid, marks them, reads them back before the trim, and trims the canvas to the frame count the caller asked for. Generated keyframe slots are SERVED on every pipeline, which retires the refusal #920 landed.

The temporal refinement ROUNDS are not ported and are refused by name, so the temporal x2 upsampler is still UNDRIVEN and docs/FEATURES.md still says so. That is the row's headline result and it is stated first, because the row was dispatched expecting the opposite.

Closes nothing. Issue #986 stays open for the rounds loop and the standalone slot decode, both listed under ## Owed. Campaign #644. Spec .agents/specs/ltx25-dfr-pipeline.md. Pin Lightricks/LTX-2 @ fd4ded7f2d88d3da713abcdd4ad41ecc4a9314ca, verified at the local checkout with git rev-parse HEAD before any anchor was read.

What landed

ltx2_dfr.{h,cpp} is dfr_layout.py in full plus the three dfr_pipeline.py helpers that are pure index arithmetic. It is its own translation unit because every one of its failure modes returns a correctly shaped, finite, plausible latent: there is no NaN, no shape disagreement and no magnitude to bound, so the only instrument that can see a defect is an exact index vector. test_ltx2_dfr compares element by element against values the upstream module RETURNED, not against a reading of its source.

ltx2_conditioning gains Ltx2ConditionVideoByGeneratedKeyframeSlots, Ltx2GeneratedKeyframeLayout and Ltx2ExtractGeneratedKeyframes, with Ltx2ClearConditioning extracting BEFORE it trims. Four things there invert or disable something every other appending item does, and each is annotated at its site: the content goes into latent and not clean, the denoise mask is 1 and not 1 - strength, marked is TRUE (upstream's only such call site), and the temporal span is one pixel frame written by hand.

ltx2_video.cpp gains the dfr pipeline kind, the canvas resolution, the per-phase slot conditioning, the slot carry between stages through the spatial upsampler, the trim back to the caller's contract, and the cut of the soundtrack to the picture.

Reach, traced rather than assumed. pipeline_kind is a LOAD knob, so all three surfaces carry it: ltx2-gen --pipeline-kind dfr, the C ABI's vllm_video_model_params.extra_keys / extra_values, and the server's --video-extra pipeline_kind=dfr at launch (server_main.cpp:492-503 parses it, :1317-1325 copies it into vmp.extras). A server started that way renders every /v1/videos request through DFR. This PR originally claimed CLI and ABI only, on the grounds that /v1/videos forwards no engine extras (#928) — true of the per-GENERATION extras num_generated_keyframes and temporal_upsample_rounds, and false of pipeline_kind. Corrected in docs/USAGE.md and here.

The oracle, and why it is not an import

scripts/gen-ltx2-dfr-goldens.py imports and EXECUTES dfr_layout. It does not import dfr_pipeline, because that pulls iclora_utils to utils.media_io to ltx_core.color.hlg, which imports PyAV — a codec binding this project deliberately does not vendor, and the same dependency the image_crf round trip is refused over. So the three helpers and three constants are lifted by AST from the real file and their OWN SOURCE TEXT is executed. Each name is asserted present, so an upstream rename raises rather than letting the generator quietly substitute a local definition for the thing under test. The generator also refuses a dirty checkout, so the recorded SHA always describes the code that ran.

The tripwire that fired, on purpose

The #920 refusal declared ABSENT HERE: GeneratedKeyframe, generated_keyframe, and test_ltx2_video re-derived those names from ltx2_conditioning.h. Section 4a of that spec predicted this exact event in terms:

If the readback lands, GeneratedKeyframe appears in the header, ABSENT goes red, and whoever landed it is told the refusal is now false.

It went red. The assertions are retired with the refusal they described and replaced by assertions about what replaced it, never widened. AGENTS.md forbids making a red gate green by deleting an assertion; this is the other case, where the subject of the assertion no longer exists.

Two upstream comments that overstate themselves

Both were found by mutations that stayed GREEN, and in both cases the green is a fact about the code rather than a hole in a test. Recorded because a later reader who removes either construct would otherwise have no way to tell.

  • dfr_layout.py:177 gives the first tile no lead-in, which reads as load-bearing and is redundant with the max(0, own_lo - lead) clamp beside it. Measured against executed upstream: _build_tile on tile 0 with lead 0, 1 and 5 returns three TileRanges that compare EQUAL. ltx2_dfr.h carried the opposite claim until the mutation refuted it, and now carries the correction with a gate on it.
  • keyframe_slots.py:161-163 says the causal fix "must not also be applied" because the span is set explicitly. Measured the same way: computing with causal_fix=True and then applying the explicit span gives a BYTE-IDENTICAL tensor, because the fix touches only the temporal axis and the span overwrites it in full.

Both are mirrored anyway, to follow upstream's text rather than its algebra.

Reachability

R1 deletes the production Ltx2DfrResolveCanvas call site and R2 deletes the production slot-conditioning call site. Both take test_ltx2_video RED, exit 1, having BUILT with zero compile errors and a CHANGED binary hash. A green there would have meant the DFR path is a test-only driver.

Two mutations stayed green against the engine suite, and the first explanation for one of them was wrong. Both are reported with what was measured, because a green mutation with a confident story attached is worse than one with none.

M8 needs an appending item AFTER the slot item, and upstream has exactly one: VideoConditionByReferenceLatent (dfr_pipeline.py:366-373), whose arm #975 owes. Until that lands the slots always trail and both readings agree. Gated in test_ltx2_dfr, which builds that configuration by hand and where M8 goes RED.

M5 was first explained as "a no-op on phase 0, which is the only phase the engine's DFR case runs" — an explanation that predicts a two-phase engine case would turn it RED. A two-phase case was then written, using the fixture spatial upsampler, rendering at full resolution and asserting stage 2 places and reads back its own slots at 4 tokens each against stage 1's 1. M5 stayed GREEN with it present, 52/52, exit 0. So the explanation was wrong.

The real reason is a property of the pipeline: stage 2 re-noises to stage_2_sigmas[0], about 0.909, so the seed is almost entirely replaced by noise before the first step and the loop generates the rest. The assertions an engine test can make about a slot are structural — counts, positions, resolutions — and the seed moves none of them; there is no A/B either, because the seed is internal rather than a request field. The two-phase case is kept for what it does establish, and its comment now says exactly that: it REACHES the seeded path, which no other engine test does, and it does not DETECT the seed. M5 stays gated in test_ltx2_dfr on the property that belongs to the port — the seed lands in latent and not in clean — where it goes RED.

Mutations

Every one carries three facts: git diff --stat after applying, whether it BUILT with the compile-error count beside it, and the exit code. Binary hashes were recorded before and after each rebuild, so no result is a stale binary reporting the previous run. The tree restored byte-identical and the binary returned to its baseline hash.

# mutation suite result errors exit
M1 choose_segment_length tie takes the SMALLER candidate test_ltx2_dfr RED 0 1
M2 _build_tile keeps boundary 0 as an anchor test_ltx2_dfr RED 0 1
M3 drop_latent_prefix omits the seam handover +1 test_ltx2_dfr RED, 18 failed 0 1
M4 NEGATIVE CONTROL: the first tile is given a lead-in test_ltx2_dfr GREEN (a no-op by algebra, proven upstream) 0 0
M4b the lead-in is dropped from EVERY tile test_ltx2_dfr RED 0 1
M5 the slot seed never reaches latent test_ltx2_dfr RED 0 1
M5b the slot seed ALSO goes into clean test_ltx2_dfr RED 0 1
M6 the slot append passes marked=false test_ltx2_dfr RED 0 1
M7 NEGATIVE CONTROL: the slot span applies the causal fix test_ltx2_dfr GREEN (byte-identical upstream) 0 0
M7b the slot span is a full latent frame, not one pixel frame test_ltx2_dfr RED 0 1
M8 the extraction ASSUMES the slots trail test_ltx2_dfr RED 0 1
M8b the layout records the wrong first_token test_ltx2_dfr RED 0 1
M11 the slot seed rounds half-away-from-zero, not half-to-even test_ltx2_dfr RED 0 1
M12 the carry-forward merge lets the ANCHOR win a shared position test_ltx2_dfr RED 0 1
M13 CONTROL: a no-op edit test_ltx2_dfr GREEN 0 0
R1 the production Ltx2DfrResolveCanvas call site is deleted test_ltx2_video RED 0 1
R2 the production slot-conditioning call site is deleted test_ltx2_video RED 0 1
M9 the slots are extracted AFTER the trim test_ltx2_video RED 0 1
M10 the DFR trim is dropped test_ltx2_video did NOT BUILD, 1 compile error — establishes nothing 1 n/a
M14 the canvas is resolved BEFORE assert_resolution (upstream's order reversed) test_ltx2_video RED 0 1
M15 the DFR audio cut is disabled test_ltx2_video RED, picture 0.375s, sound 1.01s, 2 channels at 48000 Hz 0 1

Gate

CPU only. The GPU was not used: a render ladder holds dgx.casa.

cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DVLLM_CPP_CUDA=OFF
cmake --build build -j6
ctest --test-dir build -j4 --output-on-failure

Re-run on the MERGED tree at head ad3a5e021; the last commit is documentation only. The final run is CTEST_EXIT=0, 491/491 passed, 167.17 s. origin/main moved three times during this row (0e1bee42f to 3005447f8 to e770a392f to 4496ef196) and each merge was followed by a full re-run, because a clean merge is not a building merge.

  • CONFIGURE_EXIT=0, BUILD_EXIT=0
  • ': error:' 0, ': warning:' 0, No space left 0, BFD assertion 0, against 487 Linking lines as the positive control that those greps ran over real content
  • ctest -N = 491
  • All 11 LTX-2.5 suites pass in every run, including the two this PR adds to: test_ltx2_dfr (11 cases / 652 assertions) and test_ltx2_video (52 cases / 1279 assertions)
  • Skipped by their own guards: test_modelopt_mixed_precision_checkpoint, test_voxtral_e2e. Nothing else skipped
  • 69-70 GB free disk throughout

The parallel runs were not all clean, and the reds are shown rather than dropped. One run returned CTEST_EXIT=0, 491/491 passed, at load average 6.93. Two others returned CTEST_EXIT=8test_engine_core_proc + test_cpu_threadpool in one, test_engine_core_proc + test_async_llm in the other, the latter at load average 58.55 on a box another session was hammering. Every one of those four passed when re-run ALONE, exit 0 each. All are on the standing load-dependent list (#294 and the threadpool ratio guard), and none is in this diff: git diff --name-only origin/main...HEAD | grep -iE 'threadpool|engine_core_proc|async_llm' is empty against 18 changed files as the control.

docs/FEATURES.md is a keyed record and both sides edited it. The automatic three-way merge is not accepted on its own word. AGENTS.md asks for the target version plus the scoped edit reapplied with unrelated keys proven byte-for-byte equal, and that was checked: 189 unrelated keys compare byte-for-byte equal, the new DFR row is present and is not a duplicate of anything on the target, and the LTX-2.5 DiT row differs from the target by exactly the six characters this row owns. The verifier carries its own floor — a comparison of fewer than 50 keys fails, because a parser that matched almost nothing would otherwise report a pass over an empty set.

  • check-doc-checkpoint run per commit (#573): all seven commits exit 0. The instrument is ARMED, not merely quiet: --commit b5618b305 exits 1 with its known message, captured directly rather than through a pipe — which mattered, because the piped form reported exit 0 for a checker that had plainly just printed ERROR
  • check-commit-style exit 0, check-commit-trailers exit 0, check-public-doc-tables exit 0, check-agent-record exit 0

One pre-existing red, filed rather than absorbed. scripts/agent-preflight.sh fails check-env-doc and test_check_env_doc on this branch and on every branch cut from 3005447f8: three VT_MOE_EXPERT_STREAM* knobs landed undocumented with #993. Proved pre-existing with a matched-arm check rather than asserted — the three sites are in qwen3_5.cpp, which this branch does not touch, and git diff origin/main...HEAD | grep '^+.*VT_MOE_EXPERT' returns nothing. Filed as #995, owner ENG-EXPERT-STREAM, with an index row in this branch.

Two defects this PR shipped and then found in itself

Both were found after the first push, by re-deriving this row's own upstream anchors at the final tree rather than trusting the ones written during implementation. All 44 citations resolve into their cited spans, 0 STALE — and twice the anchor was right while the CODE was not. The needle for each was written from the CLAIM the anchor is cited for rather than copied out of the span, because that check is circular and has reported 27/27 FRESH here while five anchors pointed at unrelated code.

The refusal order was reversed. The DFR canvas was resolved before Ltx2AssertResolution, where upstream calls assert_resolution at dfr_pipeline.py:291 and resolve_canvas at :314. A caller wrong on both the resolution and the frame count heard the wrong one of two correct refusals. Invisible to everything else, because on that input neither port renders anything. Gated by M14.

The soundtrack was not cut to the picture. dfr_pipeline.py:552-560 cuts decoded audio to num_frames / playback_fps, and upstream states the consequence rather than the mechanism: "Audio was generated for the padded canvas, so cut it to the video's duration or the muxed container outlasts the picture." The canvas pads 9 frames to 25; ashape.frames is derived from the PADDED count inside the phase loop, audio_lf carries it out, and the vocoder runs over all of it, so trimming the video latent touches none of it. A 9-frame DFR request emitted 0.375 s of picture beside 1.01 s of sound. Gated by M15.

The second is the more useful record, and the worse half is not the missing line. This PR shipped a comment saying the cut was "already implied by the trimmed frames", so a reader who went to check :552-560 would have found it accounted for and stopped. That comment is deleted and replaced by one that says what was wrong with it.

The first draft of the audio gate was itself wrong, in a way that reads as caution: it assumed one channel, calling that "the loosest reading and therefore the safe direction". It is the opposite — dividing by too few channels reports a LONGER file than exists, so the bound false-fails on a correct cut, which is exactly what it did. It now reads the channel count, sample rate and bit depth out of the WAV header rather than trusting the engine's own report of what it wrote.

What is owed, and why it is not here

The rounds loop needs the per-tile denoise pass as a callable. Upstream's rounds invoke the same DiffusionStage.__call__ the two stages use, per tile, with their own sigmas, stepper and seed (dfr_pipeline.py:480-499); this engine's denoise is inline inside one 680-line per-phase loop with no seam a tile can enter through. That is a refactor of the render path rather than an addition to it, so it is refused by name and listed under ## Owed against #986 rather than half-built. The refusal names the loop, names three ruled-out causes with what ruled each one out, and is gated by a case that re-derives its LOCAL claims from ltx2_dfr.h — because a refusal asserting only upstream symbol names cannot detect its own staleness, which this campaign has already paid for.

ltx-2.5-latent-temporal-upscaler-x2-bf16-1.0.safetensors is also still absent from the NAS, re-verified 2026-08-16 at the start and again at the end of this row, so a complete loop would have no real weights to run either.

Unverified, stated as unverified: nothing here has run on a real LTX-2.5 checkpoint. Every result is at reduced fixture dimensions on CPU, and no real-weight DFR render exists.

Arms

Arm State
bf16 / f32 reference served
FP8 served — the DFR path and the slot request are resolved ahead of arm selection, so no arm reaches the machinery by a different route
NVFP4 served, same reason
GGUF k-quants not applicable. LTX-2.5 ships no GGUF: the four quantization kinds upstream defines are fp8-cast, fp8-scaled-mm, nvfp4-cast and nvfp4-prequant (quantization_factory.py:23-26), and no published LTX-2.5 checkpoint is a GGUF
temporal rounds refused by name, owed by #986
stage-2 detailing IC-LoRA refused by name, owed by #975

FOLLOWING_AGENTS_PROTOCOL

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

mudler added 11 commits August 16, 2026 06:58
…ing drives (#986)

`DFRPipeline` has no representation in this tree, and it is the only upstream
consumer of the temporal x2 latent upsampler this project already ships. That
makes this row the reachability answer for code that landed unreached, not only
a new feature.

Issue: #986. Campaign: #644. Spec:
`.agents/specs/ltx25-dfr-pipeline.md`. Pin `Lightricks/LTX-2 @
fd4ded7f2d88d3da713abcdd4ad41ecc4a9314ca`, verified at the local checkout with
`git rev-parse HEAD` before any anchor was read.

The spec is committed before the implementation, so the commit order proves
which came first.

Three things the spec settles up front, because each of them would otherwise be
discovered mid-review as a claim the row did not support:

The temporal upsampler checkpoint is NOT on the NAS. Re-verified 2026-08-16
rather than inherited from `ltx25-temporal-upsampler.md` section 8.5, whose
measurement is four days old on a shared mount: the directory holds
`ltx-2.5-latent-spatial-upscaler-x2-bf16-1.0.safetensors` and nothing else. So
every temporal claim this row can make is a reduced-dimension fixture claim, and
"driven" is a statement about a code path rather than about a rendered clip.

DFR needs two thirds of what #920 left owed, and the third piece is not a
convenience it skips. The refusal names a standalone single-frame decode as part
of its one blocker, and that is right for a caller who wants slot PIXELS. DFR
never decodes its slots: it hands them to the spatial upsampler
(`dfr_pipeline.py:348`) and feeds them back as `initial_keyframes` (`:364`), and
carries them through the rounds as latents (`:527-529`). So the layout and the
extraction are owed here and the decode stays owed under section 11.

Landing that readback REDs an existing gate on purpose. The #920 refusal
declares `ABSENT HERE: GeneratedKeyframe, generated_keyframe` and
`test_ltx2_video` re-derives those names against `ltx2_conditioning.h`. Section
4a of that spec predicted this exact event in terms. The repair is to retire the
refusal, never to widen the assertion.

The spec also names the record this row contradicts. `ltx25-resolution-envelope.md:436`
records that the `Temporal x2 ups gated, UNDRIVEN` cell is untouched byte for
byte. This row makes that false deliberately, in that row's EVIDENCE rather than
its behaviour, and section 9 says so, so a later reader who greps the sentence
finds the row that moved it instead of concluding the cell drifted.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
…he loop that still does not run (#986)

`DFRPipeline`'s BASE is ported and reachable: `--pipeline-kind dfr` resolves
upstream's padded keyframe canvas, places generated keyframe slots on its segment
grid, marks them, reads them back before the trim, and trims the canvas to the
frame count the caller asked for. Generated keyframe slots are SERVED on every
pipeline, which retires the refusal #920 landed.

The temporal refinement ROUNDS are not ported and are refused by name, so the
temporal x2 upsampler is still UNDRIVEN and `docs/FEATURES.md` still says so.
That is the row's headline result and it is stated first because the row was
dispatched expecting the opposite.

Issue #986. Campaign #644. Spec `.agents/specs/ltx25-dfr-pipeline.md`. Pin
`Lightricks/LTX-2 @ fd4ded7f2d88d3da713abcdd4ad41ecc4a9314ca`, verified at the
local checkout before any anchor was read.

## What landed

`ltx2_dfr.{h,cpp}` is `dfr_layout.py` in full plus the three `dfr_pipeline.py`
helpers that are pure index arithmetic. It is its own translation unit because
every one of its failure modes returns a correctly shaped, finite, plausible
latent: there is no NaN, no shape disagreement and no magnitude to bound, so the
only instrument that can see a defect is an exact index vector. `test_ltx2_dfr`
compares element by element against values the upstream module RETURNED, not
against a reading of its source.

`ltx2_conditioning` gains the generated keyframe slot item, its layout and the
extraction. Four things there invert or disable something every other appending
item does, and each is annotated at its site: the content goes into `latent` and
not `clean`, the denoise mask is 1 and not `1 - strength`, `marked` is TRUE, and
the temporal span is one pixel frame written by hand.

## The tripwire that fired, on purpose

The #920 refusal declared `ABSENT HERE: GeneratedKeyframe, generated_keyframe`
and `test_ltx2_video` re-derived those names from `ltx2_conditioning.h`. Section
4a of that spec predicted this exact event in terms: "If the readback lands,
`GeneratedKeyframe` appears in the header, ABSENT goes red, and whoever landed it
is told the refusal is now false." It went red. The assertions are retired WITH
the refusal they described and replaced by assertions about what replaced it, not
widened.

## Two upstream comments that overstate themselves

Both were found by mutations that stayed GREEN, and in both cases the green is a
fact about the code rather than a hole in a test. Recorded because a later reader
who removes either construct would otherwise have no way to tell.

`dfr_layout.py:177` gives the first tile no lead-in, which reads as load-bearing
and is redundant with the `max(0, own_lo - lead)` clamp beside it. Measured
against executed upstream: `_build_tile` on tile 0 with lead 0, 1 and 5 returns
three `TileRange`s that compare EQUAL. `ltx2_dfr.h` carried the opposite claim
until the mutation refuted it, and now carries the correction with a gate on it.

`keyframe_slots.py:161-163` says the causal fix "must not also be applied"
because the span is set explicitly. Measured the same way: computing with
`causal_fix=True` and then applying the explicit span gives a BYTE-IDENTICAL
tensor, because the fix touches only the temporal axis and the span overwrites
it in full.

Both are mirrored anyway, to follow upstream's text rather than its algebra.

## Reachability

R1 deletes the production `Ltx2DfrResolveCanvas` call site and R2 deletes the
production slot-conditioning call site. Both take `test_ltx2_video` RED, exit 1,
having BUILT with zero compile errors and a CHANGED binary hash. A green there
would have meant the DFR path is a test-only driver.

Two mutations stayed green against the engine suite and were re-run against one
that can see them. The slot SEED is a no-op on phase 0, the only phase the engine
case runs; the layout and the trailing-token assumption agree until an appending
item lands after the slot item, and upstream's only one is the reference latent
that #975 owes. Neither is a coverage hole; both are statements about what this
port can reach, and both are gated in `test_ltx2_dfr` with that reasoning beside
them.

## What is owed, and by whom

The rounds loop needs the per-tile denoise pass as a callable. Upstream's rounds
invoke the same `DiffusionStage.__call__` the two stages use, per tile, with
their own sigmas, stepper and seed; this engine's denoise is inline inside one
680-line per-phase loop with no seam a tile can enter through. That is a refactor
of the render path rather than an addition to it, so it is refused by name and
listed under `## Owed` against #986 rather than half-built.

`ltx-2.5-latent-temporal-upscaler-x2-bf16-1.0.safetensors` is also still absent
from the NAS, re-verified 2026-08-16 at the start and the end of this row, so a
complete loop would have no real weights to run either.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
`origin/main` advanced from `0e1bee42f` to `3005447f8` while this row was in
implementation, over two ENG-EXPERT-STREAM commits (#985, #993).

The merge is clean and it does not overlap this row's subject. Of the ten files
those commits touch, the only one this branch also edits is
`tests/CMakeLists.txt`, and the two additions are in different places: theirs
registers `test_host_expert_slot_store`, this one registers `test_ltx2_dfr`.
Nothing under `src/vllm/multimodal/`, `src/vllm/model_executor/models/ltx2_*`,
`include/vllm/model_executor/models/ltx2_*` or `docs/FEATURES.md` is common to
both.

A clean merge is not a building merge, so the full gate is re-run on the merged
tree rather than inherited from the pre-merge run.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
…very branch (#986)

Found while gating row `LTX25-DFR-PIPELINE` (#986). `check-env-doc` and
`test_check_env_doc` fail in `scripts/agent-preflight.sh` for every branch cut
from `3005447f8`, because three expert-streamer knobs landed undocumented:
`VT_MOE_EXPERT_STREAM`, `VT_MOE_EXPERT_STREAM_SLOTS` and
`VT_MOE_EXPERT_STREAM_SLOT_BYTES`.

Proved pre-existing rather than asserted, with a matched-arm check. The three
are read from `src/vllm/model_executor/models/qwen3_5.cpp` at `origin/main`, a
file this branch does not touch, and `git diff origin/main...HEAD | grep
'^+.*VT_MOE_EXPERT'` returns nothing against 18 changed files as the control.
`grep -c VT_MOE_EXPERT docs/ENVIRONMENT.md` returns 0.

Not fixed in flow, and the reason is not convenience. Documenting a knob means
stating its default and when a reader should touch it, and the expert-streamer's
slot accounting is the subject of the row that added it; a plausible-sounding
entry written by a passer-by is how `docs/ENVIRONMENT.md` stops being worth
reading. `AGENTS.md` also forbids bundling unrelated work into one branch. The
index row names `ENG-EXPERT-STREAM` as the owner, which is what the in-flow rule
requires of an issue that is filed and not fixed.

It is worth an issue rather than a mention because it is a PRE-FLIGHT gate: it
fires before every edit on every branch, so it presents to each author in turn
as a red their own diff caused. That is the shape #965 and #968 both took on the
`windows-msvc-*` jobs.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
… the resolution first (#986)

The DFR canvas was resolved BEFORE `Ltx2AssertResolution`, and upstream's order
is the other way round: `assert_resolution` at `dfr_pipeline.py:291`, then
`resolve_canvas` at `:314`.

That reversal is invisible to every other case in this file, and that is what
makes it worth a commit of its own. Both refusals are correct and both name a
real defect in the request; a caller who asks for a 96-wide clip at 10 frames
simply hears a different one from this port than from the reference. Nothing
about a render, a shape or a token count can see the difference, because on that
input neither port renders anything.

Found by re-deriving this row's own upstream anchors at the final tree rather
than trusting the ones written during implementation. All 44 resolve into their
cited spans; this was the one place the anchors were right and the CODE ORDER was
not.

Gated by a new subcase, and the gate is proven rather than assumed. M14 moves the
canvas resolution back above the guard: it BUILT with `': error:' count = 0`, the
binary sha CHANGED from `452aef68448c7d21` to `7e6c27fee6fd89a4`, and the suite
went RED at 51/52, 2 assertions failed, `RUN_EXIT=1`. Restored, rebuilt to the
same baseline sha, back to 52/52 and 1248 assertions, `RUN_EXIT=0`.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
…elete the comment that said it was already cut (#986)

A 9-frame DFR request emitted 0.375 s of picture beside 1.01 s of sound. The
canvas pads 9 frames to 25, `ashape.frames` is derived from the PADDED count
inside the phase loop, `audio_lf` carries it out, and the vocoder runs over all
of it. Trimming the video latent moves `frames` and touches none of that.

Upstream cuts the decoded audio to `num_frames / playback_fps`
(`dfr_pipeline.py:552-560`) and states the consequence rather than the mechanism:
"Audio was generated for the padded canvas, so cut it to the video's duration or
the muxed container outlasts the picture."

The worse half of this is not the missing line. This row shipped a COMMENT
saying the cut was "already implied by the trimmed `frames`", so a reader who
went to check `:552-560` would have found it accounted for and stopped. That
comment is deleted and replaced by one that says what was wrong with it.

Nothing else in the tree could see the defect: the render has the right shape,
the right frame count and a zero exit status, and the mismatch appears only in a
muxed container this library does not produce. So the gate reads the WAV header
rather than trusting the engine's own report of what it wrote, and it derives the
bound from the result's own `frame_count`, `fps` and `sample_rate` rather than
from the canvas, so a mutation cannot move both sides together.

The first draft of that gate was itself wrong, and it is worth recording because
the error is the kind that reads as caution. It assumed one channel, calling that
"the loosest reading and therefore the safe direction". It is the opposite:
dividing by too few channels reports a LONGER file than exists, so the bound
false-fails on a correct cut, which is exactly what it did. It now reads the
channel count, the sample rate and the bit depth out of the file.

M15 disables the cut: it BUILT with `': error:' count = 0`, the binary sha
CHANGED from `f003301e494acc36` to `182e792b9eba8a8a`, and the suite went RED at
51/52 with the message `picture 0.375s, sound 1.01s, 2 channels at 48000 Hz`,
`RUN_EXIT=1`. Restored, rebuilt to the same baseline sha, back to 52/52 and 1265
assertions, `RUN_EXIT=0`.

Found by re-deriving this row's own upstream anchors at the final tree. All 44
resolve into their cited spans; twice the anchor was right and the code was not.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
…RES.md by key

`origin/main` advanced to `e770a392f` (#982) while this row was in review.

`docs/FEATURES.md` is a KEYED RECORD and both sides edited it, so the automatic
three-way merge is not accepted on its own word. AGENTS.md asks for the target
version plus the scoped edit reapplied, with unrelated keys proven byte-for-byte
equal, and that is what was checked: **189 unrelated keys compare byte-for-byte
equal**, this row's new `LTX-2.5 DFR base + generated keyframe slots` row is
present and is not a duplicate of anything on the target, and the LTX-2.5 DiT row
differs from the target by exactly the six characters this row owns — `GENkf/`
removed from `GENkf/DiffVAE/ref refused`, because generated keyframes are now
served.

The verifier carries its own floor: a comparison of fewer than 50 unrelated keys
fails, because a parser that matched almost nothing would otherwise report a pass
over an empty set.

`scripts/check-agent-record.py` also moved on the target. The full gate is re-run
on the merged tree rather than inherited, because a clean merge is not a building
merge and because a changed checker is a changed gate.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
`origin/main` advanced to `4496ef196` (#988). It touches three NemotronH spec
files and nothing else — no source, no test, no build file and no keyed record —
so this merge changes nothing this row builds or gates, and the full gate above
still describes the tree.

Stated rather than assumed: `git diff --name-only e770a39 4496ef1` returns
`.agents/specs/nemotron-h-a2q1-fp8-mamba.md`,
`.agents/specs/nemotron-h-a2q2-nvfp4-moe-lmhead.md` and
`.agents/specs/nemotron-h-abi-e2e.md`, and no fourth path.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
… M5 stays green (#986)

Adds the two-stage DFR case through the production entry point, with the fixture
spatial upsampler. It renders at full resolution, which is what proves both
phases ran, and asserts stage 2 places and reads back slots of its own at 4
tokens each against stage 1's 1.

It also corrects a claim this row made about its own evidence, which is the more
useful half.

M5 stops the slot seed reaching `latent`. It stayed GREEN against
`test_ltx2_video`, and the first explanation was "a no-op on phase 0, which is
the only phase the engine's DFR case runs". That explanation makes a prediction:
a two-phase case should turn it RED. The case now exists and **M5 stayed GREEN
with it present, 52/52, exit 0**, so the explanation was wrong.

The real reason is a property of the pipeline. Stage 2 re-noises to
`stage_2_sigmas[0]`, about 0.909, so the seed is almost entirely replaced by
noise before the first step and the loop generates the rest. The assertions an
engine test can make about a slot are structural, and the seed moves none of
them. There is no A/B either, because the seed is internal rather than a request
field.

So the case is kept for what it does establish and its comment says exactly that:
it REACHES the seeded path, which no other engine test does, and it does not
DETECT the seed. M5 stays gated in `test_ltx2_dfr` on the property that belongs
to the port, that the seed lands in `latent` and not in `clean`, where it goes
RED.

M8 was re-run at the same time and stayed GREEN as predicted: the slots still
trail, because nothing appends after the slot item until the #975 reference arm
lands.

`test_ltx2_video` 52 cases / 1279 assertions, `RUN_EXIT=0`. Full gate on the
merged tree: `BUILD_EXIT=0`, zero errors, zero warnings, `ctest -j4` 491/491
passed, `CTEST_EXIT=0` in 167.17 s.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
…der-claimed it (#986)

The reach note said CLI and ABI only, on the grounds that `/v1/videos` forwards
no engine extras (#928). That is true of the per-GENERATION extras and false of
`pipeline_kind`, which is a LOAD knob.

Traced rather than assumed: `--video-extra KEY=VALUE` is parsed at
`server_main.cpp:492-503` into `args.video_extras`, and `:1317-1325` copies every
pair into `vmp.extras`, refusing by name when two spellings of one key disagree.
So `--video-extra pipeline_kind=dfr` at launch selects the DFR recipe and every
`/v1/videos` request on that server renders through it.

The distinction is now stated in `docs/USAGE.md` rather than implied: three
surfaces carry `pipeline_kind`, and the two knobs beside it,
`num_generated_keyframes` and `temporal_upsample_rounds`, are per-generation and
therefore CLI and ABI only until #928 lands.

Under-claiming is the safer direction and it is still an inaccuracy: a reader
planning a deployment would have concluded DFR was unreachable from the server
and gone looking for a change that is not needed.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
…ine kinds

`LTX25-RETAKE` (`3ce1cf7c7`, #992) landed while this row was in review, and the
two rows overlap on ten files. Four conflicted as source, and all four conflicts
are the same shape: both rows add a pipeline kind, so both extend the recipe
table, the per-generation extras list and the refusal set. Every one is resolved
as a UNION with nothing dropped from either side.

- `ltx2_pipeline.h` — the `ResolveLtx2PipelineRecipe` table comment. The `dfr`
  row and the two `retake` rows now sit together, and retake's paragraphs on why
  it is not `distilled_two_stage` with a phase removed are kept in full.
- `ltx2_pipeline.cpp` — `DfrRecipe` and `RetakeRecipe`. Git's conflict swallowed
  the shared `return recipe; }` tail, so both functions had to be closed by hand;
  each keeps its own body byte-for-byte. The dispatch arms below auto-merged and
  both kinds resolve.
- `ltx2_video.h` — the extras key constants. `temporal_upsample_rounds` and the
  five retake keys are all declared, each with its own comment block unchanged.
- `ltx2_video.cpp` — the known-extras predicate, the "this family defines" list
  and the `Generate` preamble. The preamble conflict is the only semantic one:
  DFR gave `CheckGeneratedKeyframes` a `pipeline_kind` parameter, so the merged
  call is DFR's two-argument form, and both refusal blocks run.

`READER ANCHORS` was re-derived rather than assumed. Both rows insert above it,
so neither side's list was right: every anchor moved by one, `780 …` became
`781 …`, and the list here is the one `test_ltx2_video`'s own walk produced.
Both rows recorded this hazard in advance and both were correct to.

`docs/FEATURES.md` was reconciled BY KEY against `origin/main` rather than
accepted from the automatic merge: 194 keys, 192 byte-identical to main, one
added (the DFR base row) and one changed. The changed row's only difference is
the six-character `GENkf/` removal in its fourth cell; its third cell, which
carries `Temporal x2 ups gated, UNDRIVEN` and which
`.agents/specs/ltx25-resolution-envelope.md:436` asserts is untouched, is
byte-identical to main at 218 characters. `docs/USAGE.md` is exactly main plus
this row's own hunks — the diff against `origin/main` and the diff across this
row's base are equal line for line. `.agents/issue-index.md` union-merged to 253
rows: two added, zero removed, zero duplicate issue ids.

`check-env-doc` and `test_check_env_doc` are red, and they are #995, not this
merge. The only `VT_MOE_EXPERT` line this branch adds anywhere is the #995 index
row itself, and the branch touches none of the checker's four inputs.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
@localai-bot
localai-bot merged commit 332aed7 into main Aug 16, 2026
7 of 20 checks passed
localai-bot added a commit that referenced this pull request Aug 16, 2026
…rmed (#1022) (#1025)

Closes #1022.

`main` at `45b022cdc` is RED on `check-agent-record.py` — the CI job `agent-record` — for **every** branch cut from it:

```
ERROR: .agents/issue-index.md: issue #995 listed twice. Under `merge=union`
a duplicate is what two branches appending the same issue look like
```

Reproduced on a clean detached worktree at `45b022cdc`, not the shared checkout (which reports differently on this surface). Independently corroborated by the A2-Q2a helper, which hit the same red at the same base.

## Three defects, one cause, one repair

| # | Defect | Caught by |
|---|---|---|
| 1 | duplicate key `#995` (lines 270 and 272) | `check-agent-record.py` |
| 2 | line 272 lacks its trailing `\|` — a 3-cell row in a 4-column table | **nothing** |
| 3 | line 270 has an **unescaped** `\|` inside a code span — 5 rendered cells | **nothing** |

Line 270 arrived with `332aed738` (#996), whose author recorded the env-doc red they hit while gating #986. Line 272 arrived with `45b022cdc` (#997), the fix for that same red. **#997 did the right thing** — it discarded the union driver's clean auto-merge and re-appended against its pinned base `3ce1cf7c7`, asserting the prefix property by hand. But `main` then advanced to `332aed738`, which had *already* added a `#995` row, and the squash-merge applied #997's append on top without seeing it. Neither author could have seen the other's row when they wrote theirs.

A cell-count histogram over the whole file reads `{6: 252, 7: 1, 5: 1}` — **the only two malformed rows in the index were the two `#995` duplicates.** Merging them by key repairs all three defects at once.

The merged row carries BOTH sides' content, per the keyed-record rule: the discoverer's provenance (found while gating #986, proved pre-existing with a matched-arm check, deliberately not fixed in flow and why) and the fixer's resolution (documented in `docs/ENVIRONMENT.md` rather than allowlisted, and why).

## Exception argued, not waived

This change **deletes a row and edits another**, which is precisely what `scripts/check-issue-index-append-only.py` forbids. That gate is RED on this branch and I am not weakening it — there is no waiver registry, so the argument lives in the commit message where it is attached to the diff it excuses.

The append-only contract **cannot** repair a duplicate: appending a third `#995` row makes `check-agent-record` angrier, and the file only becomes well-formed again by removing one. The two gates are in genuine contradiction on this tree, and that contradiction is the defect.

The rule is preserved in substance, verified mechanically rather than by eye:

- 254 → 253 rows; `#995` appears exactly **1x**
- all 253 rows are 6-part (well-formed) — up from 252
- **252 unrelated rows byte-identical AND in the same order**, compared as a list
- the survivor sits at the **earlier** of the two positions, so every subsequent row keeps the offset it was appended against
- no key added, no key lost

That gate is preflight-only and not in CI, so this costs no CI red. Once merged, later branches diff a `main` with no duplicate and see no removal in their range — the violation is confined to this branch.

## Scope note

This is the **duplicate** case, which the checker does catch. It is *not* #1002 (append-only checker blind to an **interleave**, which preserves uniqueness and fails only the PREFIX property). #1002 stays open on its own terms. Both are consequences of a record surface every PR must write — the shape AGENTS.md warns about under "No surface that every PR must write".

## Gates

- `check-agent-record.py` RED-before at `45b022cdc` (verbatim above) → **green after**
- `check-env-doc.py` green (confirms #997's fix survives)
- `scripts/agent-preflight.sh`: 2 failures, both accounted for — `issue-index append-only` (argued above) and `test_cpu_x86_llamacpp_floor` (exit 4 `NO_QUIET_WINDOW`, box load average **106**; diff is 1 markdown file and **0** code files, so it cannot be mine by construction)

Diff is `.agents/issue-index.md`, +1/-2.

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