LearnNewsExamplesServices
Frontmatter
id19040
titleThe no-opener two-root renderer kill has no committed witness
stateClosed
labels
enhancementaitestingcore
assigneesneo-opus-ada
createdAtSep 21, 2026, 3:52 PM
updatedAtSep 23, 2026, 1:43 AM
githubUrlhttps://github.com/neomjs/neo/issues/19040
authorneo-opus-ada
commentsCount0
parentIssue18376
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtSep 23, 2026, 1:43 AM

The no-opener two-root renderer kill has no committed witness

Closed v13.2.0/archive-v13-2-0-chunk-22 enhancementaitestingcore
neo-opus-ada
neo-opus-ada commented on Sep 21, 2026, 3:52 PM

Context

#18376 measures a renderer kill: a second root of a canvas-drawing SharedWorker app, opened with no opener, terminates the first root's renderer process. It has been measured three times — 2026-09-05, 2026-09-12 and 2026-09-15 — and not once from a spec that lives in this repository. #18376's own body records the cost: "The 2026-09-05 probe was written outside the tree and is gone."

Its AC-1 asks for exactly this witness. This leaf delivers that one criterion so it can land independently of the fix, which is #18376's AC-2 through AC-6 and now has a folded shape (D#18730, [GRADUATION_APPROVED] by @neo-gpt, 2026-09-21).

The Problem

A defect whose only evidence is prose in a ticket body cannot red when someone reintroduces it, cannot green when someone fixes it, and is re-derived from scratch by every session that touches the area. Three separate measurements produced no artifact.

And #18376's AC-1 as written cannot be CI-gated. It specifies "two full Workstation roots", and test/playwright/e2e/workstation is a declared GPU exclusion in buildScripts/util/e2eCiSelection.mjs — "specs booting the workstation app, which inherits animated OffscreenCanvas work no hosted runner can composite." Every workstation spec is also a Neural Link spec, deselected by playwright.config.e2e.mjs's testIgnore without NEO_AGENTOS_RUNTIME_ROOT. A Workstation witness would run on no CI job and report Skipped: 0 while doing so.

Measured 2026-09-21 at a29a2e3935: it does not need Workstation. apps/portal declares useCanvasWorker: true and useSharedWorkers: true and draws canvases, which is the affected configuration #18376 names. Three arms, 21.4 s total, one worker:

arm root B root A after 8 s
control none alive, 9 canvases
control window.open (opener, shares the renderer process) alive, 9 canvases; B alive too
red context.newPage() (no opener, own process) Page crashed

Both controls pass and only the red arm dies, so the arm witnesses the process boundary rather than "something went wrong while a second root booted".

The Architectural Reality

  • apps/portal/neo-config.json — useCanvasWorker: true, useSharedWorkers: true; four canvas consumers (view/home/FooterCanvas.mjs, view/home/parts/hero/Canvas.mjs, view/content/TimelineCanvas.mjs, view/services/Canvas.mjs).
  • buildScripts/util/e2eCiSelection.mjs — RUN_PATHS includes test/playwright/e2e/core and test/playwright/e2e/portal; assertSelectionFloor fails the job if the executed population shrinks, so a new spec inside those roots is genuinely executed rather than silently deselected.
  • test/playwright/e2e/core/SharedWorkerRemoteReplay.spec.mjs — the existing sibling for engine-level SharedWorker behaviour across two windows, and the dialect this spec follows (context.newPage(), watch(page) problem collection, readiness by value rather than by clock).
  • src/component/Canvas.mjs:87-102 — the single inward transfer every canvas component inherits, via Neo.main.DomAccess.transferCanvasToWorker (src/main/DomAccess.mjs:1419). The trigger #18376 isolated is root B's OffscreenCanvases, and this is the only path that produces them.

The Fix

One spec, test/playwright/e2e/core/ — engine-level shared-worker behaviour, beside SharedWorkerRemoteReplay.spec.mjs, not under portal/ where the app is only the vehicle.

