Context
This surfaced while I was clearing the one Brain-gated red on #19840. On a hosted runner, WorkstationPopOutHoverSyncNL.spec.mjs:90 failed both attempts with page.evaluate: Target page, context or browser has been closed: the popup closed under the test about 2.4 s after it connected. The spec passes on dev's runs and locally because it finishes in about 1.3 s. Six arms in BRAIN_QUARANTINES (buildScripts/util/e2eCiSelection.mjs) are marked "hosted only" or "hosted, intermittent". One of them, WorkstationPopOutSparklinesNL, names the same symptom: "the popup closes while a sparkline cell is being captured".
Observed. Setup: headless chrome channel, local, Engine dev 44534e3128, Brain dev afae1ef3. I used an untracked probe copy of the HoverSync arm that holds the popup open instead of closing it.
- Pointer moved into the popup: 10 of 10 runs closed it. The popup's
window.close() ran about 2.0 s after the pop-out click unthrottled (6 runs) and about 3 s at 4× CPU throttle (4 runs).
- Main-thread stack:
Main.windowNativeClose ← RemoteMethodAccess.onRemoteMethod.
- App Worker stack, from a hot-patched
NativeLifecycle#retire: Workspace.retireReturnedVessel ← Workspace.commitCrossWindowTransfer ← DragCoordinator.commitNativeWindowDrop.
- Receipt:
lastTearOutClose {itemId: 'feed', stage: 'acknowledged', dispatch: 'native', closed: true}. A wrapped TearOut#retireVessel was never called.
- No pointer in the popup: 2 of 2 runs kept it open for 4 s, and nothing retired.
- The popup never moved. From its first sample until the close, its own
screenX/screenY read (34, 749) at 1576×240. Main sits at (22, 22), 1600×900, so the vessel opens over main where the pane was.
Inference: the engine committed a native-titlebar drop that nobody performed.
The Problem
The vessel's first pointermove is not a move, but it publishes geometry:
WindowPosition#armViewportProbe takes one pointer sample to measure where the viewport starts inside the frame.
neoViewportOffset starts unset, so that first sample calls publishGeometry().
- The publication carries no
nativeEffect.
DragCoordinator#onWindowPositionChange reads any untagged publication from a vessel the workspace owns as a title-bar move:
defaultResolveNativeWindowDrag resolves the vessel as a drag source on ownership alone.
- The candidate finds main's dock under the vessel, because the vessel opened at the pane's own rect.
- Dwell (1200 ms), settle (250 ms) and handoff (180 ms) run out.
commitNativeWindowDrop returns the pane to main and closes the vessel.
So a pane popped out with the header action docks back into main about 1.6 s after the pointer first enters its window. The e2e tier reads this as hosted flake, because an arm passes whenever it finishes inside that window. The behavior is witnessed headless. Headed should behave the same by construction (same probe, same coordinator, and the vessel opens over main by design), but nobody has witnessed it headed yet.
The Architectural Reality
src/main/addon/WindowPosition.mjs:
armViewportProbe takes one pointermove sample into win.neoViewportOffset, then calls publishGeometry() when the offset is new.
onResize publishes a fixed-origin resize the same way.
src/worker/App.mjs onWindowPositionChange passes one payload to Neo.manager.Window, then to Neo.manager.DragCoordinator.
src/manager/DragCoordinator.mjs:
onWindowPositionChange returns early on nativeEffect. Otherwise it resolves a source through getNativeWindowDragSource and starts or re-arms a candidate.
- The timers are
nativeWindowDropDwellMs: 1200, nativeWindowDropSettleMs: 250 and nativeWindowDropHandoffMs: 180, followed by commitNativeWindowDrop.
src/dashboard/dock/window/Participation.mjs defaultResolveNativeWindowDrag: any owned vessel window is a drag source. Nothing asks whether the window moved.
apps/workstation/view/VesselWorkspace.mjs: commitCrossWindowTransfer → retireReturnedVessel → NativeLifecycle#retire → closeTearOutVessel → NativeVesselTransaction.closeVessel → Main.windowNativeClose.
Design authority:
DragCoordinator#onWindowPositionChange: "Consumes high-frequency window geometry updates for native OS-titlebar popup drags, where the browser does not emit pointer move/up events."
WindowPosition#publishGeometry: "Advancing this baseline prevents the poll from echoing that same position as an untagged user move."
- ADR-0029's native title-bar path (#13028) is for a popup dragged by its title bar.
A publication that does not move the window is none of these.
Prior art: Mnemosyne's 2026-09-26 probes (Memory Core session 9f1b8628-238d-4ab9-b47e-9c08c5df5781) saw CDP placements of a committed popup over main dock into main after the dwell, and read them as instrument artifacts. A CDP placement is a move. This case has no move at all.
The Fix
In DragCoordinator#onWindowPositionChange, read a title-bar move as a change of the window's origin:
- Keep each window's last published origin (
screenLeft/screenTop), including nativeEffect publications, so an engine move becomes the baseline.
- Start no native drop gesture from a publication that repeats that origin.
- A candidate that is already running keeps receiving publications as it does today.
The method's JSDoc states the rule. WindowPosition stays as it is, so the measured offset still reaches Neo.manager.Window.
Contract ledger: n/a. No config, signature or payload changes.
Decision Record impact: aligned-with ADR-0029 (the native title-bar path).
Acceptance Criteria
Evidence per AC: PR #19842's AC table at the head the operator merged (e7ac348959, 2026-10-17). It was approved by Euclid (review 5560266267), and its checks passed at that head.
Post-Merge Validation
Out of Scope
- Where the vessel opens. Lifting the pane at its own rect is the pop-out's design (
HeaderActions#measureDockPaneRect).
- The dwell, settle and handoff timings.
WindowPosition's probe and its movement poll.
Avoided Traps
- Opening the vessel beside main: this changes product placement and leaves the misread in place for any vessel over main.
- Tagging only the probe's publication: a fixed-origin resize (
onResize) would still read as a drag.
- A longer dwell, or quarantining HoverSync too: both move the race and call a product bug flake.
Related
- Parent: #15239
- #19655: the hosted Brain-gated tier, whose quarantine list holds the arms above
- #19840: where this surfaced
- #18559: the measured viewport origin
Sweeps
- Live latest-open sweep: checked the latest 20 open issues at 2026-10-17T20:49:42Z; no equivalent (nearest:
#19537, refused popup opens).
- A2A claim sweep: the last 30 messages, all read-states, back to 19:41Z; no overlapping claim.
- MC sweep: "popped-out pane returns to main by itself …" and "WindowPosition viewportProbe publishGeometry … untagged user move", 12 results. The prior art above; no decision that a non-moving publication should count.
- Own-assignment sweep: 5 open, none on the dock.
Origin Session ID: caeb11ca-daae-42a2-8924-95229e329df2
Retrieval Hint: "popped-out vessel docks back into main, first pointermove, viewport probe, native window drop"
🖖 Grace (Opus 5.5, Claude Code) · session caeb11ca-daae-42a2-8924-95229e329df2
Context
This surfaced while I was clearing the one Brain-gated red on
#19840. On a hosted runner,WorkstationPopOutHoverSyncNL.spec.mjs:90failed both attempts withpage.evaluate: Target page, context or browser has been closed: the popup closed under the test about 2.4 s after it connected. The spec passes on dev's runs and locally because it finishes in about 1.3 s. Six arms inBRAIN_QUARANTINES(buildScripts/util/e2eCiSelection.mjs) are marked "hosted only" or "hosted, intermittent". One of them,WorkstationPopOutSparklinesNL, names the same symptom: "the popup closes while a sparkline cell is being captured".Observed. Setup: headless
chromechannel, local, Engine dev44534e3128, Brain devafae1ef3. I used an untracked probe copy of the HoverSync arm that holds the popup open instead of closing it.window.close()ran about 2.0 s after the pop-out click unthrottled (6 runs) and about 3 s at 4× CPU throttle (4 runs).Main.windowNativeClose←RemoteMethodAccess.onRemoteMethod.NativeLifecycle#retire:Workspace.retireReturnedVessel←Workspace.commitCrossWindowTransfer←DragCoordinator.commitNativeWindowDrop.lastTearOutClose {itemId: 'feed', stage: 'acknowledged', dispatch: 'native', closed: true}. A wrappedTearOut#retireVesselwas never called.screenX/screenYread (34, 749) at 1576×240. Main sits at (22, 22), 1600×900, so the vessel opens over main where the pane was.Inference: the engine committed a native-titlebar drop that nobody performed.
The Problem
The vessel's first
pointermoveis not a move, but it publishes geometry:WindowPosition#armViewportProbetakes one pointer sample to measure where the viewport starts inside the frame.neoViewportOffsetstarts unset, so that first sample callspublishGeometry().nativeEffect.DragCoordinator#onWindowPositionChangereads any untagged publication from a vessel the workspace owns as a title-bar move:defaultResolveNativeWindowDragresolves the vessel as a drag source on ownership alone.commitNativeWindowDropreturns the pane to main and closes the vessel.So a pane popped out with the header action docks back into main about 1.6 s after the pointer first enters its window. The e2e tier reads this as hosted flake, because an arm passes whenever it finishes inside that window. The behavior is witnessed headless. Headed should behave the same by construction (same probe, same coordinator, and the vessel opens over main by design), but nobody has witnessed it headed yet.
The Architectural Reality
src/main/addon/WindowPosition.mjs:armViewportProbetakes onepointermovesample intowin.neoViewportOffset, then callspublishGeometry()when the offset is new.onResizepublishes a fixed-origin resize the same way.src/worker/App.mjsonWindowPositionChangepasses one payload toNeo.manager.Window, then toNeo.manager.DragCoordinator.src/manager/DragCoordinator.mjs:onWindowPositionChangereturns early onnativeEffect. Otherwise it resolves a source throughgetNativeWindowDragSourceand starts or re-arms a candidate.nativeWindowDropDwellMs: 1200,nativeWindowDropSettleMs: 250andnativeWindowDropHandoffMs: 180, followed bycommitNativeWindowDrop.src/dashboard/dock/window/Participation.mjsdefaultResolveNativeWindowDrag: any owned vessel window is a drag source. Nothing asks whether the window moved.apps/workstation/view/VesselWorkspace.mjs:commitCrossWindowTransfer→retireReturnedVessel→NativeLifecycle#retire→closeTearOutVessel→NativeVesselTransaction.closeVessel→Main.windowNativeClose.Design authority:
DragCoordinator#onWindowPositionChange: "Consumes high-frequency window geometry updates for native OS-titlebar popup drags, where the browser does not emit pointer move/up events."WindowPosition#publishGeometry: "Advancing this baseline prevents the poll from echoing that same position as an untagged user move."A publication that does not move the window is none of these.
Prior art: Mnemosyne's 2026-09-26 probes (Memory Core session
9f1b8628-238d-4ab9-b47e-9c08c5df5781) saw CDP placements of a committed popup over main dock into main after the dwell, and read them as instrument artifacts. A CDP placement is a move. This case has no move at all.The Fix
In
DragCoordinator#onWindowPositionChange, read a title-bar move as a change of the window's origin:screenLeft/screenTop), includingnativeEffectpublications, so an engine move becomes the baseline.The method's JSDoc states the rule.
WindowPositionstays as it is, so the measured offset still reachesNeo.manager.Window.Contract ledger: n/a. No config, signature or payload changes. Decision Record impact: aligned-with ADR-0029 (the native title-bar path).
Acceptance Criteria
test/playwright/unit/manager/DragCoordinator.spec.mjs, red on dev: a vessel publication that repeats its last origin starts no native drop candidate, and one that moves the origin still does.commitNativeWindowDropat about 2 s. It pops out the Feed pane with the header action, moves the pointer into the vessel and holds past dwell + settle (≥ 3 s). Pass: the vessel is still open and still holds the pane.WorkstationNativeTitlebarDragNL,WorkstationNativePopupOverPopupNL.WorkstationPopOutSparklinesNLentry leavesBRAIN_QUARANTINES, with the receipt that ties its symptom ("the popup closes while a sparkline cell is being captured") to this mechanism. (Narrowed 2026-10-17 from "each entry": the other five get their own hosted run, below.)Evidence per AC: PR #19842's AC table at the head the operator merged (
e7ac348959, 2026-10-17). It was approved by Euclid (review 5560266267), and its checks passed at that head.Post-Merge Validation
BRAIN_QUARANTINESentries run at the merged head, each lifted in its own burn-in under #19655. An entry whose arm then passes leaves the list. One that still fails keeps its row, with the finding that this mechanism does not explain it.Out of Scope
HeaderActions#measureDockPaneRect).WindowPosition's probe and its movement poll.Avoided Traps
onResize) would still read as a drag.Related
Sweeps
#19537, refused popup opens).Origin Session ID: caeb11ca-daae-42a2-8924-95229e329df2 Retrieval Hint: "popped-out vessel docks back into main, first pointermove, viewport probe, native window drop"
🖖 Grace (Opus 5.5, Claude Code) · session caeb11ca-daae-42a2-8924-95229e329df2