Skip to content

feat(LTX25-PHASE-LORA): the adapter set belongs to a phase, and the DiT moves between them (#1118) - #1140

Merged
localai-bot merged 8 commits into
mainfrom
row/LTX25-PHASE-LORA
Aug 17, 2026
Merged

feat(LTX25-PHASE-LORA): the adapter set belongs to a phase, and the DiT moves between them (#1118)#1140
localai-bot merged 8 commits into
mainfrom
row/LTX25-PHASE-LORA

Conversation

@localai-bot

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

Copy link
Copy Markdown
Collaborator

Closes #1118.

Ltx2PhaseRecipe::loras carries upstream's per-stage adapter set, and
A2VidTwoStageRecipe gives stage 1 kNoAdaptersloras=tuple(loras) at
a2vid_two_stage.py:107 against (*tuple(loras), *tuple(distilled_lora)) at
:114, read at Lightricks/LTX-2 fd4ded7f. Until now dit_options.loras was
pushed once at load and every phase of every recipe ran the same fused weights,
so stage 1's guided schedule ran against base + distilled where upstream runs it
against the base alone. That rendered: the frames differed while the frame
count, the shapes and the sample rate did not, which is why nothing caught it.

Upstream holds ONE transformer, not two

The premise that upstream pays two resident weight sets is false, and correcting
it is what settled the design. Both DiffusionStage.from_checkpoint calls name
the same model_paths.transformer()a2vid_two_stage.py:104 and :116,
ti2vid_two_stages.py:137 and :148 — and differ only in the adapter tuple. So
upstream pays a second MATERIALIZATION, not a second model.

Ltx2RebindDitLoras is exactly that. It re-materializes from the pristine file
the tensors an adapter targets, fuses the phase's set back in, and writes into
the buffer the view already points at, so no pointer moves, Ltx2DitWeights
stays valid without re-binding, and no second weight set ever exists. Peak
residency rises by one tensor plus the adapter's own A/B factors.

Three shapes were costed and the third chosen:

Shape Resident memory Exactness Verdict
A second resident Ltx2DitWeights doubles the DiT (18.7 GB nvfp4 / 21.0 GB fp8 / ~39 GB bf16) exact rejected — heavier than the reference, and one GB10 has 119 GB with no swap
Unfused runtime LoRA + the adapter Wx + s*B(Ax) vs round_bf16(W + s*BA)x rejected — a rounding divergence AND a different GEMM path
Re-materialize the targeted tensors at the phase boundary none exact CHOSEN — it is what upstream does

The base is reconstructed by RE-READING it, never by subtracting the delta:
round_bf16(round_bf16(W + d) - d) is not W.

The field is a SET, not a boolean

Upstream needs two placements: stage 2 only for TI2Vid, A2Vid and Keyframe
(ltx-pipelines/CLAUDE.md:48), both stages for HQ and DFR (:49, :50-51).
Stage 1 kNoAdapters with stage 2 defaulted gives the first; both defaulted
gives the second. Two enumerators are the COMPLETE space while the adapter arity
is capped at one by a gated refusal (ltx2_lora.h:167-172). kAllAdapters is
the default, so distilled_two_stage, dfr, retake, one_stage, res2s and
t2a_one_stage keep the behaviour they were gated with — upstream-correct,
since distilled.py:131 builds one stage set.

Per-phase STRENGTH is deliberately absent: ti2vid_two_stages_hq.py:92-101
needs one, no recipe here would set it, and landing a branch nothing can select
is what ltx2_lora.h:41-44 already argues against. Owed to #921.

The gate that distinguishes per-phase from load-time fusion

ltx2 a2vid: the distilled adapter rides stage 2 ALONE, driven entirely through
LoadVideoEngine + Generate with the documented pipeline_kind, lora_path,
lora_strength and max_phase load extras:

  • stage 1 alone (max_phase=0), strength 1.0 vs 0.0: 0 of 63809 artifact
    bytes move. The adapter is not on stage 1.
  • both stages, the same two strengths: 11 of 146753 bytes move. The adapter
    reaches stage 2.

Both halves are load-bearing. The first REDs on today's load-time fusion; the
second REDs on an engine that simply stopped fusing. A gate asserting only "a
LoRA was applied" passes on the defect. Strength 0 is the control rather than
"no adapter", because requires_distilled_lora refuses an a2vid load carrying
no lora_path.

The loader side gates exactness byte-for-byte against a fresh load in both
directions, including the widened-to-f32 host arm the CPU parity forward runs.

Mutations

Every row prints four facts, because each has produced a false green here before.

Mutation diff BUILT compile_err exit verdict
M1 drop stage 1's kNoAdapters 1 file, -1 yes 0 1 RED
M2 delete the rebind call from the phase loop 1 file, +1/-3 yes 0 1 RED
M3 delete the load-time fuse site (standing reachability mutation) 1 file, -1 yes 0 1 RED
M4 rebind that does not restore the base 1 file, +1/-1 yes 0 1 RED
M5 make the phase scope field inert 1 file, +1/-1 yes 0 1 RED

M4's first anchor was not unique and silently mutated Ltx2StreamDitToDevice
instead, presenting as a compile error about the code under test; the harness now
asserts each anchor occurs exactly once.

Reachability

M3 is the proof: deleting the production call site REDs test_ltx2_video (6
cases). The path is include/vllm.h -> LoadVideoEngine -> Generate, and
ltx2-gen --pipeline-kind a2vid_two_stage --lora ... --audio-path ... is the
same two calls through the ABI. /v1/videos cannot drive it, because
VideoGenParamsFromRequest writes no gen.extras (#928) — stated so the reach
claim excludes it.

The IC-LoRA refusal is NARROWED, not retired

Its reason 2 — "this engine holds one DiT, fused at load, that every phase runs"
— is now false, and both the comment and the Fail text say so and name what
closed it. Reason 1, the reference clip's pixel path
(iclora_utils.py:112-117, :87-89, :144-148), is untouched by this row, so
the refusal stands. Retiring it here, as the dispatch proposed, would have
shipped an arm whose geometry nothing supplies.

Gate

cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DVLLM_CPP_CUDA=OFF

CONFIGURE_EXIT 0, BUILD_EXIT 0, : error: count 0, ctest -N 503,
CTEST_EXIT 8, 99% tests passed, 1 tests failed out of 503. The one failure is
test_serve_low_tools (#428, load-dependent); it passes in isolation, measured
rather than assumed. No space left 0 and BFD 0, each with a positive control
in the same log (505 of 506 build lines matched Building|Linking; 500 Passed
lines in the ctest log). Load average 73.8 at build, 47.1 at rerun; 13 GB free.

No GPU and no real-weights result is claimed: this is a weight-lifetime seam and
the CPU goldens are its correct gate. A real-weights comparison against
upstream's own render is still owed. It is no longer blocked on an artifact:
the distilled adapter and the full -dev- transformer have both since landed on
the NAS and their headers were read (see the review repair below). What is owed
is the RUN.

Spec: .agents/specs/ltx25-phase-lora.md, committed in 86422587f before any
product code.

Review repair (2026-08-17)

A fresh review returned PASS with three non-blocking findings, all records. They
are repaired in 17b211384, 10d9d010e and 08ea64b15. No behaviour changed:
a spec ## Outcome, two header comments, one source comment, one docs/USAGE.md
section and one new issue.

THE HEADLINE GATE'S MARGIN IS ONE BYTE. "ltx2 a2vid: the distilled adapter
rides stage 2 ALONE" has two halves, and the review's mutations measured both.
At head, unmutated: stage 1 alone moves 0 of 63809 artifact bytes, both
stages move 11 of 146753, SUCCESS! over 2420 assertions. Deleting
stage1.loras = kNoAdapters moves stage 1 to 1 of 63809 and reds
CHECK(s1_differing == 0). So the assertion that catches this row's own defect
catches it by 0.0016% of the artifact. It cannot go falsely RED, because the
render is deterministic. It can go falsely GREEN: a fixture change to the block
count, the 2-step schedule, the sigma table or the PPM's 8-bit quantization
could take that 1 to 0. The other half carries 11 and reds under "stopped fusing
altogether", so the pair does not fail open together. Both margins and all three
mutation counts are now in the spec's ## Outcome, which the row also owed for
reaching DONE.

PER-PHASE STRENGTH NEEDS MORE THAN A FIELD, and #921 is CLOSED.
Ltx2RebindDitLoras early-returns on currently_fused == fuse, and its header
calls that a no-op it detects itself. The state is a BOOLEAN, so it means
"already fused" and never "already fused at this strength". HQ is stage 1 at 0.25
and stage 2 at 0.5 (ti2vid_two_stages_hq.py:92-101, :154, :165; defaults at
utils/args.py:1174-1184) with BOTH stages fused, so that early return would
no-op the transition and stage 2 would silently render at stage 1's strength.
The trap is now written beside the early return. The review named #921 as the
inheriting owner; #921 was closed as completed the same day by
LTX25-RES2S-LOOP (4d7748646, PR #1125), which correctly scoped the distilled
LoRA out but did not list it under its own ## Owed — so the debt outlived its
owner. #1144 is filed for it, the spec and both headers point there, and a
forwarding comment is left on #921. Recorded with it: res2s_two_stage already
runs both stages at strength 1.0 where upstream runs 0.25/0.5, pre-existing and
unstated until now, which is why #1144 is a bug.

THE ARTIFACTS ARRIVED. The ## Owed bullet said the real-weights comparison
needs an adapter find /mnt/nas_share/checkpoints -iname '*lora*' returns
nothing for. That control now returns two. Headers read on the files, not copied
from a model card: ltx-2.5-22b-distilled-lora-450-bf16.safetensors,
8,899,889,568 bytes, 3320 BF16 tensors = 1660 lora_A/lora_B pairs, rank and
alpha 450, model_version 2.5.0, data end == file size; and
ltx-2.5-22b-dev-transformer-bf16.safetensors, 42,018,190,584 bytes, 4349
tensors, 21.004 B params, BF16 4059 / F32 290, model_version 2.5.0,
keyframes_abs_pos_embedding present, data end == file size.

Also folded in, so nobody derives them twice: the f32-widen branch's direct write
is unreachable with a device queue; contract drift between load and rebind cannot
occur; after a max_phase = 0 render the reference refusal prints "no adapter
was supplied" because lora_fused_tensors doubles as the state bit, which is
message-only on a path that refuses anyway. The phase-loop comment claimed a
two-stage render pays one rebind; it pays two, and docs/USAGE.md now says so
and says the cost is UNMEASURED.

One gate is RED and it is not hidden. check-doc-checkpoint.py classifies
any include/vllm/ path as user_usage and demands docs/USAGE.md in the SAME
commit, by path, without reading content. 17b211384 and 10d9d010e changed
only COMMENTS in two headers and carried no docs/USAGE.md, so both fail that
gate per-commit. That is a real rule, deliberately per-commit because a
diff-scoped range is never re-covered. Repairing it in place needs a rewrite of
two pushed commits and this session may not force-push, so it is reported rather
than hidden. 08ea64b15 carries the owed docs/USAGE.md section, and the
squash-merge commit was simulated with git commit-tree and checked: it exits 0.
The red is on the pull-request lane only.

No build was run for the repair: the change is comments and prose, and no build
can move a doctest MESSAGE count. READER ANCHORS was re-derived with a
faithful port of the test's own walk and is unchanged at
823 833 834 896 992 1008 1043 1134 1159 1264 1305 1347 1349; the port was armed
first against a one-line insertion and reported MISMATCH at exit 1.
check-public-doc-tables.py, check-issue-index-append-only.py,
check-agent-record.py, check-commit-style.py and check-commit-trailers.py
all exit 0, and the first two were each armed and refused at exit 1 before the
tree was restored byte-for-byte.

FOLLOWING_AGENTS_PROTOCOL

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

mudler added 3 commits August 17, 2026 14:08
…e load (#1118)

Four upstream pipelines build two `DiffusionStage`s from one checkpoint and give
them different adapter sets — `a2vid_two_stage.py:107` against `:114`,
`ti2vid_two_stages.py:140` against `:151`, `ti2vid_two_stages_hq.py:154` against
`:165`, and `ic_lora.py:108` against `:119`, all read at Lightricks/LTX-2
`fd4ded7f`. This engine has exactly one placement: `dit_options.loras` is pushed
at `ltx2_video.cpp:831` and nowhere else, so every phase of every recipe runs the
same fused weights.

The spec costs three shapes and chooses the third. A second resident
`Ltx2DitWeights` doubles the DiT and is not viable on one GB10, which has no
swap and no OOM line. Unfused runtime LoRA is `Wx + s*B(Ax)` where upstream is
`round_bf16(W + s*BA)x`, so it would change every arm's numerics to serve one
recipe. Re-materializing the affected tensors at the phase boundary is exact and
costs no resident memory, and on this fleet wall-clock is not the constraint that
reboots the box.

Committed before the implementation so the order proves the spec came first. The
proving consumer is `a2vid_two_stage`, not the IC-LoRA refusal the dispatch
proposed: that refusal gives two reasons, and its first one — the reference
clip's pixel path — is untouched by this row.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
…iT moves between them (#1118)

`Ltx2PhaseRecipe::loras` carries upstream's per-stage adapter set, and
`A2VidTwoStageRecipe` gives stage 1 `kNoAdapters` — `loras=tuple(loras)` at
`a2vid_two_stage.py:107` against `(*tuple(loras), *tuple(distilled_lora))` at
`:114`. Until now `dit_options.loras` was pushed once at load and every phase of
every recipe ran the same fused weights, so stage 1's guided schedule ran against
base + distilled where upstream runs it against the base alone. That rendered:
the frames differed while the frame count, the shapes and the sample rate did
not, which is why nothing caught it.

UPSTREAM HOLDS ONE TRANSFORMER, NOT TWO. Both `DiffusionStage.from_checkpoint`
calls name the same `model_paths.transformer()` (`:104` and `:116`,
`ti2vid_two_stages.py:137` and `:148`) and differ only in the adapter tuple, so
what upstream pays is a second MATERIALIZATION rather than a second resident
model. `Ltx2RebindDitLoras` is that: it re-materializes from the pristine file
the tensors an adapter targets, fuses the phase's set back in, and writes into
the buffer the view already points at, so no pointer moves and no second weight
set ever exists. A second resident `Ltx2DitWeights` would have been a heavier
architecture than the reference and would not fit one GB10; unfused runtime LoRA
would be `Wx + s*B(Ax)` against upstream's `round_bf16(W + s*BA)x`, a rounding
divergence and a different GEMM path.

The rebind reconstructs the base by RE-READING it, never by subtracting the
delta: `round_bf16(round_bf16(W + d) - d)` is not `W`, and the loader gate
compares byte-for-byte against a fresh load in both directions so that
implementation fails.

The scope field is a SET and not a boolean because upstream needs two
placements: stage 2 only for TI2Vid, A2Vid and Keyframe
(`ltx-pipelines/CLAUDE.md:48`), both stages for HQ and DFR (`:49`, `:50-51`).
Two enumerators are the complete space while the adapter arity is capped at one.
`kAllAdapters` is the default, so `distilled_two_stage`, `dfr`, `retake`,
`one_stage`, `res2s` and `t2a_one_stage` keep the behaviour they were gated
with, which is upstream-correct since `distilled.py:131` builds one stage set.

The reference-conditioning refusal gave two reasons and the second is now false;
it says so and names what closed it, keeping reason one, the reference clip's
pixel path, which this row does not touch. The refusal therefore stands.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
…is the next row's trap (#1118)

Three non-blocking findings from the fresh review of #1140, all of them records.
No behaviour changes: a spec `## Outcome`, one header comment and one source
comment.

THE HEADLINE GATE'S MARGIN IS ONE BYTE. "ltx2 a2vid: the distilled adapter rides
stage 2 ALONE" has two halves, and reverting to fusion at load moves exactly 1
of 63,809 artifact bytes — 0.0016%. `CHECK(s1_differing == 0)` cannot go falsely
RED, because the render is deterministic and 0 is 0. It can go falsely GREEN: a
fixture change to the block count, the 2-step schedule, the sigma table or the
PPM's 8-bit quantization could take that 1 to 0, and the gate would then pass on
the defect it exists to catch. The other half carries 11 of 146,753 and reds
under "stopped fusing altogether", so the pair does not fail open together —
which is why this is recorded rather than repaired. Both margins and the three
mutation counts now sit in the spec's `## Outcome`, which the row also owed for
reaching `DONE`.

PER-PHASE STRENGTH NEEDS MORE THAN A FIELD, and the header comment as written
points the next reader the wrong way. `Ltx2RebindDitLoras` early-returns on
`currently_fused == fuse` and the header calls that a no-op it detects itself.
The state is a BOOLEAN, so it means "already fused" and never "already fused at
this strength". HQ is stage 1 at 0.25 and stage 2 at 0.5
(`ti2vid_two_stages_hq.py:92-101`, `:154`, `:165`; defaults at
`utils/args.py:1174-1184`) with BOTH stages fused, so that early return would
no-op the transition and stage 2 would silently render at stage 1's strength.
#921 therefore needs `bool fuse` to become a type carrying a strength AND
`Ltx2DitCheckpoint` to record WHICH state is applied. Written beside the early
return, in the spec, and on #921. Recorded with it: `res2s_two_stage` already
runs both stages at 1.0 where upstream runs 0.25/0.5 — pre-existing, not
worsened here, and unstated until now.

THE REAL-WEIGHTS BULLET WAS OUT OF DATE. It said the comparison needs an adapter
that `find /mnt/nas_share/checkpoints -iname '*lora*'` returns nothing for. That
control now returns two, including the one this row needs:
`ltx-2.5-22b-distilled-lora-450-bf16.safetensors`, 8,899,889,568 bytes, 1660
A/B pairs at rank 450, `model_version` 2.5.0. The full/dev transformer has since
completed as well, 42,018,190,584 bytes, 4349 tensors, 21.004 B params, BF16
4059 / F32 290, `keyframes_abs_pos_embedding` present, data end == file size.
Both headers were read rather than assumed. So what is owed is the RUN, not the
artifacts.

The phase-loop comment claimed a two-stage render pays exactly one rebind. It
pays two — load fused, phase 0 off, phase 1 on — and each re-opens the adapter
and reads every A/B factor pair. That cost stays UNMEASURED and a later
performance row owns it; saying so beats a comment that undercounts it.

Also folded in, from the review's "checked and fine" list, so nobody derives
them again: the f32-widen branch's direct write is unreachable with a device
queue because `Ltx2StreamDitToDevice` refuses `widen_to_f32` by name; contract
drift between load and rebind cannot occur because
`Ltx2AdoptDeclaredDitParams` refuses unless names and shapes are identical; and
after a `max_phase = 0` render the reference refusal prints "no adapter was
supplied" because `lora_fused_tensors` doubles as the state bit — message-only,
on a path that refuses either way.

No build. The change is comment and prose, and no build can move a doctest
`MESSAGE` count. `READER ANCHORS` was re-derived with a faithful port of the
test's own walk and is unchanged at `823 833 834 896 992 1008 1043 1134 1159
1264 1305 1347 1349`; the port was armed first against a one-line insertion and
reported MISMATCH at exit 1. `check-public-doc-tables.py`,
`check-issue-index-append-only.py`, `check-agent-record.py`,
`check-doc-checkpoint.py` and `agent-preflight.sh` all exit 0, and the first was
armed with an added prose line and refused at exit 1 before the file was
restored byte-for-byte.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
mudler added 2 commits August 17, 2026 15:58
…ebt gets an open owner (#1144)

The repair one commit back wrote the per-phase strength trap into
`ltx2_loader.h` and this row's `## Owed` and said the note would also go on #921,
which the fresh review named as the owner. #921 is CLOSED. It was closed as
completed on 2026-08-17 at 12:28Z by `LTX25-RES2S-LOOP` (`4d7748646`, PR #1125),
which landed the res_2s sampler four hours before this row's head.

That row was right about its own scope: it names "the distilled LoRA per stage"
as out of scope and unchanged by it. What it did not do is list the item under
its own `## Owed`, so when the issue closed the debt outlived its owner. An
`## Owed` bullet pointing at a closed issue does not own anything; it only looks
like it does, and `check-agent-record.py` cannot see the difference because
GitHub holds the open/closed state and the index deliberately does not.

So #1144 is filed and this points at it: the spec's two strength bullets, the
`Ltx2RebindDitLoras` header, and `Ltx2PhaseLoraScope`'s "NO PER-PHASE STRENGTH,
deliberately" note, which was the one pointer at a closed issue sitting in a
shipped header. The two "#921 when this was written" mentions in Scope and the
port map keep the original number beside the new one, because the row genuinely
was bounded by #921 on the day it was written and rewriting that would be
rewriting history rather than the record.

#1144 is a `bug` and not an enhancement, and the reason is the second half of
the finding: `res2s_two_stage` — this tree's port of `TI2VidTwoStagesHQPipeline`
— sets `loras` on neither phase, so both take `kAllAdapters`, and the load
carries ONE strength (`lora_strength` absent is 1.0). It therefore runs both
stages at 1.0 where upstream runs 0.25 and 0.5 (`utils/args.py:1174-1184`,
placed at `ti2vid_two_stages_hq.py:92-101` and handed to `:154`, `:165`). That
is a live divergence on a shipped arm, pre-existing and not worsened by this
row, and it was unstated anywhere until now. It is not fixed in flow because the
fix changes a seam signature and a checkpoint's state representation, which
needs its own spec and its own fresh review.

`.agents/issue-index.md` was taken from `origin/main` wholesale and the one row
re-appended, per the record rule for a union-merged append-only file. Verified
after writing: `origin/main`'s bytes are an exact prefix of the result, the row
list is main's 315 plus exactly one, all 316 ids are unique, and no row that was
on this branch before is lost.

No build. `READER ANCHORS` re-derived unchanged at `823 833 834 896 992 1008
1043 1134 1159 1264 1305 1347 1349` with the same armed port of the test's own
walk. The two source-text gates over `ltx2_pipeline.h` match flattened comment
TEXT and are explicitly "derived rather than pinned to a line number", and
neither of the strings they hold is touched here.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
…r, and which adapter --lora wants (#1118)

Two facts a reader of the a2vid section can act on, both new with #1118 and
neither of them stated anywhere until now.

THE COST. Moving one DiT between two adapter states is paid in wall-clock rather
than memory: a two-stage render does TWO rebinds, one per phase boundary, each
re-opening `--lora` and reading every `lora_A`/`lora_B` factor pair before
re-materializing the tensors they target. The DiT is left in stage 2's state, so
the next render pays the same two. No number is published, because this recipe is
gated on reduced fixtures and nothing has timed the boundary on real weights —
saying so is the point, since the alternative is a reader assuming the seam is
free.

WHICH ADAPTER. The sample command has named
`ltx-2.5-22b-distilled-lora-450-bf16.safetensors` since #1117 without saying how
to know you have it. It is now pinned by CONTENT — 8,899,889,568 bytes, 3320 BF16
tensors forming 1660 `lora_A`/`lora_B` pairs, `lora_rank` and `lora_alpha` both
450, `model_version` 2.5.0 — because a LoRA repository can be re-quantized in
place under an unchanged filename, which is exactly why AGENTS.md asks for the
bytes and not the name. The header was read on the artifact, not copied from a
model card. The IC-LoRA is named beside it as the file this is NOT, with its own
size, and the page says plainly that nothing in the engine tells them apart:
`requires_distilled_lora` refuses a load carrying no `--lora` and that is the
whole of its check.

ON THE SHAPE OF THIS SERIES, because the reader of `git log` deserves it rather
than a puzzle. `check-doc-checkpoint.py` classifies any `include/vllm/` path as
`user_usage` and requires `docs/USAGE.md` in the SAME commit, by path and
without reading content. The two commits before this one changed only COMMENTS
in two headers and carried no `docs/USAGE.md`, so both fail that gate
per-commit. That is a real rule and they really broke it: the obligation is
per-commit by design, because a diff-scoped range is never re-covered later.
Repairing it in place would mean rewriting two pushed commits, and this session
may not force-push, so the red is left standing and reported rather than
hidden. `main` is squash-merge only, so the commit that lands carries this file
and satisfies the gate on the branch that matters; the per-commit red is on the
pull-request lane alone.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
mudler added 3 commits August 17, 2026 16:10
GitHub reported the pull request CONFLICTING while `git merge-tree --write-tree
origin/main HEAD` exited 0 and produced a clean tree, `c553ea673`. That
disagreement is the union-driver artifact: `.agents/issue-index.md` carries
`merge=union` in `.gitattributes`, the forge's mergeability probe does not apply
it, and this branch took `origin/main`'s copy of that file wholesale before
appending #1144's row — so both sides moved the same append-only file and the
probe calls it a conflict. Merging locally resolves it with nothing to
hand-resolve: the two commits arriving from `main` are a ROCm decode arm and a
GPU-lease policy row, and neither touches a path this branch edits.

Verified after the merge: the merged `.agents/issue-index.md` is `origin/main`'s
bytes plus exactly one appended row, every issue id is unique, no row is edited
or removed, and `check-issue-index-append-only.py` exits 0 over the range.

NOT BUILT. A clean `merge-tree` is not a merge-tree that compiles, and that
distinction has cost this project before. It is not paid here because this branch
adds comments and prose only, and the merged code from `main` is `main`'s own
gated tree.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
`main` advanced while this row was in review and repair. The index was rebuilt
from `origin/main` wholesale with this branch's single row re-appended, never
from the union driver, and verified: byte-identical prefix, 316 rows, 316 unique
ids.

The row's own content is unchanged since the reviewed head `851b15da7`, which
passed at 502 of 503 with `test_async_llm` (#294) green in isolation. Everything
committed since is records and comments: the `## Outcome` recording that the
stage-1 half of the gate detects its defect by one byte in 63,809, the
re-pointing of the per-phase-strength debt at #1144 because #921 had already
closed, and the USAGE content the row owed.

FOLLOWING_AGENTS_PROTOCOL

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

`04b58bf6a` (#1078) landed a gate that counts the issue index's CELLS, and
`f6f1af0b4` (#1147) a lease-runtime record. The only overlap with this row is
`.agents/issue-index.md`, and it was rebuilt from `origin/main` wholesale with
this branch's single row re-appended -- never from the union driver -- then
verified: byte-identical prefix, 318 rows, 318 unique ids.

The row's product content is unchanged since the reviewed head `851b15da7`.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
@localai-bot
localai-bot merged commit 4ae0f54 into main Aug 17, 2026
11 of 21 checks passed
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.

LTX-2.5: LoRA adapters fuse once at load, so no recipe can put the distilled adapter on stage 2 alone

2 participants