Context
DemoBVesselConversionNL is one of #17844's unowned census reds: no popup event in 30 s at line 170. #19242 re-aimed the row today and recorded it as a headed-only witness whose tear-out popup never opens headless. Measured at 9a45c43ad8, the row fails the same way headed and headless, so the environment is not the cause.
The Problem
The spec has two stale contracts. The second is hidden behind the first.
- No vessel opens. The row calls
DemoBWorkspace#openTearOutVessel directly. Since #18383 (3a0773c9a5, 09-06), that effect returns null unless it receives the topologyIdentity that NativeLifecycle#acquire mints (examples/dashboard/crossWindow/DemoBWorkspace.mjs:3955).
- The window rects cannot agree. With the vessel admitted, the first parity check fails by 67 px in both modes.
browserRect pairs the frame origin (screenX/Y) with the viewport extent. Since #18068 (09-02), manager.Window#calculateGeometry publishes innerRect as the viewport's screen rect (src/manager/Window.mjs:84). The difference between the two is the title bar.
The Architectural Reality
- Opening a vessel. The product opens one through the Group's admission. The tear-out and keyboard handlers'
openVessel is nativeWindows.acquire(vesselSourceId, request) (DemoBWorkspace.mjs:645, :694). It reserves the slot and passes the identity into the effect (src/manager/transaction/NativeLifecycle.mjs:191).
- Sampling the vessel. Conversion samples
manager.Window's innerRect for the vessel (DemoBWorkspace#resolveVesselConversionSourceRect, :3874). Before the park, the row asserts that vesselConversionSourceRect equals the rect the spec reads for that window.
- What the browser reports. Chromium reports no viewport origin. It does report the frame origin, the frame extent and the viewport extent.
manager.Window#toJSON publishes the same quantities as outerRect and innerRect.
The Fix
The change is test-only, in test/playwright/e2e/dashboard/DemoBVesselConversionNL.spec.mjs:
- Open the vessel through
nativeWindows.acquire(vesselSourceId, …), as a gesture does.
- Compare like with like. The frame's origin and extent go against
outerRect, and the viewport's extent against innerRect. Once they agree, the row works in innerRect, the rect the conversion consumes.
Acceptance Criteria
Out of Scope
DemoBPerspectivesNL, which is a different red: the paced tour does not reach its cross-window step within 10 s.
- Product code and the matrix runner.
Related
#17844 · #19242 · #18383 · #18068 · #19101
Live latest-open sweep: latest 20 open at 2026-09-26T13:24:52Z; no equivalent.
A2A sweep: latest 30, all read states; no claim on this row.
MC sweep: "Demo B vessel conversion row … popup never opens at line 170, headed-only witness, window geometry parity 67 px title bar", 10 results. The only prior reading is #19242's headed-only classification, which this ticket refutes. No decision on either contract.
Own-assignment sweep: 10 open. #17844 lists this row as unowned.
Origin Session ID: 81d1894c-d8fd-4192-8350-42e32eb0101e
Retrieval Hint: "DemoBVesselConversionNL openTearOutVessel topologyIdentity acquire innerRect frame origin title bar"
Context
DemoBVesselConversionNLis one of #17844's unowned census reds: nopopupevent in 30 s at line 170. #19242 re-aimed the row today and recorded it as a headed-only witness whose tear-out popup never opens headless. Measured at9a45c43ad8, the row fails the same way headed and headless, so the environment is not the cause.The Problem
The spec has two stale contracts. The second is hidden behind the first.
DemoBWorkspace#openTearOutVesseldirectly. Since #18383 (3a0773c9a5, 09-06), that effect returnsnullunless it receives thetopologyIdentitythatNativeLifecycle#acquiremints (examples/dashboard/crossWindow/DemoBWorkspace.mjs:3955).browserRectpairs the frame origin (screenX/Y) with the viewport extent. Since #18068 (09-02),manager.Window#calculateGeometrypublishesinnerRectas the viewport's screen rect (src/manager/Window.mjs:84). The difference between the two is the title bar.The Architectural Reality
openVesselisnativeWindows.acquire(vesselSourceId, request)(DemoBWorkspace.mjs:645,:694). It reserves the slot and passes the identity into the effect (src/manager/transaction/NativeLifecycle.mjs:191).manager.Window'sinnerRectfor the vessel (DemoBWorkspace#resolveVesselConversionSourceRect,:3874). Before the park, the row asserts thatvesselConversionSourceRectequals the rect the spec reads for that window.manager.Window#toJSONpublishes the same quantities asouterRectandinnerRect.The Fix
The change is test-only, in
test/playwright/e2e/dashboard/DemoBVesselConversionNL.spec.mjs:nativeWindows.acquire(vesselSourceId, …), as a gesture does.outerRect, and the viewport's extent againstinnerRect. Once they agree, the row works ininnerRect, the rect the conversion consumes.Acceptance Criteria
playwright.config.e2e.mjswithNEO_AGENTOS_RUNTIME_ROOTset. On dev it fails at line 170.commitEligible: truedecisions (the first one converting), zero flips, and a re-show on claim loss.Out of Scope
DemoBPerspectivesNL, which is a different red: the paced tour does not reach its cross-window step within 10 s.Related
#17844 · #19242 · #18383 · #18068 · #19101
Live latest-open sweep: latest 20 open at 2026-09-26T13:24:52Z; no equivalent. A2A sweep: latest 30, all read states; no claim on this row. MC sweep: "Demo B vessel conversion row … popup never opens at line 170, headed-only witness, window geometry parity 67 px title bar", 10 results. The only prior reading is #19242's headed-only classification, which this ticket refutes. No decision on either contract. Own-assignment sweep: 10 open. #17844 lists this row as unowned.
Origin Session ID: 81d1894c-d8fd-4192-8350-42e32eb0101e Retrieval Hint: "DemoBVesselConversionNL openTearOutVessel topologyIdentity acquire innerRect frame origin title bar"