Skip to content

feat: add vse-cut-list example witnessing the 4.5-to-5.x sequencer API rename#73

Merged
TMHSDigital merged 1 commit into
mainfrom
feat/vse-cut-list-example
Jul 19, 2026
Merged

feat: add vse-cut-list example witnessing the 4.5-to-5.x sequencer API rename#73
TMHSDigital merged 1 commit into
mainfrom
feat/vse-cut-list-example

Conversation

@TMHSDigital

Copy link
Copy Markdown
Owner

Summary

Ships examples/vse-cut-list/ — the gallery's first sequencer example and the ROADMAP pool's "VSE sequences-to-strips witness" (pool entry removed, two newly identified candidates restocked). It witnesses the 4.5 LTS → 5.x sequencer API rename, the single most common way AI-generated VSE code dies on a modern Blender: every tutorial-era snippet does sequence_editor.sequences.new_effect(..., frame_end=...), and on 5.x that path is gone twice over.

API contracts witnessed

  • Accessor rename — 5.x: sequence_editor.sequences raises AttributeError, only .strips exists. 4.5: both accessors exist and see the same strips (transition bridge asserted).
  • Creation signaturestrips.new_effect(...) ends a strip with frame_end= on 4.5, length= on 5.x; the wrong kwarg raises TypeError on each side (asserted, not assumed). 5.x also rejects the removed TRANSFORM effect type; per-strip strip.transform is the cross-version placement API.
  • Frame reads — closed-form end-exclusive spans on canonical accessors: frame_final_* on 4.5; left_handle/right_handle/duration on 5.x, where frame_final_* is deprecated (removal announced for 6.0) and asserted still equal, with the RNA is_deprecated flag checked per side.
  • Effect wiringinput_1/input_2 (not input1) on both versions, authored order, cross clamped to exactly the source overlap.
  • Scene strip — 4-arg new_scene(...) on both; default span == source scene frame range; sources a separate Stage scene.
  • Round-trip — spans, channels, colors, wiring, text, and pixel-unit transforms (tol 1e-3) survive save_as_mainfileopen_mainfile.
  • Compositing (--check-pixels) — 96×54 render: cell centers carry strip colors (tol 0.1), cross cell is a true mid blend (strictly between sources per channel), margin matches neither cross source.

Hazards discovered while authoring (witnessed in code + README)

  • GAMMA_CROSS asked to outlast the input overlap is silently clamped (request 9 over (25,33), get (25,33)).
  • A scene strip pointing at its own scene renders transparent (alpha 0) — feedback loop; first-draft "studio" was the viewer showing alpha as grey.
  • Effect strips consume their inputs — inputs never composite on their own channel, and the effect's transform applies over theirs; consumption requires the effect above the inputs (GC below T1/T2 let T2 paint the whole wall teal).
  • An empty bpy_prop_collection is falsy — se.strips or se.sequences silently picks the legacy accessor on an empty timeline.

Falsification evidence (break-the-contract probes, all on the shipped script)

Probe Result
Legacy se.sequences.new_effect(frame_end=...) on 5.1.1 AttributeError: 'SequenceEditor' object has no attribute 'sequences'
new_effect(frame_end=9) on 5.1.1 (guarded assert) TypeError ... expected (name, type, channel, frame_start, length, input1, input2)
Expect GC span (25,34) exit 5, measured GC span (25, 33, 8) != closed form (25, 34, 9) (also on 4.5.11)
Swap GC inputs exit 7, measured inputs=(T2, T1), expected T1 -> T2
Corrupt text strip before save exit 10 via reloaded re-assert (exit 9 inner)

