Skip to content

Release 0.11.0 - #818

Merged
dkackman merged 49 commits into
masterfrom
develop
Oct 10, 2026
Merged

dkackman merged 49 commits into
masterfrom
develop

Conversation

@dkackman

Copy link
Copy Markdown
Owner

Release 0.11.0: develop -> master.

Develop CI green at 66bfb05 (CI + CodeQL). Smoke and security regressions running separately.

After merge: scripts/release.sh 0.11.0 --next 0.12.0-alpha.1 from the Mac, then gh release edit v0.11.0 --notes-file with the notes below.


A short range. MiniMax H3's keyframe templates move to a 4-step turbo
LoRA that halves a long take's render time, music videos hold each shot's
audio slice by default and can give each entry its own singer, cost
estimates reach inline workflows, and torch.compile's kernel cache now
survives a reboot. Under the hood, the #790 refactor brought every module
and function back under the architecture ratchet.

MiniMax H3 (plugins/dw/skills/minimax-h3, workflows/templates)

  • The nine T2VA/FL2VA templates default to lightx2v's 4-step v1.2 turbo
    (num_inference_steps 5, shift 6/3) at 960x544 and 1344x768: on a
    345-frame take, ~7.3 min against 14.6 min for the 8-step file it
    replaces. Ref2VA templates stay on 8 steps; there is no tested 4-step
    Ref2VA file.

Music video and cuts (docs/TASKS.md)

Planning and validation

MCP and server

Acceleration (docs/ACCELERATION.md)

  • TORCHINDUCTOR_CACHE_DIR defaults to ~/.cache/dw/torchinductor, so
    compiled kernels survive a reboot instead of living in /tmp.
  • .env.example documents the environment knobs dw reads; copy it to .env
    (loaded at import, before torch) and restart the server after editing.

Web UI

  • Per-card VRAM bars in the header, status popover and server page.
  • Step and job durations on the job page, the log and the jobs list.
  • The sidebar marks the open workspace; each workspace has its own hue.

Maintenance

  • Architecture ratchet: bring the 0.10.0 re-baselined metrics back under the old baseline #790: task.py split by family, the H3 block classes moved to module
    level, task argument rules moved to dw/task_problems.py, and one
    iter_steps walk for every validation pass. CI runs the ratchet first
    so a test failure can no longer hide it.
  • UI dependencies: vitest 5, monaco-editor 0.57; the lockfile update
    clears the source-map-js and postcss-selector-parser Dependabot
    alerts.

🤖 Generated with Claude Code

dkackman and others added 30 commits October 8, 2026 20:34
- bump vitest from ^4.1.11 to ^5.0.3
- update monaco-editor from ^0.56.0 to ^0.57.0
- upgrade dompurify in monaco-editor overrides from ^3.4.13 to ^3.4.16
The ratchet ran after Tests, so a failing test skipped it and it stayed red
on develop for three days unseen. It now runs first, and every check step
runs whenever the install succeeded, so none hides another.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…790)

plan_cuts was 243 lines at complexity 16 and _align_lyrics was at 16.
plan_cuts now parses and checks its arguments in _parsed_arguments,
resolves the song's length (and its warning) in _song_length, builds the
render grid in _render_grid and the shot records with their min/max-scene
warnings in _shots. _align_lyrics takes the word-level alignment out as
_heard_spans, the seam #801's word timestamps will come from.

Behaviour, warnings, errors and the public signature and docstring are
unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dw/tasks/task.py was 1,471 lines, over the 1,100-line size ceiling. Its
command handlers move, unchanged, into four sibling modules that register
on import, the way beats/cuts/trim already do:

- audio_handlers.py: the audio commands and the cut-assessment probes
- video_handlers.py: joins, frame runs/grids, windows, fit/restore,
  stabilize, face-track crop and paste
- finish_handlers.py: grade, sharpen, film_grain, apply_lut and _load_media
- model_handlers.py: every model-backed (consumes_device) command

task.py keeps Task, task_command_info, the registry re-exports, the
general-purpose commands and the image/video processor dispatch (366
lines). Two tests import the moved private helpers from their new homes;
no patch target changed.

Ratchet: modules_over_size_ceiling 2 -> 1. modules rises 198 -> 202 - the
four new modules are the split itself; the baseline is left to the #790
payback's own re-baseline commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ass (#790)

