LearnNewsExamplesServices
Frontmatter
id16309
titleFive-beat stack return fails headless: main preview never publishes
stateClosed
labels
bugaitestingregression
assigneesneo-kimi-iris
createdAtAug 2, 2026, 12:24 AM
updatedAtAug 2, 2026, 3:32 AM
githubUrlhttps://github.com/neomjs/neo/issues/16309
authorneo-fable
commentsCount5
parentIssue15252
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 2, 2026, 3:32 AM

Five-beat stack return fails headless: main preview never publishes

Closed Backlog/active-chunk-11 bugaitestingregression
neo-fable
neo-fable commented on Aug 2, 2026, 12:24 AM

Context

During post-gap verification of the five-beat journey at dev head 3b3a614564 (2026-08-01, working tree served by the suite's own webpack server — the running-container plane lag from D#16304 does NOT apply to this receipt), the default headless run of test/playwright/e2e/workstation/WorkstationFiveBeatNL.spec.mjs fails 2/10: scene 4 (reintegration) and scene 5 (signature) — both at the same leg, executeStackReturnStep. The other 6 pass; 2 skips are contracted (headed-only continuity witness, macOS+film native titlebar).

Deterministic across 2 full-suite runs + 1 isolated run (--grep reintegration), identical receipt each time.

  • Live latest-open sweep: latest 20 open issues checked 2026-08-01T22:33Z — no equivalent found.
  • A2A in-flight claim sweep: last 15 messages checked same minute — no competing claim on this scope.
  • Filed under the #15252 production lane: the recorded journey derives from this spec, so a red return leg blocks take eligibility (and the "local green receipt" gate Emmy's voice/API boundary waits on).

The Problem

The return gesture arms in the source vessel, engages the main participation target, and wins arbitration — yet the semantic preview never publishes, so the executor's readiness poll exhausts attempts, cancels the gesture, and returns applied: false with 'main workspace did not reach one semantic + rendered stack-return claim'.

The receipt, identical across all three observations:

{"claimCount":1,"converted":false,"engaged":true,"indicators":null,"parkedItemId":null,
 "preview":null,"rendered":null,"sourceVesselConnected":false,"sourceVesselWindowId":null,
 "targetProxy":null,"targetWorkspaceId":"workstation-main","winnerStableId":"workstation-main",
 "ready":false}

(parkReceipt omitted above: it is the stale dock-leg receipt — an FYI field — showing sourceInner === targetInner === {320×240 @ 480,360}: headless popups share identical synthetic geometry, so screen-rect discrimination between vessel windows is degenerate in this mode.)

Reproducer, from repo root:

npx playwright test workstation/WorkstationFiveBeatNL -c test/playwright/playwright.config.e2e.mjs --grep reintegration

The Architectural Reality

  • executeStackReturnStep (apps/workstation/view/Workspace.mjs:4348) drives synthetic pointer events into the source vessel and polls readCrossWindowGestureSnapshot({sourceZone, targetWorkspaceId: 'workstation-main'}) (:3967) until ready.
  • ready in this no-parkedItemId form (:4015) requires claimCount === 1 + engaged + winner + preview.previewId + matching rendered.previewId + matching indicators.activePreviewId. The failing snapshot satisfies the first three and none of the preview trio.
  • The semantic preview is crossWindowParticipations.get('workstation-main').target.currentPreview; the rendered/indicator pair comes from me.dragAffordances. All three are null while engaged is true — the target zone computes no placement candidate.
  • Conversion gating: DockTabSortZone feeds createVesselConversionSensor (src/dashboard/DockVesselConversion.mjs:138) with {pointerInTarget, sourceRect, targetRect}; convert-in needs pointerInTarget && min-axis overlap ≥ 0.55 with fail-closed degenerate-rect handling. The snapshot's converted: false says this never fired for the return leg.

Regression window. The last recorded full-journey semantic receipt is exact head e981b57d0b (take-17, 2026-07-28, #15252 comment). Commits after it touching this seam:

  • 8c0badb9a4 (#16133 re-entry drag ownership — DockTabSortZone)
  • 973863610c (#16137 popup-over-popup proxies — DragDrop.mjs +1134, Workspace +328, DragCoordinator)
  • 9e6438242d (#16140 native titlebar reintegration — DragCoordinator +410, CrossWindowDragTarget, participation, and +674 lines of this spec: scene 4's current form postdates the last known green)
  • eb18119845 (#16144), 0d8e23e141 (#16147), 3171e00a89 (#16154), 5c5fe058c3 (#16156 dashboard tear-out projection retention)

Caveat: with #16151 open (headed E2E launches abort in macOS app registration), recent verification may have been mode-asymmetric — scene 4 headless may not have been green on any host since #16140. The bisect must establish the actual last-green pair, not assume e981b57d0b.

Hypotheses (labeled, not asserted — each with its falsifier)

  • H1 — stale/mis-bound conversion target: vesselConversionTargetWindowId still points at the dock-leg popup rather than main during the return leg, so the park/conversion choreography runs against the wrong window. Falsifier: log vesselConversionTargetWindowId at return-arm time; healthy = me.windowId (main).
  • H2 — headless degenerate geometry starves the sensor: with popups at identical synthetic rects and the executor's pointer path geometrically inside both, pointerInTarget or the overlap ratio never crosses 0.55 for the main target → converted stays false → the affordances/preview chain never opens. Falsifier: sample-log {pointerInTarget, rx, ry, composed} for the return sortZone's sensor during the poll loop.
  • H3 — spec/app contract drift from the #16140 spec rewrite: the return snapshot is consumed without parkedItemId while the app publishes the preview trio only on converted — i.e. the spec's contract moved ahead of (or apart from) the app seam. Falsifier: bisect with contemporary spec+app pairs.

The Fix

Bisect the window with contemporary spec+app pairs (git worktree per candidate head, symlinked node_modules, isolated --grep reintegration run ≈ 40s each). Identify the first red pair, then fix at the seam the bisect convicts — executor, sensor feed, or participation preview publication. Implementation-agnostic until the bisect lands; the receipts decide.

Acceptance Criteria

  • Root cause named with a receipt (sensor sample log or equivalent worker-truth evidence), not inference.
  • Scene 4 (reintegration) green headless at dev head, isolated and in-suite.
  • Scene 5 (signature) green headless: two-take beat-log equality restored end-to-end.
  • No regression in the currently-green six (scene 1, showcase ×2, scene 2 commit + morph, scene 3) — full-suite receipt on the PR.
  • If the conviction is spec-side contract drift (H3), the fix preserves the film-mode contract (ready/go/receipt chain + film pacing untouched or re-receipted).
  • Post-merge flag: headed spot-check documented on the PR or follow-up comment once a headed-capable session exists (#16151 constraint acknowledged).

Out of Scope

  • The headed-launch abort itself (#16151, owned by @neo-gpt-emmy).
  • Film take execution, narrative, and voice work (continue under #15252).
  • The running-plane revision-lag governance (D#16304).

Related

#15252 (production lane — this blocks take eligibility) · #16035 (journey completion) · #16151 (headed-launch abort, verification asymmetry) · #16133 #16137 #16140 #16144 #16147 #16154 #16156 (regression window) · #15906 (cross-window wiring origin)

Origin Session ID: 355d67d5-9abc-4497-a9e8-937265636376 Retrieval Hint: "five-beat stack return headless preview never publishes" · npx playwright test workstation/WorkstationFiveBeatNL -c test/playwright/playwright.config.e2e.mjs --grep reintegration

tobiu referenced in commit acbb6f2 - "fix(workstation): publish the cross-window stack-return preview trio (#16309) (#16321) on Aug 2, 2026, 3:32 AM
tobiu closed this issue on Aug 2, 2026, 3:32 AM