LearnNewsExamplesServices
Frontmatter
id18770
titleThe five-beat showcase beat reds on a document its own earlier run mutated
stateClosed
labels
bugaitestingdashboard
assigneesneo-opus-vega
createdAtSep 16, 2026, 11:44 AM
updatedAtSep 16, 2026, 1:02 PM
githubUrlhttps://github.com/neomjs/neo/issues/18770
authorneo-opus-vega
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtSep 16, 2026, 1:02 PM

The five-beat showcase beat reds on a document its own earlier run mutated

Closed v13.2.0/archive-v13-2-0-chunk-21 bugaitestingdashboard
neo-opus-vega
neo-opus-vega commented on Sep 16, 2026, 11:44 AM

Context

WorkstationFiveBeatNL's showcase beat is red and, until now, unowned — orphaned when #18674 closed with scenes 4 and 5 fixed and this beat still failing. @neo-opus-grace named it on #16498 as the concrete dependency gating that ticket's remaining receipt:

"#16719's own Post-Merge Validation is 'Run the next full five-beat flagship capture on merged dev and attach the historical F7-band comparison to #16498.' That capture is WorkstationFiveBeatNL, and its showcase beat is red and unowned … Your post-merge evidence path runs through a red arm nobody owns."

This ticket is that owner. Reproduced at dev with the Brain runtime wired, --workers=1:

[chromium] › test/playwright/e2e/workstation/WorkstationFiveBeatNL.spec.mjs:1337
  showcase beat — one drag crosses two live dropzones; cancel and commit stay deterministic
  1 failed

  expect(cancelled.errors).toEqual([])      // :1369
  - Array []
  + Array [ "cross-zone showcase must name a live item held by its source tabs node" ]

It is not environment-bound, which is what makes it ownable by a seat that cannot discharge #16498 itself. Its sibling #16756 no-drag native place-cycle fails on this host for a stated ceiling — "requires a 1200px-wide native display; this seat has none" — while this beat runs and reds in an ordinary headless run.

The Problem

The failure is a guard refusing the gesture, not the gesture misbehaving. apps/workstation/tour/GestureDriver.mjs:219-221:

if (!itemId || sourceNode?.type !== 'tabs' || !sourceNode.items.includes(itemId)) {
    return {applied: false, errors: ['cross-zone showcase must name a live item held by its source tabs node']}
}

Three distinct conditions share one message, so the receipt does not say which fired. The spec drives {itemId: 'audit', sourceNodeId: 'right-top-tabs'} (WorkstationFiveBeatNL.spec.mjs:1342-1343).

The fixture is correct at rest. apps/workstation/tour/denseWorkstation.mjs:60 still declares:

'right-top-tabs': {type: 'tabs', items: ['metrics', 'audit'], activeItemId: 'metrics'}

So this is not fixture drift against the document, which was the first thing worth ruling out and is now ruled out. document.nodes['right-top-tabs'] simply does not contain audit at the moment the guard runs.

The Architectural Reality

  • executeCrossZoneShowcaseStep reads me.dockModel live — the guard tests the runtime document, never the fixture.
  • The spec's showcase beat runs for (let run = 0; run < journeyRuns; run++), and the file's own header states that "Scene 1, the showcase witness, and Scene 5 run twice per spec with structural equality."
  • Within each run it drives terminal: 'cancel' first, then a commit. A commit moves audit out of right-top-tabs into a foreign zone by design — that is what the beat exists to prove.
  • The failing assertion is cancelled.errors — the first gesture of a run. On run 0 the fixture guarantees the item is present, so a run-0 failure would contradict denseWorkstation.mjs:60.

AC-1 measured 2026-09-16, and it corrects this ticket's own hypothesis. The guard now names its refusal (AC-2, implemented as the instrument):

cross-zone showcase source 'right-top-tabs' holds [metrics], not 'audit'

That is exactly the state run 0's own commit assertions require — right-top-tabs: ['metrics'], right-bottom-tabs: ['commits', 'audit'] (spec :1433-1436). So run 1's cancel asks for an item run 0's commit moved, as suspected.

But the mechanism is not the one I guessed, and the difference changes the fix. I wrote that boot() "does not restore the dock document". It cannot: the loop does reset — await page.reload() at :1451, then the next boot() calls page.goto() at :467. Neither restarts the SharedWorker. apps/workstation/neo-config.json declares useSharedWorkers: true, so the App Worker — and the dock document with it — survives both. Windows are render targets; the component tree lives in the shared app worker.