Twenty-odd validation passes each copied the same walk over an expanded
definition's steps: skip a non-list, skip a non-dict step, pick out its
pipeline/task/result block, map it back with author_index and build the
" in member '<name>'" suffix. dw/references.py, which already owns
author_index and MEMBER_SEPARATOR, now owns that walk too (iter_steps,
member_suffix), and every copy in dw/ goes through it. Behaviour and
messages are unchanged.

select_errors and guides._step_problems each give a block to a helper
(_select_rule_errors, _guide_problems) to come in under C901 15.

duplicate_blocks 8 -> 0, complex_functions 16 -> 14.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Private-helper extractions only; signatures, docstrings, messages and the
order of every validator call are unchanged.

- chain.run_chain: _segment_arguments, _record_seam, _spilled_frames
  (the AudioVideo constructors stay in run_chain, where test_shots pins them)
- components.load_component: _warn_float16_on_mps, _hub_auth_error
- concat_videos: _record_seam_fade; the waveform rides the input zip
- script_check.check: _heard_shot (was a closure), _silent_take,
  _clipped_findings, _unassigned_tags, _silent_shot_findings
- pipeline._with_guides: module-level _prepared_guide per entry
- locations._walk: _named_value_errors, _media_value_errors
- admission.argument_reference_errors: _effective_values, _string_leaves
  (was a closure), _resolve_reference
- media.extract_audio: _seek_with_preroll, _flushed
- hub_cache._tracker_class: the Tracker body is a module-level _Tracker,
  subclassed per download with its counters and cancel event bound
- dw_mcp media.get_output_frames: _hear_tiles

functions_over_150_lines 7 -> 3, complex_functions 16 -> 8.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The hold and guide block factories (`h3_hold._make_blocks`, 261 lines,
C901 18; `h3_guides._make_guide_blocks`, 313 lines, C901 32) defined their
ModularPipelineBlocks subclasses in the function body so diffusers loaded
lazily, and the ratchet counted every class into the factory.

The classes now live at module level in h3_hold_steps.py and
h3_guide_steps.py, which import diffusers when they load and are imported
only inside `blocks()` / `guide_blocks()`. The tensor helpers the blocks
call move with them - left in h3_hold/h3_guides they would make the lazy
import a cycle. The closure values become module imports, the two t2va
condition steps keep their shared `DwH3WhenConditionedStep` name, and the
guide layout's `__call__` is split into `_encode_guides` and
`_hold_guide_audio`. The guide layout reads `encode_vae_condition` and
`h3_hold_steps.encode_audio_span` through their modules at call time, so
the tests patch them without resetting a cache.

