Files
malkuthro-ComfyUI-Koolook/docs/reference/versioning.md
T
malkuthroandClaude Opus 4.7 cc6bc47866 docs+tooling: VAE user guide + versioning ref + 3 skills + preflight CI (#48)
* docs+tooling: VAE user guide + versioning ref + 3 skills + preflight CI

Documentation
- New user-guide tree: docs/user_guide/nodes/radiance_koolook_v2_3_3/
  with README, per-node pages for Easy_hdr_VAE_encode/decode, an
  encode/decode pairing guide (4 worked examples + ASCII connectivity
  diagram), and an HDR modes deep-dive (per-pixel comparison table).
  Folder name mirrors the code path under forks/radiance_koolook/versions/.
- New cross-cutting reference: docs/reference/versioning.md explains the
  three independent version axes (pack version, fork wrapper version,
  upstream pinned commit), when each one bumps, and which skill/doc
  owns it. Plus the v1/v2 node-ID suffix policy.
- Cross-links updated in docs/user_guide/README.md, docs/reference/
  README.md, docs/maintainers/README.md.

Skills (all under .claude/skills/)
- docs-sync — controlled find-and-replace for version tags across docs,
  code, and manifests; --scope and --dry-run flags.
- menu — lists all project skills with one-liners.
- preflight-release — companion doc for tools/preflight_release.py.

Pre-flight tooling
- tools/preflight_release.py — four checks, exit-code-driven for CI:
  (1) static AST extraction of NODE_CLASS_MAPPINGS keys (no torch needed),
  (2) stub-VAE dispatch test verifying all 5 rank/VAE-type branches,
  (3) drift check against ComfyUI-Manager's extension-node-map.json
      (catches the issue #44 phantom-nodes class of bug automatically),
  (4) saved-workflow regression check across tests/workflows/*.json.
- .github/workflows/ci.yml — new "Pre-flight Release" job runs checks
  1, 2, and 4 on every PR; check 3 (manager-meta) skipped pending the
  upstream issue #44 fix.
- tests/workflows/ — 2 starter fixtures (Depth-Anything3, Hires-FIX-wanT2V)
  + README documenting the contribution convention. Coverage grows as
  new fixtures are added; no code changes needed.

All four offline pre-flight checks pass on this branch. The
manager-meta check correctly identifies the 39 phantom IDs documented
in issue #44.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(preflight): satisfy ruff lint + bandit security gate

* fix(preflight): address blocking review findings

Three fixes from /review-pr feedback on this PR:

1. Sanitize tests/workflows/*.json — removed 4 unique absolute paths that
   leaked internal job/client info ('baconx/Toy-Hix/9110',
   'menneskehavn_3029', etc.). Replaced with placeholders like
   'path/to/sequence_a' and 'path/to/source_video'. Both fixtures still
   parse as valid JSON; grep for the old patterns returns zero hits.

2. Broaden the Koolook-ID heuristic regex from '^easy_[a-z]' to
   '^easy_[A-Za-z]'. The old pattern excluded 'easy_ImageBatch' (capital I
   after the underscore), which would have silently bypassed the
   workflow-fixture stability check for that node. Verified the new
   pattern correctly matches it.

3. Wrap check_dispatch() body in try/finally and track every sys.modules
   key the function injects in a list, so cleanup runs on the success
   path AND on any exception during exec_module / VAE-constructor
   execution. Previously only the three torch* stubs were popped, never
   the three _pf_pkg* entries — and even those weren't popped on
   exception paths. Verified zero leaked modules after the function
   returns.

The five dispatch test cases were factored into a helper
_check_dispatch_run_cases() so the try/finally wrapping stays focused on
module injection.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(preflight): address remaining review findings

Follow-up to 7844037 — picks up all the HIGH / MEDIUM / LOW review
findings that were deferred. Pre-flight still passes locally.

HIGH
- Extract check_dispatch (~195 lines) to tools/_preflight_dispatch.py.
  Main script drops from 680 → 508 lines. Module exposes a single
  run(verbose, repo_root) -> (bool, list[str]) entry; main script keeps
  the [2/4] header + PASS/FAIL line.
- Install _HttpsOnlyRedirectHandler that re-validates each redirect
  hop's scheme. Closes the gap that urlopen would otherwise follow a
  30x to http:// or file:// silently. The Bandit B310 suppression
  comment now accurately describes the protection.
- check_static docstring now honestly states it only walks
  NODE_CLASS_MAPPINGS literal dicts and does NOT apply
  NAMESPACE_SUFFIX / SKIP_VERSION_SUFFIX logic. Notes that the workflow
  check (4) is the safety net that surfaces drift the day a non-skipped
  ID lands.
- check_workflows now FAILS when the fixtures dir exists with a README
  but contains no *.json files — previously silently SKIPPED. If
  someone deletes fixtures or typoes the dir, that's a regression in
  test coverage and should fail loudly.

MEDIUM
- check_manager_meta validates the upstream entry shape before diffing.
  Previous code silently produced an empty set if the schema changed,
  reporting every one of our IDs as 'missing'. Now SKIPs with a clear
  message when shape is unexpected.
- check_workflows accumulates total_koolook_refs inside the main loop;
  drops the redundant second-pass that re-read every fixture file just
  to compute the summary count.
- _extract_workflow_node_types uses explicit detection: a canvas-format
  file with nodes: null no longer falls through to API-format and pulls
  class_type from unrelated keys.
- check_static return type simplified from (bool, set, list) to
  (bool, set). Third element was discarded at every call site.
- check_workflows now does two-pronged Koolook-ID matching: heuristic
  (catches drift even if static missed an ID) plus actual_ids (catches
  IDs that don't fit the heuristic, e.g. a future Koolook node without
  Easy / easy_ / koolook in its name).

LOW
- ANSI escape codes named in a constants dict (_ANSI["green"] etc.)
  instead of bare string literals.
- Removed dead 'cases: list[tuple[str, callable]] = []' initializer
  (was shadowed three statements later).
- check_static's per-ID listing now gated behind --verbose, matching
  check_dispatch and check_workflows.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 17:31:36 +02:00

118 lines
7.2 KiB
Markdown

# Versioning — three numbers, three meanings
This codebase carries **three independent version numbers** that often get
confused. They mean different things, bump on different schedules, and live
in different places.
## At a glance
| Axis | What it is | Where it lives | Example |
|---|---|---|---|
| **Pack version** | The Koolook release that ships to GitHub + Comfy Registry. Semver. | [`pyproject.toml`](../../pyproject.toml) `version = "X.Y.Z"`, [`CHANGELOG.md`](../../CHANGELOG.md) `## [X.Y.Z]` | `0.2.0` |
| **Fork wrapper version** | A slot under `versions/` that holds Koolook's modified code for a particular upstream baseline. Underscored. | `forks/<fork>/versions/vX_Y_Z/` directory name + the `NAMESPACE_SUFFIX` constant inside it | `v2_3_3` |
| **Upstream pinned commit** | The exact commit of the upstream third-party repo that the fork wrapper is matched to. SHA. | [`forks/<fork>/versions/vX_Y_Z/UPSTREAM_PIN.yaml`](../../forks/radiance_koolook/versions/v2_3_3/UPSTREAM_PIN.yaml), [`forks/forks_manifest.yaml`](../../forks/forks_manifest.yaml), [`forks/THIRD_PARTY.md`](../../forks/THIRD_PARTY.md) | `f262f47ddfda01ece154bf80c22769b1e4cef795` |
A current snapshot reads: *"Koolook **0.2.0** ships the **v2_3_3** Radiance
fork wrapper, which is pinned to upstream Radiance commit **f262f47**."*
All three are unrelated numbers that happen to all describe the same
release.
## When each one bumps
### Pack version (`0.2.0` → `0.2.1` / `0.3.0` / `1.0.0`)
Bumps on **every release of the Koolook pack itself**. Drives the Comfy
Registry publish workflow. Follow [`docs/maintainers/releasing.md`](../maintainers/releasing.md)
for the canonical procedure.
- **Patch** (`0.2.0 → 0.2.1`): bug fixes, internal refactors, no surface change.
- **Minor** (`0.2.0 → 0.3.0`): new nodes, new node options, anything that adds surface but doesn't break existing workflows.
- **Major** (`0.2.0 → 1.0.0`): only after a v2-style breaking change has shipped (a removed-after-deprecation node ID, an INPUT_TYPES change a saved workflow can't tolerate, etc.).
### Fork wrapper version (`v2_3_3` → `v2_4_0` / `v2_3_4`)
Bumps when **upstream releases a new version we want to track** AND the
new upstream version requires meaningfully different wrapper code.
Two patterns, decided per-fork:
- **In-place upgrade** (used by Radiance Koolook today). All exposed node
IDs are listed in `SKIP_VERSION_SUFFIX` so the user-facing IDs are
stable across versions (e.g. `Easy_hdr_VAE_encode` stays as itself
whether the wrapper is `v2_3_3` or `v2_4_0`). When upstream bumps, the
whole `versions/v2_3_3/` directory gets renamed to `versions/v2_4_0/`
in-place; there's no parallel coexistence because both versions would
collide on the same ID. Saved workflows continue loading because the
ID didn't change.
- **Versioned coexistence**. Node IDs carry the `__koolook_vX_Y_Z`
suffix (the default behavior unless explicitly added to
`SKIP_VERSION_SUFFIX`). When upstream bumps, the new `versions/v2_4_0/`
is added alongside the old one. Both are registered simultaneously
for one release cycle. Old workflows keep loading via the suffixed
old ID; new workflows can adopt the new suffixed ID. The old version
is removed in the next release.
### Upstream pinned commit (`f262f47` → some new SHA)
Bumps when **we re-sync the wrapper against a newer upstream commit**.
Recorded in:
- `forks/<fork>/versions/<vX_Y_Z>/UPSTREAM_PIN.yaml` (the per-version pin)
- `forks/forks_manifest.yaml` (the project-level fork inventory)
- `forks/THIRD_PARTY.md` (the human-readable attribution + change notes)
A new pinned commit may or may not require a new fork wrapper version —
small upstream patches can land at the same wrapper slot if our wrapper
code doesn't have to change. Bigger upstream releases usually warrant a
new wrapper version too.
## Public node-ID versioning (the `_v2` rule)
Independent of the three axes above, individual node IDs can carry a
public version suffix when a breaking change forces it:
- Original ID (no suffix): `Easy_hdr_VAE_encode`. Stays this forever.
- Bumped ID after a breaking change: `Easy_hdr_VAE_encode_v2`. Only
introduced when the original would otherwise break saved workflows.
- Both IDs register simultaneously for **one full release cycle** (the
old one displays as `Easy HDR VAE Encode (Koolook, v1 — please migrate)`
during this window).
- Old ID is dropped one release later. Pack version goes major (`1.0.0`)
to signal the breakage.
This is the rare path. Most version changes don't need it because either
the change isn't actually breaking, or the fork wrapper version mechanism
above already handles the back-compat.
## Which skill / doc owns which axis
| Axis | Skill | Doc |
|---|---|---|
| Pack version | (none, manual via release PR) | [`docs/maintainers/releasing.md`](../maintainers/releasing.md) |
| Fork wrapper version | [`docs-sync`](../../.claude/skills/docs-sync/SKILL.md) (string-sweep), [`add-external-fork`](../../.claude/skills/add-external-fork/SKILL.md) (initial setup) | [`forks/README.md`](../../forks/README.md), [`docs/maintainers/node-versioning.md`](../maintainers/node-versioning.md) |
| Upstream pinned commit | (none — manual edit to `UPSTREAM_PIN.yaml` + `forks_manifest.yaml`) | [`forks/THIRD_PARTY.md`](../../forks/THIRD_PARTY.md) |
| Node-ID `_v2` suffix | (none — manual code change with deprecation alias) | (this document) |
## Example — a hypothetical Radiance v2.4.0 release
Suppose upstream Radiance ships v2.4.0. We re-sync and the wrapper code
changes only slightly — same node IDs, same interface. The bumps:
- **Upstream pinned commit:** `f262f47…` → whatever the v2.4.0 release commit is. Update `UPSTREAM_PIN.yaml`, `forks_manifest.yaml`, `THIRD_PARTY.md`.
- **Fork wrapper version:** `v2_3_3` → `v2_4_0`. Rename `versions/v2_3_3/` to `versions/v2_4_0/`. Update `NAMESPACE_SUFFIX` and `DISPLAY_SUFFIX` constants inside. Update parent `__init__.py` import. Rename matching docs folder `docs/user_guide/nodes/radiance_koolook_v2_3_3/` → `radiance_koolook_v2_4_0/`. Update inline references via [`docs-sync v2_3_3 v2_4_0`](../../.claude/skills/docs-sync/SKILL.md).
- **Pack version:** `0.2.0` → `0.3.0`. Cut a release PR per [`releasing.md`](../maintainers/releasing.md).
- **Node IDs:** unchanged (stable IDs). No `_v2` suffix introduced. Saved workflows keep loading.
If the v2.4.0 wrapper required a *behaviorally* breaking change to one of
the node IDs — say `Easy_hdr_VAE_encode` now returns a different shape
that downstream samplers can't handle — only then would we add
`Easy_hdr_VAE_encode_v2` and start the deprecation cycle.
## See also
- [`docs/maintainers/releasing.md`](../maintainers/releasing.md) — pack version release procedure.
- [`docs/maintainers/node-versioning.md`](../maintainers/node-versioning.md) — the rules for safely changing `INPUT_TYPES` / `RETURN_TYPES` / class names without breaking saved workflows.
- [`forks/THIRD_PARTY.md`](../../forks/THIRD_PARTY.md) — upstream attribution and change notes for each fork.
- [`forks/forks_manifest.yaml`](../../forks/forks_manifest.yaml) — machine-readable fork inventory.
- [`.claude/skills/docs-sync/SKILL.md`](../../.claude/skills/docs-sync/SKILL.md) — the find-and-replace skill for fork-version bumps.