Wildcard options, fixed values and combines can carry a `negative`, and a
derivation action gains the `negative` ("Add to negative") mode. The
engine files negatives per variable in `__wp_negatives__`, carries them
across nodes, and the Assembler gets a `negative` output built from the
variables its template rendered, filled into a `negative_template` at
`$negatives`. Negatives resolve on their own seed stream and refs inside
them resolve quietly, so picks never shift. Injector rows can set a
negative, the Prompt Cleaner cleans an optional negative with its own
rule column, and the preview endpoint returns the negatives table.
Schema v8 stamps payloads that use a negative.
Canvas Context runs now set an explain flag. With it, each trace row carries
the module's display name and a handler detail dict: which derivation branch
fired, with every test's result and the value it read; a wildcard's option,
odds, pool and the constraints that re-weighted it; a constraint's reach and
rule counts. Warnings a module raised name it as their owner, and trace rows,
warnings and nested @{} picks are tagged with the Context node's graph id.
WP Debug forwards the nested-pick log, node seeds, internal flags, rolled
axes, constraint hits and multi-pick items.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wwo837fQ1tm6RacaQGYom1
Three coordinated changes to the WP_* node family.
1. New WP_SeedList node
Emits a list of N derived seeds for a downstream loop (is_output_list).
Three independent override toggles (override_seed / override_count /
override_strategy) each mirror the wired Loop's base_seed / count /
strategy. Connecting loop_config auto-flips override_count +
override_strategy ON so the natural intent of wiring in a loop gets
the defaults right; override_seed stays explicit opt-in.
All emitted seeds are masked to 50 bits via the new MAX_SAFE_SEED
constant in engine.seed_derive so values sit inside ComfyUI's
frontend randomize range and copy-paste reproduces identically in a
standalone sampler.
2. Context Loop type split + downstream Context seed widget lock
Split WP_CONTEXT_LOOP_CONFIG (wire payload) from a new
WP_CONTEXT_LOOP_WIDGET (DOM-widget-only TYPE). Loop's own widget
mounts on the widget type; the wire type has no factory so consumers
like WP_SeedList render their loop_config socket as a plain input
instead of being hidden by a fallback-undefined widget.
New graph walker hasUpstreamLoopOverridingSeed: WP_Context's widget
glue greys out the local seed stock widget when an upstream Loop has
override_seed ON, so users read "this value is dead while the Loop
drives it" without inspecting the Loop config separately.
3. wp_ prefix sweep + tooltips across every WP_* node input
Custom DOM widget input names now carry the wp_ prefix so canvas
socket labels read as branded WP widgets: modules -> wp_modules,
rows -> wp_rows, viewer -> wp_viewer, cleaner -> wp_cleaner,
context_loop_config -> wp_context_loop_config. Every stock input
across the node family gets a tooltip describing what it does and
when to wire it from another node. Tests + comfy_api stub updated.
CLAUDE.md notes the wp_ convention for future custom widgets.
Bundle size budget bumped 388 -> 395 KB to fit the SeedList Vue chunk
(~4.9 KB net gzip) + override lock UI; entry stays at ~4 KB gzipped.
DebugViewer now reads a flat snapshot shape — user vars at the top
plus `__wp_trace__` / `__wp_picks__` / `__wp_warnings__` /
`__wp_node_seed__` keys consumed by per-tab readers. Trace and
warnings accumulate cumulatively across the chain in `build_payload`
so a terminal Debug node sees every contribution, matching the
injector's existing cumulative-merge pattern.
- highlight.ts: tiny JSON tokenizer wrapping keys/strings/numbers/
booleans/punctuation in `wp-jh-*` spans for syntax-colored display
- DebugViewer.vue: Snapshot tab uses highlighted `<pre>`; Trace +
Picks + Warnings tabs render typed tables instead of raw JSON
- :deep() rules style the v-html-injected highlight spans, since
scoped data-v-* attributes don't attach to raw HTML