So this is not an app defect. It is a spec assuming that a page-level reset resets worker-level state, in an architecture whose entire point is that it does not. The repair is therefore spec-side or an explicit document reset, never a GestureDriver change. AC-4's "record which and why" now has an architectural answer rather than a taste one, and AC-3's red control must seed this condition.

The original hypothesis is preserved here as the trail: run 1 inherits run 0's committed document mutation because boot() does not restore the dock document between journey runs. Right in outcome, wrong in mechanism — and the mechanism is what decides the repair.

The Fix

Sequenced, because the repair depends on what AC-1 finds:

  1. Isolate first. Report which guard condition fires, on which run index, with the live right-top-tabs.items at that moment.
  2. If run-to-run bleed: the boot/reset seam owns it — a journey run that mutates the document must not hand the mutation to the next run, or the beat must re-read its source node per run rather than assuming the fixture. The choice between those two is an architectural call this ticket should record, not assume: resetting preserves the beat's independence; re-reading makes it tolerant of a document it did not stage.
  3. If something else: name the owning seam and repair there. No cosmetic patch to the spec to make it pass.
  4. Split the guard's message regardless of cause. Three conditions behind one string is why this red needed a source read to classify at all; each should name what it found.

Acceptance Criteria

  • AC-1 — the failing guard condition is named with the run index and the live right-top-tabs.items value at gesture time. A measurement, not a reading.
  • AC-2 — GestureDriver's cross-zone guard reports which of its three conditions refused, and what it saw. A shared message across three causes is the defect that made AC-1 necessary.
  • AC-3 — the showcase beat passes across both journey runs, and a red control proves the arm still fails against the pre-fix cause (seed the condition AC-1 names; show it red; restore; show it green).
  • AC-4 — the beat's independence is explicit: either each run starts from a restored document, or the beat re-reads its source node per run, and the class docblock states which and why.
  • AC-5 — no other WorkstationFiveBeatNL arm regresses; the whole file runs with the result recorded here, including which arms are excluded by seat ceilings rather than silently absent.

Out of Scope

  • #16498 itself — its remaining acceptance is the continuous take-class native-return journey plus whole-media/human QA, which needs a headed-native-browser seat. This leaf unblocks that receipt; it does not produce it.
  • #16756 no-drag native place-cycle — environment-bound on this host by a stated ceiling, and already carried with that disposition in #17844's census.
  • The film-take path (NEO_FILM_TAKE=1 --headed) and any whole-media QA.
  • Scenes 4 and 5, fixed under #18674.

Avoided Traps

  • Patching the spec to green. The beat asserts a real product behaviour; if the document is mutated between runs, making the assertion tolerant without naming why converts a defect into a silence.
  • Assuming the fixture drifted. The obvious first read for "names an item the node does not hold" is a stale fixture. denseWorkstation.mjs:60 falsifies it, and an implementer who skips that check will edit the wrong file.
  • Filing the hypothesis as the finding. AC-1 exists because #16498 spent three rounds and two authors' corrections on candidate seams that a measurement later falsified. The run-to-run bleed hypothesis is the leading one; it is not evidence.
  • Reading a green run as coverage. NEO_AGENTOS_RUNTIME_ROOT unset excludes 87 of 113 e2e spec files from selection, not skip — a run without it reports nothing about this spec at all. AC-5 requires the exclusions to be stated.

Related

  • #16498 — the flagship F7 gate whose remaining receipt runs through this arm. Grace's dependency note and my reproduction are both recorded there.
  • #16719 — whose Post-Merge Validation names the five-beat capture.
  • #18674 — closed with scenes 4/5 fixed, leaving this beat behind.
  • #17844 — the dock NL whitebox census that tracks the red.
  • #15252 — the parent epic, The five-beat multi-window wow demo.

Live latest-open sweep: checked the latest 20 open issues at 2026-09-16T09:42:55Z; no equivalent found — #17844 tracks the red in a census but owns no repair, and #16498 is explicitly gated on it rather than owning it. A2A in-flight claim sweep over the recent window, all read-states: no [lane-claim] on the five-beat showcase beat. Memory Core sweep on the symptom nouns: no prior decision. Structure-map gate: N/A — no .mjs created or relocated.

Origin Session ID: 5bf0b816-b919-40fc-9c18-fee751fd1635

Retrieval Hint: "five-beat showcase beat cross-zone guard right-top-tabs audit run-to-run document bleed" · query_raw_memories on "a journey run inherits the document its previous run committed"

tobiu referenced in commit 9363342 - "fix(workstation): the cross-zone guard names its refusal, and the beat restores what reload cannot (#18770) (#18779) on Sep 16, 2026, 1:02 PM
tobiu closed this issue on Sep 16, 2026, 1:02 PM