Files
040b30733d feat(matte): first-party mask-guided one-step video matting nodes (#269)
* feat(matte): first-party mask-guided one-step video matting nodes

Adds matte/ — an independent implementation of the published VideoMaMa
one-step SVD method (matte/pipeline.py) plus Koolook's temporal windowing,
subject-focused crop/stitch, resolution control (/64, shortest-side) and
auto OOM resolution-backoff. Nodes: KoolookMatteLoader, KoolookMatteSampler,
KoolookMatteFocusCrop, KoolookMatteFocusStitch.

Registered via the existing guarded _merge_node_group("Koolook Matte",
".matte"), so a missing diffusers disables only these nodes. diffusers is
already pulled in by the radiance/whatdreamscost forks, so no new dependency.

Loads (never bundles) the VideoMaMa UNet (CC-BY-NC) + SVD VAE at runtime;
matte/NOTICE records the model licenses and user responsibility.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* chore(dev-sync): include matte/ in RUNTIME_PATHS

So `sync_to_dev` copies the new matte node package into the live ComfyUI
install alongside the rest of the koolook pack.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(matte): raw cond latents; fp16 default; preserve checkpoints on dev-sync

pipeline.py: _encode_latents must NOT divide by vae scaling_factor. The
VideoMaMa UNet is trained on raw VAE latents (matching okdalto's
VideoInferencePipeline, which multiplies by scaling_factor then divides it
back out -> net x1). Dividing over-scaled the conditioning ~5.5x and produced
a systematically blurry matte on every frame. Verified 5/5 vs the desktop /
vanilla reference on identical single-frame inputs.

nodes.py: harden the loader precision fallback so fp16 is the true default -
only an explicit "bf16" opts out; a stale "auto" widget now resolves to fp16
instead of bf16.

sync_to_dev.py: the rmtree+copytree mirror deleted matte/checkpoints/ (the
gitignored ~10GB SVD+VideoMaMa weights) on every matte sync, forcing a
re-download. Add PRESERVE_IN_DEST + selective _clean_dest so runtime-
downloaded model data survives a sync.

docs: add docs/maintainers/matte-pipeline.md (latent-scaling invariant,
black-output causes, fidelity levers, single-frame + vanilla-oracle debug
loop, checkpoint preservation).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(matte): address PR #269 review

- license: align matte to the repo's GPL-3.0 (was self-contradictory: claimed
  "MIT licensed - see LICENSE" while LICENSE is GPL-3.0). pipeline.py header,
  NOTICE, and the maintainer doc updated. NOTICE still credits VideoMaMa
  (CC BY-NC) + SVD (Stability Community License).
- nodes.py _ensure_2d_mask: squeeze first, then handle [H,W,C]/[C,H,W]
  explicitly and RAISE on ambiguous shapes -- previously [H,W,3] silently
  became [W,3] (wrong geometry).
- nodes.py OOM backoff: catch RuntimeError (OutOfMemoryError subclasses it, but
  cuBLAS/cuDNN/older paths raise plain "RuntimeError: CUDA out of memory"); the
  existing message guard still filters non-OOM errors.
- nodes.py: warn when the guide mask is empty instead of silently falling back
  to full-frame.
- sync_to_dev.py: PRESERVE_IN_DEST is now an exact relative path
  ("matte/checkpoints"), not a bare name matched at any depth; handle symlinks
  before is_dir() in _clean_dest so a symlinked dir isn't recursed/rmtree'd.
- CHANGELOG: add the Koolook Matte nodes under [Unreleased] with the
  non-commercial model-license caveat.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(matte): address PR #269 re-review

- sync_to_dev.py [BLOCKING]: a top-level symlinked dest (e.g. target/matte -> X)
  was passed straight into _clean_dest()/copytree(), which follow the link and
  can mutate files outside the target. Now unlink a symlinked dest and own the
  path as a real dir (checked before exists(), which follows symlinks). Verified
  with a repro: the symlink target's file survives.
- nodes.py: force float32 on a CPU fallback (CUDA unavailable). Half precision
  is unreliable on CPU; fp16 kernels would error. Warn that CPU is very slow.
- docs: correct the preserved-path guidance to the target-relative
  "matte/checkpoints" (was a bare "checkpoints" name); reword "near-verbatim
  reimplementation" -> "independent implementation targeting behavioural parity"
  to match the NOTICE/pipeline framing.
- nodes.py: also warn on a degenerate (<8px) guide-mask region before the
  full-frame fallback (was silent).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(matte): address PR #269 re-review (CI red + FocusCrop frame check)

- nodes.py: KoolookMatteFocusCrop now validates images vs coarse_mask frame
  counts (raises like KoolookMatteSampler.run_inference). A mismatch previously
  made cropped_images/cropped_mask diverge and silently drop/misalign frames at
  FocusStitch.
