feat(LTX25-DFR-PIPELINE): the DFR canvas, the slots it invents, and the loop that still does not run (#986) - #996
Merged
Merged
Conversation
…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]
This was referenced Aug 16, 2026
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]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
DFRPipeline's BASE is ported and reachable:--pipeline-kind dfrresolves 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.mdstill 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. PinLightricks/LTX-2 @ fd4ded7f2d88d3da713abcdd4ad41ecc4a9314ca, verified at the local checkout withgit rev-parse HEADbefore any anchor was read.What landed
ltx2_dfr.{h,cpp}isdfr_layout.pyin full plus the threedfr_pipeline.pyhelpers 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_dfrcompares element by element against values the upstream module RETURNED, not against a reading of its source.ltx2_conditioninggainsLtx2ConditionVideoByGeneratedKeyframeSlots,Ltx2GeneratedKeyframeLayoutandLtx2ExtractGeneratedKeyframes, withLtx2ClearConditioningextracting 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 intolatentand notclean, the denoise mask is 1 and not1 - strength,markedis TRUE (upstream's only such call site), and the temporal span is one pixel frame written by hand.ltx2_video.cppgains thedfrpipeline 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_kindis a LOAD knob, so all three surfaces carry it:ltx2-gen --pipeline-kind dfr, the C ABI'svllm_video_model_params.extra_keys/extra_values, and the server's--video-extra pipeline_kind=dfrat launch (server_main.cpp:492-503parses it,:1317-1325copies it intovmp.extras). A server started that way renders every/v1/videosrequest through DFR. This PR originally claimed CLI and ABI only, on the grounds that/v1/videosforwards no engine extras (#928) — true of the per-GENERATION extrasnum_generated_keyframesandtemporal_upsample_rounds, and false ofpipeline_kind. Corrected indocs/USAGE.mdand here.The oracle, and why it is not an import
scripts/gen-ltx2-dfr-goldens.pyimports and EXECUTESdfr_layout. It does not importdfr_pipeline, because that pullsiclora_utilstoutils.media_iotoltx_core.color.hlg, which imports PyAV — a codec binding this project deliberately does not vendor, and the same dependency theimage_crfround 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, andtest_ltx2_videore-derived those names fromltx2_conditioning.h. Section 4a of that spec predicted this exact event in terms:It went red. The assertions are retired with the refusal they described and replaced by assertions about what replaced it, never widened.
AGENTS.mdforbids 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:177gives the first tile no lead-in, which reads as load-bearing and is redundant with themax(0, own_lo - lead)clamp beside it. Measured against executed upstream:_build_tileon tile 0 with lead 0, 1 and 5 returns threeTileRanges that compare EQUAL.ltx2_dfr.hcarried the opposite claim until the mutation refuted it, and now carries the correction with a gate on it.keyframe_slots.py:161-163says the causal fix "must not also be applied" because the span is set explicitly. Measured the same way: computing withcausal_fix=Trueand 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
R1deletes the productionLtx2DfrResolveCanvascall site andR2deletes the production slot-conditioning call site. Both taketest_ltx2_videoRED, 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 intest_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 intest_ltx2_dfron the property that belongs to the port — the seed lands inlatentand not inclean— where it goes RED.Mutations
Every one carries three facts:
git diff --statafter 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.choose_segment_lengthtie takes the SMALLER candidatetest_ltx2_dfr_build_tilekeeps boundary 0 as an anchortest_ltx2_dfrdrop_latent_prefixomits the seam handover+1test_ltx2_dfrtest_ltx2_dfrtest_ltx2_dfrlatenttest_ltx2_dfrcleantest_ltx2_dfrmarked=falsetest_ltx2_dfrtest_ltx2_dfrtest_ltx2_dfrtest_ltx2_dfrfirst_tokentest_ltx2_dfrtest_ltx2_dfrtest_ltx2_dfrtest_ltx2_dfrLtx2DfrResolveCanvascall site is deletedtest_ltx2_videotest_ltx2_videotest_ltx2_videotest_ltx2_videoassert_resolution(upstream's order reversed)test_ltx2_videotest_ltx2_videopicture 0.375s, sound 1.01s, 2 channels at 48000 HzGate
CPU only. The GPU was not used: a render ladder holds
dgx.casa.Re-run on the MERGED tree at head
ad3a5e021; the last commit is documentation only. The final run isCTEST_EXIT=0, 491/491 passed, 167.17 s.origin/mainmoved three times during this row (0e1bee42fto3005447f8toe770a392fto4496ef196) 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 left0,BFD assertion0, against 487Linkinglines as the positive control that those greps ran over real contentctest -N= 491test_ltx2_dfr(11 cases / 652 assertions) andtest_ltx2_video(52 cases / 1279 assertions)test_modelopt_mixed_precision_checkpoint,test_voxtral_e2e. Nothing else skippedThe 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 returnedCTEST_EXIT=8—test_engine_core_proc+test_cpu_threadpoolin one,test_engine_core_proc+test_async_llmin 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.mdis a keyed record and both sides edited it. The automatic three-way merge is not accepted on its own word.AGENTS.mdasks 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-checkpointrun per commit (#573): all seven commits exit 0. The instrument is ARMED, not merely quiet:--commit b5618b305exits 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 ERRORcheck-commit-styleexit 0,check-commit-trailersexit 0,check-public-doc-tablesexit 0,check-agent-recordexit 0One pre-existing red, filed rather than absorbed.
scripts/agent-preflight.shfailscheck-env-docandtest_check_env_docon this branch and on every branch cut from3005447f8: threeVT_MOE_EXPERT_STREAM*knobs landed undocumented with #993. Proved pre-existing with a matched-arm check rather than asserted — the three sites are inqwen3_5.cpp, which this branch does not touch, andgit diff origin/main...HEAD | grep '^+.*VT_MOE_EXPERT'returns nothing. Filed as #995, ownerENG-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 callsassert_resolutionatdfr_pipeline.py:291andresolve_canvasat: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-560cuts decoded audio tonum_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.framesis derived from the PADDED count inside the phase loop,audio_lfcarries 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-560would 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## Owedagainst #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 fromltx2_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.safetensorsis 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
quantization_factory.py:23-26), and no published LTX-2.5 checkpoint is a GGUFFOLLOWING_AGENTS_PROTOCOL
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]