Context
test/playwright/unit/core/VdomDestroyCancellation.spec.mjs:32 reds intermittently under full unit-suite load. Surfaced while measuring something else (#18275's fix), so it was first checked for attribution: 2/2 red on unchanged dev, 1/2 with the #18275 patch, and 10/10 green in isolation both ways. Pre-existing, not introduced.
Operator asked for a closer look. What that found is not (yet) an engine defect — it is that the arm cannot tell an engine defect from ambient traffic, which is why the intermittent has stayed unownable.
Live latest-open sweep: checked the latest 20 open issues at 2026-09-08T21:10Z; no equivalent found. A2A in-flight claim sweep over the last 30 messages (all read-states): no overlapping [lane-claim]. Corpus grep for VdomDestroyCancellation hits three archived PR bodies only. Distinct from #18487 (Maximize, a different spec) and from #18439 (e2e tier, different suite).
The Problem
The failure signature is stable and specific — captured at dev:
Error: a stale success payload from a destroyed flight must apply ZERO deltas
Expected: 0
Received: 1
> 104 | expect(deltaCalls, '…must apply ZERO deltas').toBe(0)
The arm builds two global monkey-patches, and both are wider than the contract it states.
1. The counter is process-wide. Neo.applyDeltas is replaced globally and deltaCalls increments on every call from anywhere:
Neo.applyDeltas = function(...args) {
deltaCalls++;
return realApplyDeltas?.apply(this, args)
};The assertion reads as "this stale payload applied no deltas." What it measures is "no component anywhere in this process applied any delta during these 20ms." Neo is module-global and a Playwright worker runs spec files sequentially in one process, so a prior file's un-awaited async update landing in the window is indistinguishable from the leak under test. Received: 1 therefore does not identify a culprit — which is exactly why nobody has been able to action this.
This is the same instrument shape that produced a wrong magnitude on #18275, where a file-shared static counter carried constructions from earlier arms.
2. One mocked promise is handed to every caller. While armed, updateBatch returns the same promise regardless of who asks:
VdomHelper.updateBatch = function(data) {
return armed ? armed.promise : realUpdateBatch.call(this, data)
};Any component reaching updateBatch during the armed window receives the destroyed child's stale payload and, being alive, applies it through a correctly-unguarded continuation — VdomLifecycle.mjs:342's if (me.id && !me.isDestroyed) gates on the initiator, so a live joiner passes it legitimately. In production each caller gets its own payload; here they share one. Measured on a green run by instrumenting the mock: armedCallers: ["vdc-child"] — only the child joins today, so this is currently latent rather than firing. It is one ancestor-timing change away from being the cause, and no arm would say so.
The Architectural Reality
src/mixin/VdomLifecycle.mjs:342 — the guard under test, and it is correct: if (me.id && !me.isDestroyed) blocks both the delta application and the vnode distribution for a destroyed initiator.
src/component/Base.mjs:1326 and :1866 — the only other applyDeltas emitters on a destroy/unmount path. Both are synchronous and both fall outside the measured window (child.destroy() precedes the deltaCalls = 0 reset; parent.destroy() runs in the finally, after the assertion). So neither explains Received: 1.
- The window is two fixed
setTimeout(20) waits. They are not the defect — the arm fails on a count, not on an assertion that ran early.
What is established, and what is not
Established: the arm's two instruments are broader than the contract; the guard at :342 is correct; the two destroy-path emitters are outside the window; the failure is a count of 1 with no identity attached.
Not established: whether a real engine leak exists. One Received: 1 was captured today; every attempt to re-catch it with a diagnostic attached has been green — 5 default-worker runs, 3 at --workers=1, 3 over the spec's own directory, 8 more full runs. An earlier single --workers=1 red was not identified to a test and is discarded rather than argued from.
The rate drifted from ~50% this morning to 0/19 this evening on unchanged source, so sampling harder is the wrong instrument — the between-sample variance exceeds the effect, which is the trap this repo has already paid for on #18275.
The Fix
Make the arm name what it caught, without weakening it.
- Record every applied payload, not just a count, and assert on deltas that reference the destroyed component — the contract is about this flight's payload, not about process-wide quiet.
- Carry the full recorded log in the assertion message, so the next occurrence is self-diagnosing on a CI runner where nobody can attach a session.
- Scope the
updateBatch mock to the child's own batch, so a joiner cannot receive another component's stale payload. Assert the joiner set, so a future ancestor-timing change trips an arm instead of silently becoming the cause.
- Then re-measure. If the arm still reds, it now names the culprit and a real defect can be filed against evidence. If it stops, the intermittent was ambient traffic and the guard was never in question.
Acceptance Criteria
Out of Scope
- Fixing any engine leak this uncovers. No leak is established. If AC-5 surfaces one it gets its own ticket with the payload as evidence.
- The two fixed 20ms waits. They are load-bearing for the flight-departure sequencing and are not what fails; churning them would be an unmeasured change to a spec already under suspicion.
- #18487 (Maximize) and #18439 (e2e BigData). Different specs, different suites; named only so a reader does not merge three intermittents into one.
- Quarantining the arm. It guards a real cancellation boundary and has an owner. Repair beats skip.
Avoided Traps
- "It is a flaky sleep, widen the timeout." The arm fails on
Received: 1, not on an assertion racing a pending update. Widening the window would make a wrong count more likely, not less.
- "It went green 19 times, it is fixed." Nothing was changed in those 19 runs. Absence at an unstable rate is not evidence, and this ticket exists partly because that inference is available and wrong.
- "Received: 1 proves the engine leaks." It proves one delta applied somewhere in the process. The instrument cannot say whose, which is the actual finding.
Decision Record impact
none.
Related
- #18275 (same over-broad-counter instrument shape, and where this surfaced)
- #18487 (a different pre-existing intermittent — Maximize)
- #18439 (e2e tier intermittents under load)
- #12986 (the vdom delta-stream contract epic)
Origin Session ID: 69ff8d6f-0e9e-4c44-aff9-e8007f4d7090
Retrieval Hint: query_raw_memories("VdomDestroyCancellation zero deltas applyDeltas process-wide counter armed promise shared joiner")
Authored by ⚖️ Ada · @neo-opus-ada · Claude Opus 5 · Claude Code
Context
test/playwright/unit/core/VdomDestroyCancellation.spec.mjs:32reds intermittently under full unit-suite load. Surfaced while measuring something else (#18275's fix), so it was first checked for attribution: 2/2 red on unchangeddev, 1/2 with the #18275 patch, and 10/10 green in isolation both ways. Pre-existing, not introduced.Operator asked for a closer look. What that found is not (yet) an engine defect — it is that the arm cannot tell an engine defect from ambient traffic, which is why the intermittent has stayed unownable.
Live latest-open sweep: checked the latest 20 open issues at 2026-09-08T21:10Z; no equivalent found.A2A in-flight claim sweep over the last 30 messages (all read-states): no overlapping[lane-claim]. Corpus grep forVdomDestroyCancellationhits three archived PR bodies only. Distinct from #18487 (Maximize, a different spec) and from #18439 (e2e tier, different suite).The Problem
The failure signature is stable and specific — captured at
dev:The arm builds two global monkey-patches, and both are wider than the contract it states.
1. The counter is process-wide.
Neo.applyDeltasis replaced globally anddeltaCallsincrements on every call from anywhere:Neo.applyDeltas = function(...args) { deltaCalls++; return realApplyDeltas?.apply(this, args) };The assertion reads as "this stale payload applied no deltas." What it measures is "no component anywhere in this process applied any delta during these 20ms."
Neois module-global and a Playwright worker runs spec files sequentially in one process, so a prior file's un-awaited async update landing in the window is indistinguishable from the leak under test.Received: 1therefore does not identify a culprit — which is exactly why nobody has been able to action this.This is the same instrument shape that produced a wrong magnitude on #18275, where a file-shared static counter carried constructions from earlier arms.
2. One mocked promise is handed to every caller. While armed,
updateBatchreturns the same promise regardless of who asks:VdomHelper.updateBatch = function(data) { return armed ? armed.promise : realUpdateBatch.call(this, data) };Any component reaching
updateBatchduring the armed window receives the destroyed child's stale payload and, being alive, applies it through a correctly-unguarded continuation —VdomLifecycle.mjs:342'sif (me.id && !me.isDestroyed)gates on the initiator, so a live joiner passes it legitimately. In production each caller gets its own payload; here they share one. Measured on a green run by instrumenting the mock:armedCallers: ["vdc-child"]— only the child joins today, so this is currently latent rather than firing. It is one ancestor-timing change away from being the cause, and no arm would say so.The Architectural Reality
src/mixin/VdomLifecycle.mjs:342— the guard under test, and it is correct:if (me.id && !me.isDestroyed)blocks both the delta application and the vnode distribution for a destroyed initiator.src/component/Base.mjs:1326and:1866— the only otherapplyDeltasemitters on a destroy/unmount path. Both are synchronous and both fall outside the measured window (child.destroy()precedes thedeltaCalls = 0reset;parent.destroy()runs in thefinally, after the assertion). So neither explainsReceived: 1.setTimeout(20)waits. They are not the defect — the arm fails on a count, not on an assertion that ran early.What is established, and what is not
Established: the arm's two instruments are broader than the contract; the guard at
:342is correct; the two destroy-path emitters are outside the window; the failure is a count of 1 with no identity attached.Not established: whether a real engine leak exists. One
Received: 1was captured today; every attempt to re-catch it with a diagnostic attached has been green — 5 default-worker runs, 3 at--workers=1, 3 over the spec's own directory, 8 more full runs. An earlier single--workers=1red was not identified to a test and is discarded rather than argued from.The rate drifted from ~50% this morning to 0/19 this evening on unchanged source, so sampling harder is the wrong instrument — the between-sample variance exceeds the effect, which is the trap this repo has already paid for on #18275.
The Fix
Make the arm name what it caught, without weakening it.
updateBatchmock to the child's own batch, so a joiner cannot receive another component's stale payload. Assert the joiner set, so a future ancestor-timing change trips an arm instead of silently becoming the cause.Acceptance Criteria
updateBatchmock serves the armed promise only to the child's own batch; a second caller during the armed window is asserted rather than silently joined.Out of Scope
Avoided Traps
Received: 1, not on an assertion racing a pending update. Widening the window would make a wrong count more likely, not less.Decision Record impact
none.
Related
Origin Session ID: 69ff8d6f-0e9e-4c44-aff9-e8007f4d7090
Retrieval Hint:
query_raw_memories("VdomDestroyCancellation zero deltas applyDeltas process-wide counter armed promise shared joiner")Authored by ⚖️ Ada ·
@neo-opus-ada· Claude Opus 5 · Claude Code