test: pin the comfyui-promptchain slot-replacement break to the read path - #15595
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
🎭 Playwright: ✅ 1985 passed, 0 failed · 3 flaky📊 Browser Reports
🎨 Storybook: ✅ Built — View Storybook📦 Bundle Size
⚡ Performance Report
Absolute values
Raw data{
"timestamp": "2026-08-22T05:30:26.476Z",
"gitSha": "06414436a7fe4eb81bfaa7e864a71498a797d3a0",
"branch": "cb__promptchain-slotlinks",
"measurements": [
{
"name": "canvas-idle",
"durationMs": 2073.999000000015,
"styleRecalcs": 6,
"styleRecalcDurationMs": 6.112000000000003,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 576.434,
"heapDeltaBytes": 2808012,
"heapUsedBytes": 65176316,
"domNodes": -286,
"jsHeapTotalBytes": 3923968,
"scriptDurationMs": 11.176999999999998,
"eventListeners": -187,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "canvas-idle",
"durationMs": 2037.776000000008,
"styleRecalcs": 8,
"styleRecalcDurationMs": 7.700000000000002,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 572.7679999999999,
"heapDeltaBytes": 160456,
"heapUsedBytes": 69050188,
"domNodes": -281,
"jsHeapTotalBytes": 4710400,
"scriptDurationMs": 11.114,
"eventListeners": -185,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-mouse-sweep",
"durationMs": 2407.731999999953,
"styleRecalcs": 77,
"styleRecalcDurationMs": 46.237,
"layouts": 12,
"layoutDurationMs": 6.9510000000000005,
"taskDurationMs": 1454.174,
"heapDeltaBytes": 6890948,
"heapUsedBytes": 75952588,
"domNodes": -281,
"jsHeapTotalBytes": 6021120,
"scriptDurationMs": 174.84900000000002,
"eventListeners": -155,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-mouse-sweep",
"durationMs": 2285.88400000001,
"styleRecalcs": 78,
"styleRecalcDurationMs": 46.102,
"layouts": 12,
"layoutDurationMs": 4.038,
"taskDurationMs": 1291.4399999999998,
"heapDeltaBytes": 5435888,
"heapUsedBytes": 74623260,
"domNodes": -281,
"jsHeapTotalBytes": 6021120,
"scriptDurationMs": 159.20999999999998,
"eventListeners": -155,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1738.9590000000226,
"styleRecalcs": 31,
"styleRecalcDurationMs": 18.538000000000004,
"layouts": 6,
"layoutDurationMs": 0.6380000000000001,
"taskDurationMs": 407.25,
"heapDeltaBytes": 3747140,
"heapUsedBytes": 72797844,
"domNodes": 76,
"jsHeapTotalBytes": 5242880,
"scriptDurationMs": 13.559999999999999,
"eventListeners": 19,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1728.144000000043,
"styleRecalcs": 31,
"styleRecalcDurationMs": 19.856,
"layouts": 6,
"layoutDurationMs": 0.7079999999999999,
"taskDurationMs": 423.57,
"heapDeltaBytes": 3651212,
"heapUsedBytes": 72545512,
"domNodes": 75,
"jsHeapTotalBytes": 4980736,
"scriptDurationMs": 14.406,
"eventListeners": 19,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "dom-widget-clipping",
"durationMs": 743.7199999999962,
"styleRecalcs": 10,
"styleRecalcDurationMs": 7.089000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 439.10099999999994,
"heapDeltaBytes": -7228136,
"heapUsedBytes": 61538444,
"domNodes": 16,
"jsHeapTotalBytes": 6029312,
"scriptDurationMs": 32.947,
"eventListeners": 2,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "dom-widget-clipping",
"durationMs": 729.5950000000175,
"styleRecalcs": 10,
"styleRecalcDurationMs": 6.591999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 448.42400000000004,
"heapDeltaBytes": -6041448,
"heapUsedBytes": 63589352,
"domNodes": 16,
"jsHeapTotalBytes": 6029312,
"scriptDurationMs": 33.624,
"eventListeners": 2,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-idle",
"durationMs": 2049.544000000026,
"styleRecalcs": 4,
"styleRecalcDurationMs": 3.995000000000002,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 643.68,
"heapDeltaBytes": 3498912,
"heapUsedBytes": 86653972,
"domNodes": -280,
"jsHeapTotalBytes": 3104768,
"scriptDurationMs": 40.609,
"eventListeners": -185,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-idle",
"durationMs": 2052.739000000088,
"styleRecalcs": 3,
"styleRecalcDurationMs": 2.8269999999999995,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 668.5199999999999,
"heapDeltaBytes": -18170492,
"heapUsedBytes": 72751196,
"domNodes": -276,
"jsHeapTotalBytes": -1576960,
"scriptDurationMs": 42.112,
"eventListeners": -153,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-pan",
"durationMs": 3236.434000000031,
"styleRecalcs": 62,
"styleRecalcDurationMs": 9.322999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 2662.751,
"heapDeltaBytes": 25957948,
"heapUsedBytes": 90846356,
"domNodes": 0,
"jsHeapTotalBytes": 1273856,
"scriptDurationMs": 924.1930000000001,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-pan",
"durationMs": 3441.6400000000067,
"styleRecalcs": 66,
"styleRecalcDurationMs": 12.58,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 2787.372,
"heapDeltaBytes": -12386728,
"heapUsedBytes": 77732484,
"domNodes": -281,
"jsHeapTotalBytes": 4415488,
"scriptDurationMs": 973.401,
"eventListeners": -181,
"totalBlockingTimeMs": 28,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "large-graph-zoom",
"durationMs": 4516.298000000006,
"styleRecalcs": 66,
"styleRecalcDurationMs": 12.955000000000002,
"layouts": 60,
"layoutDurationMs": 8.549000000000001,
"taskDurationMs": 2738.362,
"heapDeltaBytes": 16482896,
"heapUsedBytes": 88363720,
"domNodes": -235,
"jsHeapTotalBytes": -827392,
"scriptDurationMs": 909.8159999999999,
"eventListeners": -147,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-zoom",
"durationMs": 4574.540999999954,
"styleRecalcs": 66,
"styleRecalcDurationMs": 12.652,
"layouts": 60,
"layoutDurationMs": 8.527,
"taskDurationMs": 2757.661,
"heapDeltaBytes": 8419668,
"heapUsedBytes": 74674152,
"domNodes": 24,
"jsHeapTotalBytes": 2359296,
"scriptDurationMs": 937.826,
"eventListeners": 12,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "legacy-node-drag",
"durationMs": 3388.318999999967,
"styleRecalcs": 41,
"styleRecalcDurationMs": 5.4879999999999995,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 2279.4120000000003,
"heapDeltaBytes": -2298288,
"heapUsedBytes": 70583544,
"domNodes": -287,
"jsHeapTotalBytes": -1613824,
"scriptDurationMs": 229.35300000000004,
"eventListeners": -1,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "legacy-node-drag",
"durationMs": 3178.884000000039,
"styleRecalcs": 41,
"styleRecalcDurationMs": 5.3950000000000005,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 2229.972,
"heapDeltaBytes": 13185800,
"heapUsedBytes": 79408088,
"domNodes": 0,
"jsHeapTotalBytes": 417792,
"scriptDurationMs": 219.03799999999998,
"eventListeners": 188,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "minimap-idle",
"durationMs": 2045.8939999999757,
"styleRecalcs": 4,
"styleRecalcDurationMs": 3.7289999999999996,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 681.7710000000001,
"heapDeltaBytes": -22559928,
"heapUsedBytes": 68931304,
"domNodes": -279,
"jsHeapTotalBytes": 3665920,
"scriptDurationMs": 46.23,
"eventListeners": -185,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "minimap-idle",
"durationMs": 2043.3960000000297,
"styleRecalcs": 4,
"styleRecalcDurationMs": 4.328000000000002,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 716.434,
"heapDeltaBytes": -22419020,
"heapUsedBytes": 68796736,
"domNodes": -281,
"jsHeapTotalBytes": 4190208,
"scriptDurationMs": 48.04299999999999,
"eventListeners": -185,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 782.0720000000279,
"styleRecalcs": 45,
"styleRecalcDurationMs": 9.819999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 562.764,
"heapDeltaBytes": 17828196,
"heapUsedBytes": 88160128,
"domNodes": 16,
"jsHeapTotalBytes": 5767168,
"scriptDurationMs": 147.96,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 784.3900000000303,
"styleRecalcs": 45,
"styleRecalcDurationMs": 9.929,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 558.346,
"heapDeltaBytes": 17929792,
"heapUsedBytes": 88085932,
"domNodes": 16,
"jsHeapTotalBytes": 5767168,
"scriptDurationMs": 145.98899999999998,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-idle",
"durationMs": 2022.5689999999759,
"styleRecalcs": 7,
"styleRecalcDurationMs": 6.12,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 557.959,
"heapDeltaBytes": -8017796,
"heapUsedBytes": 61954780,
"domNodes": -297,
"jsHeapTotalBytes": 5496832,
"scriptDurationMs": 10.107999999999999,
"eventListeners": -201,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "subgraph-idle",
"durationMs": 2037.4049999999215,
"styleRecalcs": 9,
"styleRecalcDurationMs": 8.182,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 559.624,
"heapDeltaBytes": -13408812,
"heapUsedBytes": 56351264,
"domNodes": -295,
"jsHeapTotalBytes": 5234688,
"scriptDurationMs": 9.591000000000003,
"eventListeners": -201,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1857.6069999999731,
"styleRecalcs": 76,
"styleRecalcDurationMs": 38.092,
"layouts": 16,
"layoutDurationMs": 4.802,
"taskDurationMs": 1126.4530000000002,
"heapDeltaBytes": 10338516,
"heapUsedBytes": 80465300,
"domNodes": -295,
"jsHeapTotalBytes": 5234688,
"scriptDurationMs": 114.569,
"eventListeners": -231,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1910.209000000009,
"styleRecalcs": 77,
"styleRecalcDurationMs": 42.074,
"layouts": 16,
"layoutDurationMs": 4.832,
"taskDurationMs": 1154.457,
"heapDeltaBytes": -2753304,
"heapUsedBytes": 67729036,
"domNodes": -297,
"jsHeapTotalBytes": 6021120,
"scriptDurationMs": 117.02799999999999,
"eventListeners": -199,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "subgraph-transition-enter",
"durationMs": 1384.492000000023,
"styleRecalcs": 20,
"styleRecalcDurationMs": 33.67000000000001,
"layouts": 15,
"layoutDurationMs": 13.506,
"taskDurationMs": 988.363,
"heapDeltaBytes": -7464392,
"heapUsedBytes": 84739096,
"domNodes": 13671,
"jsHeapTotalBytes": 10747904,
"scriptDurationMs": 31.424999999999994,
"eventListeners": 2381,
"totalBlockingTimeMs": 131,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "viewport-pan-sweep",
"durationMs": 12421.677999999985,
"styleRecalcs": 246,
"styleRecalcDurationMs": 40.244,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 9568.480000000001,
"heapDeltaBytes": 8651296,
"heapUsedBytes": 91971192,
"domNodes": -281,
"jsHeapTotalBytes": 5132288,
"scriptDurationMs": 3230.7619999999997,
"eventListeners": -159,
"totalBlockingTimeMs": 10,
"frameDurationMs": 16.66333333333326,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "viewport-pan-sweep",
"durationMs": 12596.80800000001,
"styleRecalcs": 246,
"styleRecalcDurationMs": 40.899,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 9724.01,
"heapDeltaBytes": -2715328,
"heapUsedBytes": 80509788,
"domNodes": -284,
"jsHeapTotalBytes": 5394432,
"scriptDurationMs": 3233.708,
"eventListeners": -159,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "vue-large-graph-idle",
"durationMs": 18510.113999999987,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 17984.918999999998,
"heapDeltaBytes": -22244072,
"heapUsedBytes": 187974984,
"domNodes": -6552,
"jsHeapTotalBytes": 1499136,
"scriptDurationMs": 360.45899999999995,
"eventListeners": -7473,
"totalBlockingTimeMs": 1,
"frameDurationMs": 17.773333333333238,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-idle",
"durationMs": 18393.02799999996,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 18008.417999999998,
"heapDeltaBytes": -23211428,
"heapUsedBytes": 182296800,
"domNodes": -6548,
"jsHeapTotalBytes": -1224704,
"scriptDurationMs": 361.05300000000005,
"eventListeners": -7473,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.776666666666642,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-pan",
"durationMs": 22561.847999999998,
"styleRecalcs": 170,
"styleRecalcDurationMs": 23.647999999999975,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 22280.709000000003,
"heapDeltaBytes": -31624244,
"heapUsedBytes": 183313992,
"domNodes": -6548,
"jsHeapTotalBytes": -1708032,
"scriptDurationMs": 960.6740000000001,
"eventListeners": -7469,
"totalBlockingTimeMs": 186,
"frameDurationMs": 17.776666666666642,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-pan",
"durationMs": 23158.303000000047,
"styleRecalcs": 171,
"styleRecalcDurationMs": 26.222000000000023,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 22931.148,
"heapDeltaBytes": -31543444,
"heapUsedBytes": 180334064,
"domNodes": -6548,
"jsHeapTotalBytes": -7516160,
"scriptDurationMs": 963.1160000000001,
"eventListeners": -7469,
"totalBlockingTimeMs": 141,
"frameDurationMs": 17.776666666666763,
"p95FrameDurationMs": 16.700000000004366
},
{
"name": "workflow-execution",
"durationMs": 499.60699999996905,
"styleRecalcs": 18,
"styleRecalcDurationMs": 26.275000000000002,
"layouts": 3,
"layoutDurationMs": 1.3059999999999998,
"taskDurationMs": 151.947,
"heapDeltaBytes": 5820268,
"heapUsedBytes": 72319464,
"domNodes": 148,
"jsHeapTotalBytes": 0,
"scriptDurationMs": 11.276,
"eventListeners": 99,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "workflow-execution",
"durationMs": 124.56600000007256,
"styleRecalcs": 8,
"styleRecalcDurationMs": 17.147000000000002,
"layouts": 3,
"layoutDurationMs": 1.418,
"taskDurationMs": 98.87099999999998,
"heapDeltaBytes": 3276068,
"heapUsedBytes": 69779644,
"domNodes": 130,
"jsHeapTotalBytes": 0,
"scriptDurationMs": 4.749999999999999,
"eventListeners": 25,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
}
]
} |
Codecov Report✅ All modified and coverable lines are covered by tests. @@ Coverage Diff @@
## feature/ecs-migration #15595 +/- ##
========================================================
Coverage ? 82.29%
========================================================
Files ? 1900
Lines ? 107660
Branches ? 33595
========================================================
Hits ? 88599
Misses ? 18732
Partials ? 329
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
…path Replays the two functions the one confirmed-broken pack actually runs (mobcat40/ComfyUI-PromptChain order-chain.js:123 and main.js:507) against the ECS branch. The break is a read divergence, not a rejected write: replaceNodeInputs never rejects on any promptchain sequence. Adds a forced-rejection arm that pins the slotLinks.ts:192 early return, so the claim that a rejected batch abandons the node layout is asserted rather than read off the source.
ce0005c to
e42b301
Compare
Summary
comfyui-promptchain does not break through
slotLinks.ts:192. Its break is a read divergence:{...slot}cannot carrylinkbecauselinkis a prototype accessor, so the pack's own later reads ofslot.linkreturnundefinedand it acts on "nothing is connected". This pins that mechanism, and pins the:192early return separately so the two stop being conflated.Tests only. No production change.
Changes
legacySlotLinkMutations.test.ts, replaying the two functions the pack actually runs —mobcat40/ComfyUI-PromptChainjs/lib/order-chain.js:123(updateInputLabels, thenode.inputs[i] = {...slot}site) andjs/main.js:507(trimEmptyAutogrowSlots, a rawinputs.splicegated oninput.link != null).Three pass, two are
it.failsasserting the wanted behaviour:keeps the link store correct when the pack replaces every slotremoveInputafter it reindexes correctly.never rejects the endpoint batch, though a rejection is detectableremoveInputreturns normally — #15593's claim, asserted.reads the live link id back through a spread copyit.failscopy.linkshould return the live id. Returnsundefined.keeps connected inputs when the pack re-reads slot.linkit.fails.linkasundefinedon every slot, computeskeepCount = 1, and splices off 3 of 4 inputs including all 3 connected ones.keeps every input when the same trim reads live slotsThe control is the point: 3 slots destroyed vs 0, same function, same fixture, one arm known non-zero.
graph.serialize()after that trim still lists all three links targeting input slots the node no longer has, so this reaches the saved workflow.Review Focus
The
:192early return is real but is not promptchain's bug. Across every sequence tried — reentrant slot substitution fromonConnectionsChangeduringremoveInput, rawinputs.splicefollowed byremoveInput, and reconnecting after both —updateEndpointsreturnedokevery time andconsole.error('Failed to replace node inputs')fired 0 times. It stays worth fixing on its own merits; it is not the pack break.Consequence for the shim. A shim that intercepts the write and routes
link/linksmutations does not help here, because promptchain never writeslink— it reads it. Mutation M1 below simulates a shim that rehydrates the assigned plain object into aNodeInputSlot; that one does fix it.Mutation verification
Baseline for this file: 8 passed | 6 expected fail (14).
NodeInputSloton indexed assignment tonode.inputs(a shim simulation)it.failsmarkers flipping to pass: both new ones plus the pre-existingdisconnects through a plain-object input slot. Widened tosrc/lib/litegraph/src/node/+linkStore.test.ts+LLink.store.test.ts: 3 failed | 124 passed | 3 expected fail (130) — same three markers, no genuine regression.return []atslotLinks.ts:194so the rejection falls throughnever rejects the endpoint batch, on the layout assertion.removalsfrom the endpoint batch inreplaceNodeInputskeeps the link store correct.Each reverted; baseline restored and re-run green after each.
Both
it.failsmarkers were checked by flipping them toit: both fail onAssertionError, never on aTypeError. The first draft of one of them passed onTypeError: source.getOutputLinks is not a functionand was rewritten.Gates
oxfmt --check,oxlint --type-aware(verified non-vacuous against a deliberately bad file: exit 1),knipexit 0,vue-tsc --noEmitat 8GB: 0 errors on anysrc/lib/litegraph/path. The 1418TS2688plus 68 implicit-any errors it reports are the known symlinked-node_modulesartifact, all in unrelated.vuefiles.