Stage 3 of #601. It builds the plan's Stage 3 and its join_windows' static window-count check section, from plan v3. If this body and the plan disagree, the plan wins.
Filed by the lead agent, model claude-opus-5-5 via anthropic, 2026-10-05. Reshaped for plan v3 by the lead agent (claude-opus-5-5 via anthropic), 2026-10-06: the template ships unpriced (a cost is measured, never derived, and restore-deblur has none); the measured per_entry moves to new stage 4; the plugin version bump is dropped; acceptance now expects an unknown estimate and asks the tester to record the run's timings.
Builds
- A static window-count check owned by
join_windows (Don, 2026-10-05). It is a module in the shape of dw/dissolve_frame_errors.py, wired into validation_errors, and it calls stage 2's rule in dw/task_domains.py.
- It applies to any
join_windows step. There is no template-specific logic in validate.
- It fires when all of these are knowable: the
source file (asset:/output:, or a readable literal path, probed header-only); literal num_frames and overlap; and videos as gather:<step>, whose member count is known after for_each expansion.
- It errors at the step's path, naming the count needed. When an input isn't knowable it stays silent and leaves the decision to the run-time refusal.
workflows/templates/ltx2/restore-long.json.
- A short note in the
dw:ltx-2.5 skill on choosing windows for a long source.
Owes
- Tests: the catalog-structure tests pass on the template. Check unit tests on a plain
join_windows workflow, not the template: short, exact and long lists; an unknowable source and a non-literal num_frames stay silent.
- Docs: the template description,
WORKFLOW_GUIDE.md's for_each example list, and the check in TASKS.md's join_windows section.
Deploy
Server restart. No plugin version bump: the version is pinned to the engine's and moves only at release (tests/test_plugin_skills.py). The skill note reaches the tester through origin/develop.
Passes when
The plan's stage 3 acceptance intent holds over MCP on the LTX-capable server (CUDA, 24 GB):
list_workflows(shape=…) lists the template, and validate_workflow on it is clean. Its plan.estimate is unknown (no cost yet), and validate doesn't refuse on that.
- The tester's verify comment records the minutes of one
restore@wN step and the whole run's minutes, with the window count and device, for stage 4.
- A ~10 s
asset: clip with the right list gives the source's frame count and audio length, no visible seams, and no sync drift.
- A list one entry short is refused at
validate_workflow with the needed count, before any GPU time. So is a hand-written windowed workflow that is not the template.
The stage also passes every pending: #<this issue> case the tester writes.
Stage 3 of #601. It builds the plan's Stage 3 and its
join_windows' static window-count check section, from plan v3. If this body and the plan disagree, the plan wins.Filed by the lead agent, model
claude-opus-5-5viaanthropic, 2026-10-05. Reshaped for plan v3 by the lead agent (claude-opus-5-5viaanthropic), 2026-10-06: the template ships unpriced (a cost is measured, never derived, andrestore-deblurhas none); the measuredper_entrymoves to new stage 4; the plugin version bump is dropped; acceptance now expects an unknown estimate and asks the tester to record the run's timings.Builds
join_windows(Don, 2026-10-05). It is a module in the shape ofdw/dissolve_frame_errors.py, wired intovalidation_errors, and it calls stage 2's rule indw/task_domains.py.join_windowsstep. There is no template-specific logic in validate.sourcefile (asset:/output:, or a readable literal path, probed header-only); literalnum_framesandoverlap; andvideosasgather:<step>, whose member count is known afterfor_eachexpansion.workflows/templates/ltx2/restore-long.json.windowfor_each overvariable:windows(entries{name, index}), arestorefor_each (therestore-deblurpipeline,frames: previous_result:window), andjoin(join_windows(gather:restore, source=variable:source_video)).costblock yet. Stage 4 adds the measured one.windows(soindex) stays out ofcost_drivers, so stage 4'sper_entrywon't be made unknown (validate_workflow: plan.estimate ignores a per-entry num_frames in a list-driven template (follow-up to #589) #593's_list_entry_field_shifted).dw:ltx-2.5skill on choosingwindowsfor a long source.Owes
join_windowsworkflow, not the template: short, exact and long lists; an unknowable source and a non-literalnum_framesstay silent.WORKFLOW_GUIDE.md's for_each example list, and the check inTASKS.md'sjoin_windowssection.Deploy
Server restart. No plugin version bump: the version is pinned to the engine's and moves only at release (
tests/test_plugin_skills.py). The skill note reaches the tester throughorigin/develop.Passes when
The plan's stage 3 acceptance intent holds over MCP on the LTX-capable server (CUDA, 24 GB):
list_workflows(shape=…)lists the template, andvalidate_workflowon it is clean. Itsplan.estimateis unknown (nocostyet), and validate doesn't refuse on that.restore@wNstep and the whole run's minutes, with the window count and device, for stage 4.asset:clip with the right list gives the source's frame count and audio length, no visible seams, and no sync drift.validate_workflowwith the needed count, before any GPU time. So is a hand-written windowed workflow that is not the template.The stage also passes every
pending: #<this issue>case the tester writes.