- pipeline.py: split "vae.to('cpu'); _clear_cache(...)" onto two lines (Ruff
  E702 was failing Lint & Smoke).
- constraints-test.txt: bump pillow 12.2.0 -> 12.3.0 (pip-audit CVE, fixed in
  12.3.0). Pillow is a leaf dep so the closure is unaffected; CI re-audits.
- README: note the Koolook Matte nodes need diffusers (already via the LTX /
  Radiance forks) and huggingface_hub for runtime weight downloads.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: AI Machine <ai.machine@x.baconcph.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 17:03:12 +02:00
..

Maintainer docs

Project-internal procedures. If you're cutting a release, forking a node, hitting the Comfy Registry API, or debugging CI — read these first.

These are docs for humans doing the work. The corresponding agent workflows for Claude Code live in ../../.claude/skills/ and should be kept in sync with these prose docs.

Contents

File What it covers
conventions.md Cross-cutting project conventions that don't fit any single topic doc — currently the Mermaid-for-diagrams rule. Add new cross-cutting rules here as they accrete.
releasing.md Canonical step-by-step release procedure: branch → PR → publish-validate → squash-merge → tag → GitHub Release. Anti-patterns to avoid. The per-release tickbox mirror is .github/ISSUE_TEMPLATE/release_checklist.md.
registry-api.md The Comfy Registry's undocumented version-management endpoints (deprecate, delete, query) reverse-engineered while cleaning up v0.1.0–0.1.5. Includes ready-to-paste curl commands and an optional GitHub Actions workflow YAML for codified version management.
dependency-security.md Dependency CVE protocol: the locked test set as the review surface, local/CI pip-audit gates, relocking, and weekly scheduled audit response.
published-setup-loop.md Architecture overview / entry point for the publish → run loop: the plain-terms loop, a technical map (frontend JS → Koolook routes → ComfyUI engine), and the contract/schema requirements. Read this first, then follow the links.
published-setups.md Published workflow setup schema, server-side storage boundary, sidebar publish flow, and catalog API contract for external frontends.
published-setup-external-ui-contract.md Product/design contract for how ComfyUI publish nodes expose controls and result fields to an external frontend.
published-setup-full-circle-plan.md Remaining implementation plan for the full authoring → publish → exported setup/API → external runner loop.
external-frontend-job-submitter-brief.md Handoff brief for an AI or developer session building the real external frontend job submitter.
external-frontend-kit.md Complete file/dependency/fixture checklist for another AI session building the production external frontend.
node-versioning.md Hard-won rules for changing INPUT_TYPES / RETURN_TYPES / class names without breaking saved user workflows. The five rules + the suffix-version pattern (MyNode → MyNodeV2) + the alias-then-deprecate migration path.
curated-sidebar.md The Kforge Labs sidebar starter-preset workflow. How to customize the bundled web/starter_preset.json shipped to fresh users (Snapshot → Load → starter). Storage keys, library directory resolution, reset procedure.
workflows-sidebar.md The "Workflows" section of the same sidebar. Save canvas / save selection / directories / archive on collision / load with named tab. Storage shape, action semantics, reset procedure.
dev-iteration-loop.md The fast iteration pattern we used to build the sidebar — the dev-sync loop, agent trigger phrases (go, dev-sync, paste-JSON), what survives across re-syncs vs what doesn't, push/publish gates. Read this when returning to UI work after a break.
comfyui-server-api-testing.md How to give an AI session access to a running ComfyUI server, submit API-format prompts, poll /history, keep outputs safe, and document real server-side validation in PRs.

Read this first if you're confused about version numbers: ../reference/versioning.md explains the three independent version axes in this codebase (pack version, fork wrapper version, upstream pinned commit) and which skill/doc owns each one. Worth a one-time read before starting any version-bump work.

Companion agent skills

Skill (in .claude/skills/) Mirrors this doc
license-pre-check Runs before any third-party fork; refuses to proceed on incompatible licenses. The principles also apply when a human is doing it manually.
add-external-fork The forks/ workflow — clone outside MAIN, register in forks_manifest.yaml, namespace the IDs. Phase 0 calls license-pre-check.
docs-sync Find-and-replace a version tag (or any string token) across docs, code constants, and manifests in one controlled pass. Used during fork wrapper version bumps.
preflight-release Runs the release-gate checks from tools/preflight_release.py — static AST node-ID extraction, VAE wrapper rank/type dispatch roundtrip, and workflow-fixture stability. The ComfyUI-Manager extension-node-map drift check remains available as an explicit advisory check (--check manager-meta) but does not block releases because Manager metadata is maintained independently. Run before opening any release PR — releasing.md step 1.
menu-comfy Lists all project skills with one-liners — quick inventory when you can't remember what's available. Distinct from the global /menu skill so the two don't collide.