Muting both image loaders is a legal way to run this — the optional inputs vanish
from the prompt and core reads that as text-to-video — but with no image to match,
the canvas came from ratio arithmetic and landed on 768x1312. Legal, and 41 rows
short of the canvas the model itself ships with, for no reason anyone could
explain.
Each match tier now names its own portrait fallback: 768x1344, 480x832, 352x608.
Tests assert all three are legal, portrait, and that full quality is the model's
own default rather than whatever the arithmetic produces.
The node cannot ask the MODEL object which LoRAs it carries — they are baked into
its weights before it arrives — so the info line reads the model path out of the
workflow, the same way the checkpoint guard does. It names each active LoRA with
its strength and counts the switched-off slots, because a bypassed slot looks
almost identical to a live one on the canvas and 'why doesn't my character look
right' is usually exactly that.
Writing it exposed a real bug in the checkpoint guard: it walked ONE hop up the
model path, so with a LoRA loader in between it read the LORA's filename as the
checkpoint. On a correct graph that produced 'family unproven' at best and a
false MISMATCH REFUSAL at worst — a hard stop on a workflow with nothing wrong
with it. It now walks the whole chain and takes the loader at the far end.
138 offline checks, including the chain walk, a cycle that must not hang it, and
the ref2va refusal still firing THROUGH an active LoRA.
Two problems with the first menu, both found by using it.
MATCHING. Core fits your image to the canvas, not the other way round, and it
fits the first frame by STRETCHING it. So a landscape photo in a portrait canvas
came out visibly squashed, with only a log line to say so. The menu now leads
with 'match my image', which takes the ASPECT from your frame and only the SIZE
from the menu: the fit becomes a no-op, nothing is cropped, and the pixels are
resampled once instead of twice. Same arithmetic as the official template's
GetImageSize -> ResolutionSelector chain, done inside the node so the canvas
stays at nine nodes. With no image supplied it falls back to portrait AND SAYS SO.
SIZE. Every size in the first menu was ~1.0 MP, which is the model's maximum
canvas, not its working default — the official template renders at 0.4 MP and
tabulates 0.2 MP as an ordinary choice. A measured 5 s render at 1.03 MP and 20
steps took 14 minutes, so shipping only the expensive end was a real cost to
anyone trying an idea. Fast (~0.4 MP) and draft (~0.2 MP) now exist at both ends
of the menu, and the 0.2 MP 16:9 case lands exactly on the template's 608x352 —
a test asserts it, which is how this stays the same arithmetic rather than an
invention.
Steps default 20 -> 14. Twenty came from the template's scheduler and nothing
measured; this sampler converges early, and the same repo ships 4- and 8-step
turbo LoRAs, which says the tail is cheap. Anyone who wants the old number types
it.
Additive: the option lists grew, inputs did not. 125 offline checks pass.
One node per capability and no mode dropdown, because a mode widget spanning two
sampling paths is a mistake this line has already paid for. Shared plumbing sits
at module scope so a second node cannot drift from this one.
Built on ComfyUI core alone — no second pack to install, which is the whole
premise. Core's own fl2va node supplies the conditioning and keyframes; the
sampling and the two decodes mirror core's SamplerCustomAdvanced, VAEDecode and
vae_decode_audio, and say so where they do, so they can be diffed against the
source rather than trusted.
What it refuses to offer: sampler, scheduler, cfg, sigma shift, negative prompt.
What it guards: the checkpoint family (fl2va vs ref2va, read out of the workflow
because nothing in the MODEL object carries the filename), the canvas — core does
NOT round the output canvas on this path, so the menu is the only guard — and
both frames' fitting, which core does asymmetrically and silently.
66 offline checks in tests/test_offline.py, no pytest and no GPU needed. They
caught the canvas claim above, which an earlier draft had backwards.