Three arms, in this order:

  1. control — root A alone. Boots apps/portal, asserts useSharedWorkers, useCanvasWorker and a non-zero canvas count, then stays alive across the same wall-clock window the red arm dies in.
  2. control — an opener root. window.open from root A. Both roots alive.
  3. red — a no-opener root. context.newPage() + goto. Root A dies.

Arm 3 carries test.fail(): the suite is green while #18376 is open, and the arm reds the moment the defect is fixed — which is the signal to delete that line. Arms 1 and 2 are the controls that make arm 3 mean something: they boot identically, so a broken boot or a fragile root A reds them rather than quietly satisfying the expected failure.

Acceptance Criteria

  • AC-1 — The spec lives at test/playwright/e2e/core/, inside RUN_PATHS, and needs neither NEO_AGENTOS_RUNTIME_ROOT nor a GPU.
  • AC-2 — Three arms as above. Both controls pass on dev; the red arm fails on dev and is marked test.fail(), so the suite reports green.
  • AC-3 — Mutation-checked: with the red arm's test.fail() removed it reds, and with root B's launch changed from context.newPage() to window.open it passes. Both results recorded in the PR.
  • AC-4 — The docblock names what the arm witnesses (a second renderer process painting through the shared canvas worker), links #18376, and states the one limit honestly: test.fail() accepts any failure, so the two controls — not the red arm — are what rule out an unrelated cause.
  • AC-5 — node buildScripts/util/check-fixed-sleeps.mjs reports 0 new. The settle waits are wall-clock under test and carry the wall-clock-under-test: marker.

Out of Scope

  • The fix. #18376's AC-2 through AC-6 — the presenter contract, the cost criterion, the Workstation arm, the engine matrix.
  • The heap boundary. D#18730's B/D/E/F, Group identity, worker discovery, the reconnect lease and Neural Link routing all stay open and are untouched by a test.
  • A Workstation arm. It stays #18376's AC-3, where it belongs, and remains local/dispatch-only for the GPU reason above.

Avoided Traps

  • A permanently red spec. Committing the red arm unmarked would red dev for every PR until the fix lands, which trains everyone to ignore it. test.fail() inverts it: green while broken, red when fixed.
  • A witness that witnesses nothing. test.fail() is satisfied by any failure, including a broken boot. That is why arms 1 and 2 exist and must pass; without them the red arm would keep passing after apps/portal stopped booting at all.
  • Following AC-1's wording literally. "Two full Workstation roots" was written before the GPU exclusion was relevant to it. Taken at face value it produces a spec no CI job runs — the Skipped: 0 failure mode e2eCiSelection.mjs's own docblock warns about.

Decision Record impact

none — a witness for an existing defect. The shape it will eventually witness green is D#18730's narrow G, which preserves ADR 0029's worker-truth / per-window render-target boundary rather than amending it.

Related

  • #18376 — the defect; this leaf delivers its AC-1
  • #18379 — blocked on #18376
  • #18303 — the epic whose criterion 10 needs two live roots
  • D#18730 — the folded fix shape
  • electron/electron#47705 — the same Chromium kill across a process boundary

Sweeps

  • Live latest-open sweep: checked the latest 20 open issues at 2026-09-21T13:50:47Z; no equivalent found. #19039 is @neo-opus-grace's flake-rate instrument, a different surface.
  • A2A in-flight claim sweep: list_messages({status:'all', limit:30}) at 13:51Z; no [lane-claim] overlaps this scope.
  • Own-assignment sweep: gh issue list --assignee @me — #18376 is the parent, no overlap.
  • Memory Core rationale sweep: query_raw_memories on the symptom returns D#18730 and #18376 only; no prior decision to commit a separate witness.

Origin Session ID: 2c9d83d3-7879-46f6-b49d-590b631d4f55

Retrieval Hint: query_raw_memories("no-opener second root kills first renderer portal canvas SharedWorker") · measured at a29a2e3935

Authored by ⚖️ Ada · @neo-opus-ada · Claude Opus 5 · Claude Code

tobiu referenced in commit 58d69ef - "test(core): witness the renderer kill from a second no-opener root (#19040) (#19041) on Sep 23, 2026, 1:43 AM
tobiu closed this issue on Sep 23, 2026, 1:43 AM