tests/test_h3_rules.py now also pins that h3_hold and h3_guides import no
diffusers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
….py (#790)

task_domains.py was 1,452 lines, the only module over the ratchet's
1,100-line ceiling. The cross-argument rules of the families that need
more than a domain - ingredients_grid, crop/paste_face_track,
analyze_beats, plan_cuts, apply_lut, check_script's lines - move to a
new dw/task_problems.py (631 lines); the generic domain machinery,
choice_errors and the media-timing rules (window, slice, fit, dissolve,
frame size, select) stay in task_domains.py (857 lines).

The dependency runs one way: task_problems reads as_number and
choice_errors, and task_argument_errors reaches its rules only through
the registered static_check table, so import_cycles stays 0. Importers
are updated directly, with no re-export shim; the registry-rules test
scans both modules for static checks. Behaviour unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude_md_lines counts every CLAUDE.md under the repo, and agent worktrees
under .claude/worktrees are full checkouts: with six open, a local run read
903 lines against a baseline of 129.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lowered:
- modules_over_size_ceiling 2 -> 0: task.py's handlers split by family,
  task_domains.py's per-family rules moved to task_problems.py
- functions_over_150_lines 7 -> 0 and complex_functions 16 -> 2: plan_cuts,
  the H3 block factories, run_chain, load_component, concat_videos,
  script_check.check and the rest; the two left are the parsers
  lut.parse_cube and prompt_weighting.parse_prompt_attention, accepted
- duplicate_blocks 8 -> 0: references.iter_steps replaces the copied
  step walk in every validation pass

Raised, approved by Don on #790:
- modules 198 -> 205: the splits themselves - audio/video/finish/model
  task handler modules, h3_hold_steps and h3_guide_steps (the H3 block
  classes, imported lazily), task_problems

Kept as accepted: test_dw_patch_targets 325 (the new tasks' tests),
claude_md_lines 129.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…obs report finished_steps

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…t_gallery_metadata for levels

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…nts, per-character references

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…inding name it for a written file

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…nst its source slice

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…he match_audio chains; stop promising mouth sync; correct the #619 conclusion

A null hold_audio is dropped from the pipeline call. Hold plus reference is untested; the 3-arm A/B stays open.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…y estimates

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…as ''

a43b527's mid-run manifest entry copied event.get("subfolder") as-is, so a
step that saved flat put None where ManifestEntry types a string. Every
POST /api/jobs whose step_end carried no subfolder failed response
validation, which held develop red and blocked the #802/#803 hand-offs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…is inherited, warn where offload/quantization/frames differ

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…x and reports total, cut server-side

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…rules.finding(), reuses beats.SILENT_DBFS; map row

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…escription and skills show the shape

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…places the track

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…nal item: field

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ead warning on a replaced track

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
dkackman and others added 19 commits October 9, 2026 22:00
…ll_scale, near_silent) and lists them in rules_applied

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…o entries may carry their own singer

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
#59)

Its multi-root containment (workflow dir, asset libraries, output root)
is invisible to the query, so the existence test of the already-confined
path read as an uncontrolled access. Scope the validator-parameter
sanitizer to it the same way dw/security.py's validators are.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hen every entry overrides the default

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…m_frames counts as a per-entry cost field

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… 0.00 s offset on 8/8 shots vs up to 1.37 s reference-only

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…s_result: of an earlier video step

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…pieces by aligned word times

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…rkspace

The header meter, status popover and server page now read /api/memory's
`workers` list - one reading per card - instead of the top level, which
only ever repeats the first card. The header stacks one bar per card.

The sidebar gains a Workspaces label, chevrons, single-line truncated
names, and an open-workspace block with a --select rail, tint and a guide
line down its sections. Each workspace carries a hue hashed from its name
(wsColor), shown in the sidebar and the breadcrumb.

--select is a new token for the user's place (nav selection and the focus
ring, which moves off --live); design-rules.test.ts holds where it may
appear, and app.css's header records the three colour meanings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Read off data the server already records: every event's `at` (seconds
since the job started) pairs step_start with step_end for each finished
step, and the job record's started_at/finished_at give the total.

- flow view: a finished node's time, a for_each group's first-start to
  last-end span, and each member chip's own time
- log: each line led by its `+12.3s` clock
- job header: `took 7m 43s`, or a ticking `running ...` while it runs
- jobs list: the same formatDuration

A historical job streams no events, so it shows the header total only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…turbo

The nine templates that ran minimax_h3_fl2v_turbo_8step_v1.0(_768p) now run
minimax_h3_fl2v_turbo_4step_v1.2_768p_bf16 at num_inference_steps 5 and
video/audio shift 6/3 - the file's training shift, at 960x544 as well as
1344x768. Measured on lem (2026-10-10, origami prompt, seed 42): 13.2 s/step
at 960x544x124 with clean video and an action-tracking soundtrack (job
974f0bedf1f8), and a 345-frame take in ~7.3 min against 14.6 min for the
8-step reference (d038264721bf vs 9e41d8de9518).

v1.2 records alpha 8 at rank 128, unlike v1.0/v1.1 (128), so lora_alpha
stays unset. The ref2va templates stay on 8 steps: there is no tested
4-step Ref2VA file, and the 544p 4-step v0.1 renders noise.

Tests pin the new file's trained shift, recorded alpha and step count
(new: each template's steps are its adapter's NFE + 1); the nine step-cache
keys are regenerated. Catalog evidence added for turbo-4step-keyframe and
instantx-turbo-4step; the H3 skill, its checkpoint reference and the
templates README carry the new default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…first-and-last-frame templates

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…test 5 bump

51f74ff moved vitest 4 -> 5; the plain @testing-library/jest-dom types no
longer reach vitest's Assertion, so svelte-check failed on
ArgumentsEditor.test.ts and CI's UI type check has been red since.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#802 added measure_sync as its own task module (198 lines, own tests).
Folding it into cuts.py or another task module would push that module
past its size warning. Approved by Don for the 0.11.0 release.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dkackman
dkackman merged commit 67d118c into master Oct 10, 2026
19 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.

1 participant