fix(LTX25-RETIRE-DEAD-ARMS): retire the invented refusals, and the assertion that could not fail (#644, #611) - #882
Merged
Conversation
…t have (#644, #611) The LTX-2.5 out-of-scope ledger records seven refusals. Two of them are not refusals of anything. `kMultishot` cites "ltx-pipelines multishot entry points", and no such entry point, symbol or string exists in Lightricks/LTX-2 @ fd4ded7f or huggingface/diffusers @ 3a2f35d4. `kVideoEngineWiring` says the end-to-end composition "is phase L7, not L5", and L7 shipped in `cefacd2d0`. A third, `kCfgParallelism`, names something upstream does not do: there is no CFG pass to split, because the distilled recipe denoises with SimpleDenoiser at both stages. Three more are recorded as refusals but have no product call site, so nothing a caller can send reaches them. Calling a declared boundary a refusal overstates what the port has, and the messages now say which kind they are. Separately, `duration_head_path` is accepted by `kKnownLoadExtras` and read by nothing, so a caller who points at a duration head silently gets the recipe default (#611). The spec carries the full accepted/read inventory of all ten extras and the derivation of every absence claim, each with its positive control in the same command. Section 1.6 was re-derived at integration against `origin/main` `9a8615672`, because `2e9d95e74` renamed `kTemporalUpsampler` to `kSpatiotemporalUpsampler` after this row's base. The split it establishes -- two reachable, three markers -- is unchanged. Refs #644, #611. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [claude-code]
…sertion that could not fail (#644, #611) `kMultishot` and `kVideoEngineWiring` are gone: one refused a feature neither reference has, the other one that shipped in `cefacd2d0`. `kCfgParallelism` becomes `kMultiGpuParallelism` and its message names upstream's three actual forms. The three arms with no product call site say `DECLARED, NOT REQUESTABLE`, so a marker can no longer read as a refusal a caller could trip. `duration_head_path` is refused by name at load instead of accepted and read by nothing, which is what silently substituted the recipe default for the file a caller named (#611). THE ASSERTION THAT COULD NOT FAIL. The retirement note's `ltx-core` check was `CHECK(flat.find("ltx-core") != npos)` over the whole flattened header. That string occurs six times in the file -- the upstream map at :8 and :28, `parse_model_version`, `kLoraFusion`, and twice in the note itself -- so the assertion survived deleting the clause it exists to hold, and it passed in this row's own red-first run. The positive checks are now scoped to the note, sliced from the `kMultishot` marker to the next enumerator heading and derived rather than pinned to a line, and the `ltx-core` one asserts the CLAIM: "ships at INFERENCE inside `ltx-core`". Rewriting the note to say the guidance ships inside the TRAINER ONLY now fails it -- BUILD_EXIT=0, 40 cases, 1 assertion red -- while under that same mutation `ltx-core` still occurs five times in the file, which is the old assertion staying green. THE DOC ROWS THE MERGE WOULD HAVE FALSIFIED. `2e9d95e74` ported the temporal x2 latent upsampler on this same issue and renamed the enumerator, so the arm this port still refuses is the SPATIOTEMPORAL one. `docs/FEATURES.md` and `docs/USAGE.md` now say that, and say plainly that the temporal-only arm is ported, gated and driven by nothing. main's "Temporal x2 ups gated, UNDRIVEN" cell is byte-for-byte unchanged. The FEATURES gate's `reachable_words` carried the bare token `upsampler`, which matches both arms and therefore distinguishes neither; it reads `spatiotemporal upsampler`, matched case-insensitively, and the case now also holds the reachable row itself, so a row calling the ported arm refused is red. The recorded reader anchors in `ltx2_video.cpp` moved again under the merge and are re-derived to 655 710 806 822 824 894 919 1024 1065; the derived-anchor gate is what found them. #611, #691 and #692 are appended to `.agents/issue-index.md`, the append-only surface `51e0cb5b1` created, rather than to the `roadmap_v1.md` table main deleted. A grep for all three returned zero against a #644 control in the same command, so all three were genuinely missing; each names `ROAD-V1-LTX25` as its owning row, and the unowned ratchet is unmoved at 33. Closes #644 in part. Refs #611, #691, #692. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [claude-code]
This was referenced Aug 15, 2026
`main` moved seven commits past this branch while the fourth review round was in flight, and two of them bind the repair that follows. `8f49ac3be` adds AGENTS.md `## Nothing lands dead` and `.agents/reachability.md`, which name the exact shape finding F1 describes: the test-only driver, where the only thing that calls the new code is the test written for it. `98f8e046d` retires `--allow-unported` on the LTX-2.5 path. Merged rather than rebased because `ea6b01f1f` is already the published head of pull request #882, and `main` is never force-pushed here. No conflicts. `98f8e046d` moves the nine derived READER ANCHORS in `ltx2_video.cpp` by five lines, which the anchor gate reports on the next run; that record edit rides in the commit after this one, with the change that made it stale. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [claude-code]
…ication `ltx2_video.cpp`'s phase guard tested `im.upsampler_cfg.temporal_upsample` alone. Every BOTH-flags config satisfies that too, so the two guards were an implication over one variable and this one always fired first. A caller who supplied a genuine spatiotemporal checkpoint was told it is the TEMPORAL x2 upsampler and pointed at the spatial one: wrong on both counts, and pointing them at the arm they already had. The cost is not only the message. It made the ledger refusal that names this arm, `ltx2_upsampler.cpp:465`, unreachable from any request, so `docs/FEATURES.md`'s "a product path constructs each and throws" was false for the one arm it was still true of after #889. Narrowed to `temporal_upsample && !spatial_upsample` so a both-flags config falls THROUGH to that refusal. The reviewer who found this named a real limit on their own evidence: no fixture drove a both-flags checkpoint through `LoadVideoEngine`, so mutation could not separate "unreachable" from "untested" and only the static implication settled it. That hole is closed here. The new subcase writes a both-flags upsampler and drives it through `LoadVideoEngine` + `Generate` rather than calling `Ltx2LatentUpsample` directly, because AGENTS.md `## Nothing lands dead` requires the smallest failing test to enter through a production entry point. RED before, on the shipped guard: `SPATIOTEMPORAL` absent, and both `it is the TEMPORAL x2 upsampler` and `Supply the spatial upsampler` present. Green after, `test_ltx2_video` 40/40, 827 assertions. Two mutations, each of which BUILT with 0 errors before it was run. Widening the guard back to `temporal_upsample` alone: RED, 3 assertions. The reachability mutation from `.agents/reachability.md` — deleting the production call site `Ltx2UpsampleVideoLatent` in the phase driver: RED, and it also fires the positive control in `test_ltx2_pipeline`'s new split case, which then reports `Ltx2UpsampleVideoLatent callers = <none>`. The tree was restored byte-for-byte after each, verified by sha256. The recorded READER ANCHORS move by five lines in the same commit. That is the merge of `origin/main`, not this change: `98f8e046d` added lines above them, and the derived-anchor gate caught it exactly as it was built to. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [claude-code]
…lter hid Two review findings on the LTX-2.5 out-of-scope ledger, plus the records they made stale. ## #889 — `kBetaScheduler` was published as reachable and has no caller The header defines a reachable refusal as one "a caller CAN trip", and `docs/USAGE.md` published "Both are reachable". Neither was true of `kBetaScheduler`. Its site `ltx2_pipeline.cpp:199` sits inside `Ltx2Schedule`, which has zero call sites in `src/`, `include/` or `examples/`; the engine calls `Ltx2SigmaSchedule` directly and no ABI field, load extra or CLI flag carries a scheduler kind. The only driver is the unit test that constructs the enumerator by hand. §1.6 asked whether an enumerator appears in `src/`, and that question's true answer is the wrong answer. Reclassified as a marker rather than wired, and UPSTREAM is why, not convenience. At Lightricks/LTX-2 `fd4ded7f`, `BetaScheduler` is defined at `ltx-core components/schedulers.py:91` and constructed nowhere in the repository: all seven `ltx-pipelines` entry points hard-code `LTX2Scheduler()` (`ti2vid_one_stage.py:81`, `ti2vid_two_stages.py:87`, `ti2vid_two_stages_hq.py:90`, `a2vid_two_stage.py:78`, `t2a_one_stage.py:67`, `keyframe_interpolation.py:82`, `retake.py:96`), and vLLM-Omni `a4ea67a21` has zero hits for the name against 81 files carrying `ltx` as the control. Routing the engine through `Ltx2Schedule` would have invented a scheduler-selection surface that upstream does not have, so mirroring upstream forbids the wiring repair. The classification is now DERIVED. `test_ltx2_pipeline`'s new "the reachable/marker split matches the source" walks the product tree, counts callers of each arm's entry function, and requires the message to agree in both directions, so a caller appearing later fails the marker wording just as its absence failed the reachable wording. Two positive controls ride in the same walk plus a file-count floor, because this is an absence claim about our own tree and this row has already shipped four of those. That is the anti-tautological shape #691 asks for, applied to the beta arm; #691 stays open for the three markers that have no call site to derive from. ## #892 — the multi-GPU marker's `cfg` absence is false, and a form is missing The header shipped an assertion that `cfg` is absent from both multigpu trees and the refusal shipped "three forms". At the pin it is 5 hits against 33 files as the control, two of them prose about CFG at `docs/multigpu/gemma.md:103-104`. The spec's grep was correct and its PATH FILTER was wrong: scoped to the two SOURCE trees, it excluded `docs/multigpu/`, where the answer is written out. That is this row's own transferable lesson committed a fourth time. There is also a fourth `BuilderProtocol` in the directory the refusal cites, `multigpu/bp_gemma_builder.py:42` `BatchParallelGemmaBuilder`. The disposition is unchanged and stronger. `gemma.md:104` records that the distilled pipeline this port runs takes no `negative_prompt` and "runs without CFG", so the one form that would carry a CFG pair is the one upstream tells you not to use here. A reason beats an absence. ## Reachability disclosure Per AGENTS.md `## Nothing lands dead`, which landed in `8f49ac3be` while this repair was in flight: `Ltx2Schedule` and `Ltx2SchedulerKind` are UNREACHED. Owned by row LTX25-RETIRE-DEAD-ARMS, tracked by #893, listed under `## Owed` in the row's spec. This is not a staged slice awaiting a wiring wave — upstream selects no scheduler anywhere, so there is nothing to wire it to, and the open decision is retire-or-keep-as-recorded-mirror. Deciding that is a behavior change with its own red-first evidence, which is why this commit labels the arm honestly and does not also delete the dispatcher. ## Evidence RED before, `test_ltx2_pipeline` 39/42 cases, 8 assertions failing: the beta marker assertion, four on the multi-GPU message (`three forms` present, `four forms` / `BatchParallelGemmaBuilder` / `gemma.md` absent), the header's `cfg` sentence, and the split case reporting `Ltx2Schedule callers = <none>` with both controls live at `ltx2_video.cpp:1515` and `:1689`. Green after, 42/42, 2485 assertions. Two mutations, each BUILT with 0 errors before it was run. Dropping the `marker` suffix from the beta refusal: RED in both the ledger case and the split case. Restoring "three forms": RED, 2 assertions. Tree restored byte-for-byte after each, verified by sha256. One consequence worth recording because it cost a build cycle: the header may not QUOTE the retired sentence while explaining it. A text gate matches text and cannot tell a quotation from a claim, so the corrected note describes the old sentence instead of reproducing it, and says so. ## Records `docs/FEATURES.md` and `docs/USAGE.md` are keyed records, edited by key: exactly two FEATURES rows change and the other 365 lines are byte-identical, with the filter's own line count as the control. `.agents/issue-index.md` gains four rows and loses none. The spec's §1.1 control count is re-measured at 24 rather than 22, its §2.1 `docs/USAGE.md` anchor is replaced by the paragraph's opening words after being wrong by ~290 lines, and §4 item 7 now describes the tightened `ltx-core` assertion that shipped rather than the weak one it replaced. Moving anchors in `ltx2_video.cpp` are named by symbol, not by line, because three anchors in this row went stale inside one branch. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [claude-code]
FOLLOWING_AGENTS_PROTOCOL Keyed records reconciled by key; the issue index is append-only (merge=union). Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [claude-code]
localai-bot
pushed a commit
that referenced
this pull request
Aug 15, 2026
…chors (#644) `origin/main` advanced four commits while this branch sat on `00613767d`. Merged rather than rebased, because a rebase over a pushed branch is a force-push and `AGENTS.md` forbids one. The merge reported no conflict. It is not a document-only merge, which is why it is committed on its own. The one commit that matters here is `0785cfc4d` (#882, `LTX25-RETIRE-DEAD-ARMS`), which touches the same two files this row's record cites most: it adds 70 lines to `src/vllm/multimodal/ltx2_video.cpp` and 306 to `tests/vllm/multimodal/test_ltx2_video.cpp`, all of them AHEAD of every anchor this spec carries into those files. Seven citations that were correct at `00613767d` are wrong at this commit, and the repair rides in the next one. The rest is `04be1390b` (#901) sweeping unchecked registry downcasts across 30 translation units, `b5f27c9a4` (#906) recording issue #904, and `727ac7734` (#909). None of them is on this row's path. Verified after merging rather than assumed: `git diff --numstat origin/main` names `.agents/issue-index.md`, `.agents/model-matrix.md`, `.agents/specs/ltx25-prompt-adaln.md`, `scripts/gen-ltx2-goldens.py`, `scripts/measure-ltx2-prompt-adaln.py`, `tests/vllm/models/ltx2_goldens.inc`, `tests/vllm/models/test_ltx2.cpp` and `tests/vllm/multimodal/test_ltx2_video.cpp` — and no `src/` or `include/` path, so the claim in this row's Outcome that it changes no product source still holds against the NEW `origin/main`. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [claude-code]
localai-bot
pushed a commit
that referenced
this pull request
Aug 15, 2026
…alidated, marked UNKNOWN rather than carried (#644, #673) The merge that repairs seven anchors also invalidates a count, and the count was about to ride along unexamined — which is the same defect in its other form. An anchor and a measurement both name a tree, and this row's rule is that neither survives a merge on the argument that it probably did not move. `0785cfc4d` (#882) added 306 lines to `tests/vllm/multimodal/test_ltx2_video.cpp` between `00613767d` and this branch's tip, taking it from 37 to 40 `TEST_CASE`s. The Outcome quoted 37 / 784 with `LTX2_CHECKPOINT_ROOT` unset and 37 / 9031 with it set, dated to the PREVIOUS merge, in three places. What is measured here is the SOURCE count, 37 to 40, by `grep -c '^TEST_CASE'` on both revisions with the same grep returning matches on `origin/main` as its control. The doctest CASE and ASSERTION totals were NOT re-run, so they are recorded as UNKNOWN rather than adjusted, guessed, or left standing. Marking a number superseded is cheap; inventing its replacement is not available, because the `set` arm needs the 18.72 GB NVFP4 and 23 GB FP8 DiTs under `$CHECKPOINT_ROOT` and no CI host has them. That debt is #673's, where it already lives. Two claims that DO survive, checked rather than assumed. The #673 ratio finding — CI executes a single-digit percentage of this suite — does not depend on the exact totals. And the #900 reachability finding, that deleting the term leaves `test_ltx2_video` green, is not undone by adding three cases that also do not observe it. Scoped by measurement, not by assertion: `test_ltx2_loader.cpp` and `test_ltx2_device.cpp` are byte-identical across those two revisions — `git diff --numstat` reports nothing on either, against a positive control that reports `62 8` on `ltx2_video.cpp` — so their counts are untouched, and `test_ltx2.cpp` differs only by this branch's own edit. All 33 citations re-derived again on this tree: 33 FRESH, armed control still 6 STALE of 33. This commit changes one Markdown file and no build input, so the `BUILD_EXIT=0` / `CTEST_EXIT=0` / `100% tests passed, 0 tests failed out of 480` gate measured at `7bf2a9297` still describes the tree that lands; `git diff --name-only 7bf2a92` naming only the spec is the evidence, and it is stated as an inherited gate rather than a fresh one. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [claude-code]
This was referenced Aug 15, 2026
localai-bot
added a commit
that referenced
this pull request
Aug 16, 2026
…rim it back (#930) (#964) The LTX-2.5 phase loop was fixed at one `Ltx2VideoTokenCount(vshape, 1)`, and that single limitation blocked three conditioning arms. Two rows walked into it hours apart without talking to each other — [#930](#930) from the IC-LoRA port and [#920](#920) from the generated-keyframe-slots port — which is why it gets a seam of its own rather than a fix inside whichever row noticed it last. Issue: [#930](#930). Spec: [`.agents/specs/ltx25-token-append.md`](.agents/specs/ltx25-token-append.md). Campaign [#644](#644). Pin `Lightricks/LTX-2 @ fd4ded7f2d88d3da713abcdd4ad41ecc4a9314ca`, verified at the working checkout. ## Why this branch replaces #948 **This is a history repair, not a content one.** [#948](#948) carried this row through implementation and a fresh review to PASS at head `a1b1d8da4`. It cannot land, and the reason is entirely in its commit ORDER. `scripts/check-doc-checkpoint.py` walks a range **per commit** ([#573](#573)). The review-repair commit `b5618b305` edited `include/vllm/model_executor/models/ltx2_conditioning.h` and `include/vllm/multimodal/ltx2_video.h` — the `user_usage` class — while the `docs/USAGE.md` edit that pays for them sat in a sibling commit. The final tree satisfied the obligation; only the ordering failed. Measured on this branch, the checker still REDs on `b5618b305` in isolation and is green on both commits here, so the instrument is armed rather than merely quiet. A commit message cannot be corrected in place and this repository uses no force variant, so the branch is rebuilt with the shape the checker requires: **one spec commit, then one implementation commit** carrying `docs/USAGE.md` and `docs/FEATURES.md` alongside the code they describe. #678 was rebuilt as #880 and #661 as #882 for exactly this rule. **The reviewed content is proven unchanged.** Built on `2daa3287f` — `origin/main` when the rebuild started — this branch's head tree hash was `d937252dd06efd6a07c4affebff42153b25075a5`, byte-for-byte equal to `a1b1d8da4^{tree}`, and `git diff a1b1d8d HEAD` was empty. `origin/main` then advanced to `f365cc299` (#958), so the branch was rebased onto it; restricted to this row's ten files, the only remaining differences against `a1b1d8da4` are the two lines #958 itself changed — its own appended issue-index row and its `--offload-config` rewrite in `docs/USAGE.md`. The eight code, test, spec and `docs/FEATURES.md` files are byte-identical. Nothing below was re-derived. ## The sizing in #930 is corrected, not inherited #930 names two blocked arms. There are three: reference video, the last-frame keyframe, and generated keyframe slots. #930 predates #920 and its author asked for the correction. This spec is the record that supersedes both counts. ## What was actually missing The appending conditioning ITEMS were already ported and gated. Two halves were not. `Ltx2ExtendKeyframesMask` mirrors `extend_keyframes_mask` (`conditioning/mask_utils.py:76-105`). Upstream's docstring makes the call an obligation of appending itself — *"Every conditioning item that appends tokens must call this, otherwise the per-token marker goes out of sync with the token sequence"* (`:83-85`) — so it lives inside `AppendTokens` rather than at the three call sites. Both `None` branches are mirrored, including the zero-fill only `marked=true` reaches (`:100-101`), so #920's arm finds it already correct. `Ltx2ClearConditioning` mirrors `clear_conditioning` (`tools.py:88-117`). Two things there are not a truncation: the denoise mask comes back **all ones** rather than sliced (`:104`), because the returned state describes a finished latent, and `keyframes_mask` is dropped entirely (`:113`). `Ltx2LatentState` grows a `keyframes_mask` field so the marker can be extended with the sequence it describes. ## Three findings that changed the design **The attention mask is not the gap, and no field is added for it.** Both appending video items pass a literal `attention_mask=None` (`keyframe_cond.py:70`, `reference_video_cond.py:88`), `update_attention_mask` returns `None` for that case (`mask_utils.py:110-143`), and the only route to a non-`None` mask is `ConditioningItemAttentionStrengthWrapper`, whose sole application site is `iclora_utils.py:169` on the IC-LoRA path. `combined_image_conditionings` — the route this engine mirrors — never wraps. A field here would be one no ported item could populate, which is the unpassed-parameter shape [`.agents/reachability.md`](.agents/reachability.md) enumerates. The refusals that cite the absent field were right to mention it and wrong to offer it as the blocker. **The sigma schedule must keep reading the target count.** Upstream fixes it twice over: the argument is `math.prod(latent.shape[2:])` of the *unpatchified* target (`schedulers.py:32`), which by construction cannot contain appended tokens, and every pipeline computes its sigmas before a state exists (`ti2vid_one_stage.py:207` passes no latent; `distilled.py:200-201` uses frozen constants). This engine's call sits **after** the conditioning block, so before this change it would have re-shifted the whole trajectory the moment anything appended. It now reads a `target_tokens` local. **The trim cannot be gated on pixels alone, so it is gated on a guard.** Appended tokens sit at the tail of a contiguous `[tokens, width]` buffer and `Ltx2VideoUnpatchify` takes a bare pointer, so an un-trimmed state would unpatchify the same head bytes and render pixel-identical frames. Correct output for the wrong reason. A `VT_CHECK` at the pointer boundary is what turns "the head happens to be right" into "the buffer *is* the target grid", and it is what makes deleting the trim a RED (mutation M3). ## The arm lifted, and the two left alone The **last-frame keyframe** arm is served, mirroring `combined_image_conditionings` (`helpers.py:272-308`): one preprocess-and-encode shared by both arms, and a branch on `frame_idx` sending 0 to `VideoConditionByLatentIndex` (`:296`) and anything else to `VideoConditionByKeyframeIndex` (`:302`). Both may be supplied at once. Nothing is added to `include/vllm.h` — `last_frame` was already on the ABI. **Reference video stays refused and its message is byte-identical.** At this base, PR #938 (`row/LTX25-IC-LORA`) is open and unmerged and `git log --grep '#923'` is empty, so `--lora` does not read the IC-LoRA scale factors and that refusal's stated cause is still true. #930's body describes the message as already rewritten onto token-append; **that is not the state of `origin/main`.** Rewording it would have shipped a refusal naming the first of two causes — the defect a sibling row nearly shipped. **Generated keyframe slots** (#920, PR #929, also open) and **reference audio** stay refused for their own reasons. ## What lands unreached, named rather than discovered `Ltx2ExtendKeyframesMask`'s **`marked=true` branch lands with a unit driver and no production caller.** The only upstream construct that passes `true` is `VideoGeneratedKeyframeSlots` (`keyframe_slots.py:121`), which belongs to the generated-keyframe-slots arm and not to this row. Every appending item ported here passes `false`. It is landed rather than stubbed because building half of `extend_keyframes_mask` is the worse option: the two `None` branches are not symmetric, and a port that mirrors one and guesses the other gets #920's arm silently wrong. Mutation M5 shows the branch is not inert — appending with `marked=true` instead of `false` is RED. Owner of the wiring: row `LTX25-GENERATED-KEYFRAMES`, issue [#920](#920). Listed under `## Owed` in the spec. Declared here per [`.agents/reachability.md`](.agents/reachability.md) `## Landing a slice that is not reached yet`. ## Evidence RED first, on the pre-row engine with the tests in place: `test_ltx2_video` FAILED, the new case throwing the last-frame refusal verbatim. That run also printed `assertions: 825 | 825 passed | 0 failed` beside `Status: FAILURE!` — the thrown-case trap, which is why the exit code is the authority throughout. The witness is on **rendered artifact bytes with a no-op control**, because `Ltx2ConditioningTrace` is filled before denoise and cannot observe the loop. A keyframe render differs from a no-keyframe render in **59773 of 91169** bytes; two different keyframes differ from each other in **334**; the same request twice is byte-identical. The control is what separates "the append reached the maths" from "the instrument is blind" — a sibling row's first attempt found every arm identical *including* its control, and without that control a blind instrument reads as a real-but-subtle effect, which is the direction that ships. Two new trace fields, `video_tokens` and `schedule_tokens`, are written *inside* the phase loop for that same reason, and the sigma claim is checked as a relation between two measured values rather than against a literal. Upstream ships **no tests** — `find /home/mudler/_git/LTX-2 -name 'test_*.py'` returns 0 across the whole repository at the pin — so nothing was ported and every case is written against an upstream anchor instead. ## Review repairs A fresh review returned FAIL on six findings. The seam itself survived: every upstream design decision checked out and the pixel witness reproduced exactly. Two claimed guarantees survived mutation and are now gated. **The all-ones restore was not gated.** `Ltx2CreateVideoLatentState` already sets every target-range mask value to `1.0`, and the append writes `1 - strength` only at the tail, which the trim drops under either implementation — so "restore all ones" and "slice" produced identical bytes over the range the test walked, and mutation M6 (slice instead of restore) was **GREEN**. The case now conditions token 0 *inside* the target with `Ltx2ConditionVideoByLatentIndex` before the append, which writes `1 - strength` at `start .. start + count` (`latent_cond.py:41`). A slice then leaves `0.4` at token 0. M6 is **RED**, and a `REQUIRE` on `mask.front()` before the trim asserts the instrument is armed rather than assuming it. **Nothing gated that the keyframe lands on the last frame.** Mutation M10 (`frame_idx` from `frames - 1` to `0`) was **GREEN**: both renders still differed from the no-op control and from each other, and the token count was identical, because a keyframe pinned to the first frame appends exactly as many tokens as one pinned to the last. The engine now asserts the first appended token's temporal position, recomputed from `frames` and `fps` rather than read back from the argument, so the two are independent expressions (`keyframe_cond.py:52-58`). M10 is **RED**. `origin/main` advanced to `c2019b0e3` (#935) during review and the branch stopped merging. Three conflicts, two with a trap: `docs/FEATURES.md`'s LTX-2.5 cell is at `MAX_CELL_CHARS` exactly, so the obvious merge lands at 226 and REDs — resolved by keeping main's complete cell and trimming only this row's own wording, to 220. And both sides had rewritten the `READER ANCHORS` line, so **neither** value was correct afterwards; it was re-derived a third time from the merged file. Every upstream `file:line` in this change was re-derived at the final tree by a needle taken from the **claim**, never read out of the cited span, and the load-bearing needles were checked for uniqueness in their files. The sweep covers **119** citations in this row's added lines — 108 explicit and 11 bare `:NN` continuations — and corrected **13**. Four of those were the review's: `tools.py:103` and `:112` in the `Ltx2ClearConditioning` declaration and in the spec, and `schedulers.py:38-39` in four places including the append-only issue-index row, which is fixed first and SHA-anchored because it could not be corrected after landing. Three were not, and two of those three are anchors written *during this repair* and caught by the sweep over its own output: - `ltx2_recipes.py:125-158` names a file that exists neither upstream nor in this tree. The distilled recipe's frozen sigmas are `distilled.py:200-201` over `utils/constants.py:17-23`. - A bare `(:100-101)` resolves against `tools.py`, the nearest file named above it, whose `:100-101` is a real and unrelated statement. It means `mask_utils.py`. The two bare continuations in `Ltx2ClearConditioning`'s declaration are spelled with their file for the same reason: the nearest name above them is `blocks.py`, and `blocks.py:104` and `:113` are both real imports. - `latent_cond.py:36-38`, written here for the M6 repair, is `stop_token` and a `clone()`. The `1 - strength` write is `:41`. **One anchor is left alone deliberately.** `latent_cond.py:38-39` is cited at eight pre-existing sites across specs, golden scripts and other rows' tests for "only `clean_latent` and `denoise_mask` are written". Those writes are `:40-41`; `:38-39` is a `clone()` and a blank line. The drift predates this row and the sites belong to other rows, so correcting them here would be scope this PR did not claim. It is named rather than left for the next sweep to rediscover. ## Gate on the rebuilt branch Rerun in full rather than inherited, on the rebased head `fd9948f14`, CPU-only Release, `-j6` build and `ctest -j4`: `CONFIGURE_EXIT=0`, `BUILD_EXIT=0`, `: error:` count **0**, `No space left` **0**, `BFD assertion` **0** (all three greps positive-controlled against a synthetic line), `ctest -N` **485**, `CTEST_EXIT=0`, `100% tests passed, 0 tests failed out of 485`. Load average 4.94 at start and 11.02 at end; 46 G free. Row suites, run directly for their assertion counts: `test_ltx2_video` 44/44 cases, 1024/1024 assertions; `test_ltx2_vae` 39/39, 3092/3092; `test_ltx2` 43/43, 4388/4388; `test_ltx2_device` 18/18, 546/546. M6 and M10 were rerun on this branch rather than carried over. **M6** — `Ltx2ClearConditioning` slices instead of restoring — `git diff --stat` one file `1 +/1 -`, BUILT with 0 compile errors, exit **1**: `38 passed | 1 failed`, four `CHECK( 0.4 == 1 )` at mask tokens 0-3. **M10** — `frame_idx` `frames - 1` to `0` — one file `1 +/1 -`, BUILT with 0 compile errors, exit **1**: `42 passed | 2 failed`, both cases THREW the temporal-position `VT_CHECK` (`0.333333` wanted, `0.000000` got). M10 prints `assertions: 923 | 923 passed | 0 failed` beside `Status: FAILURE!`, which is the thrown-case trap; the exit code is the authority. The tree was restored byte-for-byte after each — `git write-tree` back to `d937252dd0` — and rebuilt before remeasuring. `READER ANCHORS` were re-derived at the final tree and are unchanged: `756 811 907 923 925 1003 1028 1133 1174`. The `docs/FEATURES.md` LTX-2.5 support cell measures **220** characters, exactly `MAX_CELL_CHARS`, with main's `, A2V WAV` and every host and measurement qualifier intact. Checkers, exit codes captured directly: `check-doc-checkpoint` **0** over the range and **0** on each commit individually, `check-commit-trailers` **0**, `check-commit-style` **0**, `check-issue-index-append-only` **0**, `check-agent-record` **0**, `check-public-doc-tables` **0**. 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.
Retires the arms of the LTX-2.5 out-of-scope ledger that do not exist upstream, refuses the load extra that was accepted and read by nothing, and — after four rounds of review — repairs the ledger's own claim about which refusals a request can reach. 12 files, +2148/−54: spec, header, refusal messages, two public documents, and the tests that hold each claim.
Tracks #611 and #644 items D–I and N. Pattern this row is an instance of: #604. Spec:
.agents/specs/ltx25-retire-dead-arms.md. Pins:Lightricks/LTX-2 @ fd4ded7f,huggingface/diffusers @ 3a2f35d4,vllm-project/vllm-omni @ a4ea67a21.Closes #889. Closes #890. Closes #892.
#893 stays open on purpose and must not be closed by this merge: it is the
## Nothing lands deaddisclosure forLtx2Schedule, which this branch labels honestly rather than wires. #611 and #691 also stay open, with their remaining halves named at the end.The body that was here belonged to #880, and replacing it is part of this change. The repository sets
squash_merge_commit_message = PR_BODY, so this field is the landed commit message. It carried, verbatim, the already-merged body of #880 (keyframes_abs_pos_embedding) — a different row, a different issue, a different diff, 22 files that are not these 12. Landing it would have written a permanent commit message describing work already onmain. No gate can catch that: the trailer and style checkers validate the body's shape, and its shape was perfect. Recorded rather than quietly swapped, because "the body is the commit message" only protects the history if somebody checks that it describes this change.What was wrong
Ltx2UnportedPipelineFeatureis a ledger of arms this port refuses by name. Read as a whole it claimed more than was true, in five separate ways.kMultishotrefused "multishot generation" and cited "ltx-pipelines multishot entry points". No such entry point, symbol or string exists in either reference. Retired.kVideoEngineWiringsaid the end-to-end composition "is phase L7, not L5". L7 landed incefacd2d0. A refusal whose subject shipped is a false statement. Retired.kCfgParallelismwas anchored toltx-pipelines/multigpu, which contains no CFG batching. RenamedkMultiGpuParallelismand re-anchored.duration_head_pathwas accepted and read by nothing (LTX-2.5: duration_head_path is accepted and never read — a caller who supplies it silently gets the recipe default #611). A caller who pointed at a duration head silently got the recipe default. Now refused by name, with the full ten-keykKnownLoadExtrasinventory recorded and gated.The four review rounds
Every finding is written into the spec's
## Outcomerather than summarised away, because the findings are the row's subject.hadamardis not 0 hitssceneasserted trainer-only; theshotfile list offered as exhaustive at five when it is sevencfgasserted absent from both multigpu trees; a fourth form omitted (#892)kBetaSchedulerpublished as reachable with no caller (#889)docs/FEATURES.md,docs/USAGE.md, §1.6ltx2_video.cppThe first four are one defect: an absence asserted from our own vocabulary, with no positive control, three of them behind a path filter that excluded the files carrying the answer. A row whose stated purpose is retiring instances of #604 committed four of them, three into files a user or a porter reads.
The last two are a different defect and worth separating. They were not inaccurate citations. They were classification and control flow, and between them the ledger's reachable column was empty in practice while two public surfaces published two entries in it.
#889 — a refusal nothing calls
The header defines a reachable refusal as one "a caller CAN trip", and
docs/USAGE.mdpublished "Both are reachable — a render asking for either gets a refusal naming the missing piece." Neither was true ofkBetaScheduler. Its siteltx2_pipeline.cpp:199sits insideLtx2Schedule, andLtx2Schedulehas zero call sites insrc/,include/orexamples/. The engine callsLtx2SigmaScheduledirectly, and no ABI field, load extra or CLI flag carries a scheduler kind. The only driver is the unit test that constructs the enumerator by hand.§1.6 had asked whether an enumerator appears in
src/. That question's true answer is the wrong answer: acaselabel is not a caller.Upstream decides the repair, and it forbids the wiring one. At
fd4ded7f,BetaScheduleris defined atltx-core components/schedulers.py:91and constructed nowhere in the repository. All sevenltx-pipelinesentry points hard-codeLTX2Scheduler():ti2vid_one_stage.py:81,ti2vid_two_stages.py:87,ti2vid_two_stages_hq.py:90,a2vid_two_stage.py:78,t2a_one_stage.py:67,keyframe_interpolation.py:82,retake.py:96. vLLM-Omnia4ea67a21has zero hits for the name, against 81 files carryingltxas the control. Routing the engine throughLtx2Schedulewould have invented a scheduler-selection surface upstream does not have, so mirroring upstream means reclassifying the arm as a marker.The split is now derived rather than written.
test_ltx2_pipelinegains "the reachable/marker split matches the source": it walks the product tree, counts callers of each arm's entry function, and requires the message to agree in both directions — no caller demandsDECLARED, NOT REQUESTABLE, and a caller appearing later forbids it. Two positive controls ride in the same walk, plus a file-count floor, because this is an absence claim about our own tree and this row has already shipped four of those. That is the anti-tautological shape #691 asks for, applied to the beta arm; #691 stays open for the three markers that have no call site to derive from.#890 — the shadowed arm
The phase guard tested
im.upsampler_cfg.temporal_upsamplealone. Every both-flags config satisfies that too, so the two guards were an implication over one variable and this one always fired first. A caller supplying a genuine spatiotemporal checkpoint was told it is the TEMPORAL x2 upsampler and pointed at the spatial one: wrong on both counts, and pointing them at the arm they already had. It also made the ledger refusal atltx2_upsampler.cpp:465unreachable from any request — so after #889, the reachable column was empty.Narrowed to
temporal_upsample && !spatial_upsample, so a both-flags config falls through to the refusal that names the correct arm.The reviewer who found this named a real limit on their own evidence: no fixture drove a both-flags checkpoint through
LoadVideoEngine, so mutation could not separate "unreachable" from "untested", and only the static implication settled it. That hole is closed here, and closed the wayAGENTS.md## Nothing lands deadrequires — the new subcase drives the checkpoint throughLoadVideoEngine+Generate, not through a direct call toLtx2LatentUpsample.#892 — a fourth form, hidden by a path filter
The header shipped an assertion that
cfgis absent from both multigpu trees; the refusal shipped "three forms". Re-derived at the pin, with the file list as the control in the same pass:Two of the five are substantive prose at
docs/multigpu/gemma.md:103-104. The spec's grep was correct and its path filter was wrong: scoped to the two SOURCE trees, it excludeddocs/multigpu/, where the answer is written out. There is also a fourthBuilderProtocolin the directory the refusal cites —multigpu/bp_gemma_builder.py:42,BatchParallelGemmaBuilder, which partitions a prompt list across ranks.The disposition is unchanged and stronger.
gemma.md:104records that the distilled pipeline this port runs takes nonegative_promptand "runs without CFG", so the one form that would carry a CFG pair is the one upstream tells you not to use here. A reason beats an absence.Nothing lands dead: the disclosure this owes
AGENTS.md## Nothing lands deadand.agents/reachability.mdlanded in8f49ac3be(#886) while this repair was in flight, and they name #889's shape exactly: the test-only driver, where the only thing that calls the new code is the test written for it. The guide ships no checker and says why, so there is no exit code to report.Per that rule, stated here, in the commit body, and under
## Owedin the spec:Ltx2ScheduleandLtx2SchedulerKindare UNREACHED. Owned by rowLTX25-RETIRE-DEAD-ARMS, tracked by #893. This is not a staged slice awaiting a wiring wave — upstream selects no scheduler anywhere, so there is nothing to wire it to. The open decision is retire-or-keep-as-recorded-mirror, and that is a behaviour change owing its own red-first evidence, which is why this branch labels the arm honestly and does not also delete the dispatcher.Red before, green after
Ltx2Schedule callers = <none>with both controls live;DECLARED, NOT REQUESTABLEabsent from the messagetest_ltx2_pipeline42/42 cases, 2485 assertions, exit 0SPATIOTEMPORALabsent;it is the TEMPORAL x2 upsamplerandSupply the spatial upsamplerboth presenttest_ltx2_video40/40 cases, 827 assertions, exit 0three formspresent;four forms/BatchParallelGemmaBuilder/gemma.mdabsent; headercfgsentence present at offset 32030The full RED run was
test_ltx2_pipeline39/42 cases with 8 assertions failing, andtest_ltx2_videored on the new subcase.Four mutations, each of which BUILT with 0 errors before it was run — a mutation that fails to compile reads as a passing test:
temporal_upsamplealoneLtx2UpsampleVideoLatenttest_ltx2_video, and it fires the split case's positive control, which then reportsLtx2UpsampleVideoLatent callers = <none>markersuffix from the beta refusalThe tree was restored byte-for-byte after each, verified by
sha256sum -c.One consequence worth recording, because it cost a build cycle: the header may not QUOTE the retired sentence while explaining it. A text gate matches text and cannot tell a quotation from a claim. The corrected note describes the old sentence instead of reproducing it, and says so in the comment.
Keyed records, edited by key
docs/FEATURES.mdanddocs/USAGE.mdare keyed records. Exactly two FEATURES rows change; the other 365 lines are byte-identical, verified by sha256 of the filtered file, with the filter's own line count (367 → 365 on both sides) as the positive control.docs/FEATURES.md:165"Temporal x2 ups gated, UNDRIVEN" is untouched, verified by sha256 of that line againstHEAD. Indocs/USAGE.mdonly one paragraph moves: lines 1–1956 hash identically, and the tail hashes identically at a 5-line offset..agents/issue-index.mdgains four rows and loses none —git diff --numstatreads4 0, against a positive control showing the same tool reporting11 6fordocs/USAGE.md.scripts/check-issue-index-append-only.pyexits 0.Every
file:lineanchor was re-derived at this tree and asserted unique, not merely present. Three were correct:ltx2_upsampler.cpp:465,ltx2_pipeline.cpp:199,ltx2_pipeline.cpp:191. Two had moved with the merge and are now named by symbol instead of by line, becauseltx2_video.cppmoves on every merge and three anchors in this row went stale inside one branch. The nine derived READER ANCHORS moved five lines when98f8e046dlanded; the gate that derives them caught it, which is what it was built for.Gate
CPU, this box, clean configure into a fresh
build/. Shared and busy: another session was running its ownctest -j 8concurrently and load average sat between 11 and 84 during the run.grep -c ': error:'over the build log = 0.No space left= 0 andBFD assertion= 0, against positive controls of 603Building CXXand 478Linking CXXlines, so the log was searchable and carries no ENOSPC. The build ended[1083/1083].df -h /32G free (93%) after the build.ctest -N= 477, which ismain's count: this branch registers no new ctest entry.git diff <merge-base>..HEAD -- tests/CMakeLists.txt | grep '^+' | grep -cE 'vllm_cpp_add_test|add_test\('= 0, against a positive control of 1 for07457f87c, which did add one. The CMake change is threetarget_compile_definitionsblocks and their comments.Full suite: 100% tests passed, 0 tests failed out of 477, 250.14 s. Two did not run and neither belongs to this row:
test_modelopt_mixed_precision_checkpointandtest_voxtral_e2e, bothSkipped. The same ENOSPC grep over the ctest log is 0 against a positive control of 475Passedlines.No known-red fired in this run, including
test_cpu_x86_llamacpp_floor(#618) despite the load. Read that as this branch not adding one, not as those issues closing.scripts/agent-preflight.shreports the seven CI-wiring failures that are pre-existing onmain(check-release-binary-contract,check-release-workflow,check-test-registrationand their four suites; root cause #873, fix in flight as #878). Proven pre-existing rather than asserted:git diff origin/main HEADover every input those checkers read —scripts/check-test-registration.py,scripts/check-release-binary-contract.py,scripts/check-release-workflow.py, their four test scripts, and.github/workflows/— is empty, against a positive control where the same command reportsdocs/FEATURES.mdandsrc/vllm/multimodal/ltx2_video.cpp.check-commit-style.py --range <merge-base>..HEADandcheck-commit-trailers.py --range <merge-base>..HEADboth exit 0. The trailer gate initially failed on the twogit mergecommits, which carried no trailer block —rev-listincludes merge commits and the checker has no exemption for them. Repaired by redoing the merge with an authored message rather than by exempting anything, andea6b01f1fremains an ancestor of this head, so the push is a fast-forward and nothing was force-pushed.Not in scope, still owed
Constructing a duration head (#611; its user-visible half, silent substitution of the recipe default, is closed). The retire-or-keep decision on
Ltx2Schedule(#893). The anti-tautological gate for the three markers that have no call site to derive from (#691)..agents/specs/ltx-2-5.md§2 "Out" still listsmultishotand is operator-owned (#692).FOLLOWING_AGENTS_PROTOCOL
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]