Measured check values (CI logs carry these)

  • 5.1.1: accessor: strips only (.sequences removed); end kwarg: length; spans A(1,33) B(25,57) C(1,57) GC(25,33) SC(1,251) on left_handle/right_handle/duration; GC input_1=T1 input_2=T2 clamped; transforms tol 1e-03; all survive save/reload
  • 4.5.11: identical values on frame_final_*, .sequences bridged to .strips, frame_end
  • Pixels (identical on 5.1.1/4.5.11, Cycles and EEVEE): TL(0.851,0.102,0.22) TR(0.059,0.749,0.8) BL(0.949,0.62,0.102) BR(blend)(0.341,0.349,0.463) margin(0.318,0.314,0.322)
  • Hero parity: 5.1 vs 4.5 render mean|diff| 0.00002, mean luminance 0.3767 vs 0.3768

Visuals

The still is the sequencer's own output at frame 29 (mid cross): crimson/teal/amber program cells + the 50/50 cross-blend cell over the Stage scene strip (dark studio, warm wedge pool), caption carrying the closed form. An off-by-one in end-exclusive span math drops its cell to the dark stage.

Contact sheet (candidate leftmost, then the pinned calibration set): docs/gallery/contact-sheets/vse-cut-list-contact-sheet.webp

Per-criterion verdicts vs armature-bend / damped-track-aim / bmesh-gear:

  • Stage darkness: candidate left-band 0.173 (family 0.122–0.202) ✓; top-band 0.309 vs 0.279/0.052/0.189 — brightest top but inside the armature-bend envelope ✓
  • Wedge warmth: warm pool upper-right, consistent with family ✓
  • Subject fill: mosaic 74% width / 72% height (spec 70–90%) ✓
  • Saturation: Standard transform, authored strip colors read exact ✓
  • Thumbnail legibility: 4 blocks + dark stage read instantly ✓
  • Mean luminance: candidate 0.372 vs 0.279 / 0.172 / 0.305 — highest (saturated cells cover ~53% of frame), not sortable as the odd one out in the lineup

Test plan

  • Local binaries: C:\Program Files\Blender Foundation\Blender 5.1\blender.exe (5.1.1, self-reported) and .scratch/blender-4.5.11-windows-x64/blender.exe (4.5.11 LTS, self-reported, official download).
  • Both run: check-only (exit 0), --check-pixels --engine cycles (exit 0), --output hero render (EEVEE on 5.1.1 GPU host; parity render on 4.5.11).
  • CI: blender-smoke 4.5/5.1 run both the check and the pixel witness (Cycles CPU).

Proven by live run vs inspection only

  • Live run (both binaries): all checks, falsification probes, pixel witness, hero renders, hero parity diff, webp asset generation, contact-sheet composite + luminance stats, gallery regeneration.
  • Inspection only: generated HTML alt/witnesses text (read post-generation), README/manifest/count wiring (also re-verified locally with the CI jobs' logic), landing-page template having no hardcoded counts.

…I rename

AI-generated VSE code still targets the pre-rename API everywhere:
sequence_editor.sequences is gone on 5.x, new_effect ends strips with
length= there but frame_end= on 4.5, and frame_final_* reads are
deprecated aliases for left_handle/right_handle/duration. No existing
example covers the sequencer, so this drift had no smoke-gated witness.

The example builds a deterministic cut list (color programs, a clamped
GAMMA_CROSS fed by a dedicated source pair, a scene strip, a text strip),
asserts every span against its closed form on each version's canonical
accessors, and re-asserts after a save/reload round-trip. A --check-pixels
mode witnesses the compositing contract on a tiny render. Hazards found
while authoring are witnessed too: the cross clamps to the source overlap,
effect strips consume their inputs only when stacked above them, and a
same-scene scene strip renders transparent.

Runs check-only on 4.5 LTS and 5.1 in blender-smoke; the render is the
sequencer's own output staged in the dark studio per VISUAL-STYLE, gated
against the pinned contact-sheet set.

Signed-off-by: fOuttaMyPaint <TMhospitalitystrategies@gmail.com>
@github-actions github-actions Bot added documentation Improvements or additions to documentation ci labels Jul 19, 2026
@TMHSDigital
TMHSDigital merged commit ddd2ba7 into main Jul 19, 2026
9 checks passed
@TMHSDigital
TMHSDigital deleted the feat/vse-cut-list-example branch July 19, 2026 17:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant