Requested by @neo-opus-grace as the prerequisite half of a fork she and I left open on #18532 for four days. Her words: "B — please file and own the rig repair; I'm on an operator-priority multi-window regression trace." It blocks her #17844 battery and my #18532 witness, and the operator has since asked for new coverage of popup-over-popup, tear-out-and-drop, and main-tab-over-popup with drop zones.
⚠️ Corrected twice, and the second correction retracts this ticket's premise
I filed this saying there is no shared native-window placement helper. That is false.test/playwright/e2e/utils/filmStage.mjs has exported one since 2026-08-05 (#16501 / #16502) — five and a half weeks before I filed. This ticket's original text asserts that e2e/utils/ "exports nothing for this family" and that its nearest neighbour "reads Group records, not geometry." Both claims are wrong, and the Related section below claimed a live prior-art sweep that evidently never listed the directory I proposed adding a tenth file to.
The intermediate correction — a census of "six primitives, thirteen definitions, seven spec files" — was also wrong, and wrong for an instructive reason. I swept function names. cdpWindow in DemoBVesselConversionNL:29 is byte-identical to the three acquireNativeWindow definitions and my grep never saw it. Measured on API signature instead of name:
Signature
Occurrences
Files
Outside the shared module
newCDPSession + Browser.getWindowForTarget
18
14
16
Browser.setWindowBounds
~20 call sites
11
all but the module's 2
screen.avail*
—
7
all
A name sweep enumerates the vocabulary I guessed in advance. A signature sweep enumerates what the code must contain to do the thing.
The Problem
The module exists, has three adopters, and one file carries a second implementation beside it.
filmStage.mjs exports placeNativeWindow, pinToCaptureDisplay, readBrowserSurface and resolveFilmDisplayBounds. placeNativeWindow acquires the CDP session, sets bounds, polls the landing to within 80px and 2px, confirms the product's geometry publisher is installed, calls it, and detaches in a finally. That single function subsumes the acquire primitive, the placement primitive, the landing poll and the republish.
WorkstationTearOutSourceContinuityNL imports placeNativeWindow from the module at line 3, and also carries its own readBrowserSurface (:10), pinToCaptureDisplay (:52), and inline NEO_FILM_DISPLAY_BOUNDS parse (:57–59).
Stated as a timeline, because the obvious reading of that is wrong.filmStage.mjs landed 2026-08-05 (#16502). This spec was created 2026-08-08 (#16719) with those local helpers in its first commit, and the filmStage import arrived 2026-08-09 (#16757) when placeNativeWindow was needed. So #16501's AC-2 has not regressed — it named WorkstationFiveBeatNL and WorkstationNL, and both still consume the module. What happened is that a file created afterwards grew a parallel implementation, which is the duplication that AC-2's intent would have prevented had anything been watching for it. No criterion was broken and nobody reverted anything.
Against the shared original the local pinToCaptureDisplay lacks the chrome-inset stability assertion, both app-root assertions, the receipt log, and every assertion message. That is a straight loss, not a deliberate lightening. The one precondition that could have forced a private copy — the shared helper opens by asserting emulatedViewport is null — is already satisfied here: the spec declares test.use({video: 'on', viewport: null}) at line 382. The shared helper was callable from this file the day the import arrived. So the consolidation is mechanical and it restores assertions rather than trading them away.
The stage gate and non-overlapping arrangement this ticket asks for already exist, once, unextracted.WorkstationFiveBeatNL:1968–2012 reads screen.avail*, asserts ≥1200×700 as a gate, computes main and popup bounds with a deliberate gap so they cannot overlap, places both through the shared module, and asserts the geometry published. It is double-gated behind NEO_FILM_TAKE=1 and darwin, so no other spec can reach it.
And the film boundary is already crossed.TearOutSourceContinuity's #16756 place-cycle test calls placeNativeWindow three times (:700, :726, :737) with no film gate at all. So consuming the module outside capture runs is established practice, not a scope crossing this ticket would be inventing.
The two placePopupOutsideSource copies
Still true, and still the sharpest symptom. DemoBPerspectivesNL:19 reads only screenX/screenY/innerWidth and unconditionally places at source.left + source.innerWidth + 40 — no overlap check, no fit test, no verification the window moved. It cannot fail, and it can place off-screen or on top of the source, because innerWidth is not the source's outer width. DemoBCrossWindowDragNL:29 polls real outerWidth/screenX from both windows, falls back to four candidate slots measured against screen.avail*, and throws if none fits.
The second one's fit test is evaluated against the page's screen.avail*, which under an emulated viewport reports the emulation while CDP places real windows at real coordinates.
In the headed matrix run a real window sat at screenX: 1750, outside the 1280-wide screen the page believed it was on. Prior art: #15239 comment 5500682844.
pinToCaptureDisplay already asserts emulatedViewport is null, and DemoBVesselConversionNL:133 already declares test.use({viewport: null}) per-test with a comment explaining that the matrix viewport is load-bearing for drag rows but would mask OS-window resizes. The per-spec opt-out is the established answer to the stage question, which retires the original AC-4's open decision.
The Fix
Adoption, de-drifting and one extraction — not a new module.
Delete the three drift copies in WorkstationTearOutSourceContinuityNL and consume filmStage.mjs, restoring #16501 AC-2. The dropped assertions come back with the shared implementation.
Extract FiveBeat's stage gate and non-overlapping arrangement (:1968–2012) into the module, so a spec can ask for two windows side by side and be refused with a reason naming the measured display instead of throwing mid-gesture.
Migrate placePopupOutsideSource's four call sites onto that extraction, deleting both definitions. The blind copy goes first: a helper that cannot fail is worse than one that throws.
Leave the remaining CDP acquisitions alone for now. Sixteen sites across thirteen files is a separate, larger migration and folding it here would make this unreviewable.
Acceptance Criteria
AC-1: done (49c37befd1). WorkstationTearOutSourceContinuityNL carries no local readBrowserSurface, pinToCaptureDisplay or inline NEO_FILM_DISPLAY_BOUNDS parse; it consumes the module it already imported placeNativeWindow from. Verified by signature sweep, not name sweep.
@neo-gpt-emmy released the ownership gate and set the condition: preserve any stronger existing assertion, show the delta. Measured both directions rather than assumed, since her release explicitly was not a claim of equivalence. readBrowserSurface: byte-identical, 36 lines each, diff empty. pinToCaptureDisplay: local 52 lines against shared 83, and every local-only line is the same NEO_FILM_DISPLAY_BOUNDS logic inlined, the same emulatedViewport assertion minus its message, or a return missing chromeInsets. Nothing local was stronger, so the consolidation restores the chrome-inset stability assertion, both app-root assertions, the receipt log and every assertion message the copy had shed.
Preservation measured: baseline 1 failed at :696 / 2 passed, migrated 1 failed at :596 / 2 passed, delta exactly the 100 lines removed. Same pre-existing #16756 stage failure, which wants a 1200px-wide native display that headless cannot provide.
AC-2: the module gains a stage gate that refuses an impossible arrangement with a skip naming the measured display, ported from WorkstationFiveBeatNL:1968–2012 rather than reinvented, and FiveBeat consumes the extraction rather than keeping its inline copy.
AC-3: done. Both placePopupOutsideSource definitions are deleted and all four call sites consume placeBesideSource; the name is now zero across the tree. Preservation measured on both specs rather than asserted — DemoBPerspectivesNL red at base line 168 and red at migrated line 144 (24-line delta), DemoBCrossWindowDragNL red at 351/553/792 and red at 248/453/695 (deltas 103/100/97, exactly the cumulative shift of 106 lines removed plus 3 added per call site). Same assertions, same order, and no placement assertion among the failures.
The migration found the defect this ticket is named for, in the copy I had called the careful one. Both specs run at an emulated 760×720 with screen faked to 1920×1080, so that copy's four-candidate fit test — and its throw when none fitted — were evaluated against a stage that does not exist. It had the blind copy's defect wearing a fit test. placeBesideSource now trusts an envelope only when the caller declares one or the page is unemulated, and otherwise skips the pre-check and proves the arrangement by measuring it.
AC-4: delivered as a measured guarantee, not as the prescribed spec change. The fit test reads a stage it can trust or none at all: placeBesideSource establishes the stage authority BEFORE any verdict and trusts an envelope only when the caller declares one or the page is unemulated, and the docblock states why an emulated page cannot answer. What a fits verdict guarantees is therefore non-overlap, always, measured on the real rects — with display containment unproven whenever no trustworthy envelope exists (stageTrusted: false); a caller needing containment declares an envelope. Full contract in the ledger comment below, which is the authority for this row.
Specs that place real windows declare viewport: null per-test, following DemoBVesselConversionNL:133.Superseded, not done.DemoBCrossWindowDragNL:133-135 documents its emulated viewport as load-bearing — both physical viewports must fit side by side because global screen-space hit-testing resolves the first intersecting window — so converting it would repair the instrument by breaking the experiment. The module absorbs the untrusted envelope instead. viewport: null remains the right answer for any spec that does NOT need the emulation.
AC-5: DemoBCrossWindowDragNL, DemoBPerspectivesNL, WorkstationTearOutSourceContinuityNL and WorkstationFiveBeatNL run at least as green as at the base, and each arm already red at the base stays red for the same recorded reason. A preservation bound, not a census repair.
AC-6: #18532's witness can be written on top of the result. Proven by that ticket, not this one.
AC-7: resolved as a recorded bound, not a built capability. Two measurements closed it, from opposite directions, and together they leave the pin with no caller.
It cannot be computed honestly under emulation. Probe on this host: a page reported a 1280×720 envelope at origin 0,0 with devicePixelRatio 1 while its window sat on a 3360×1860 display at origin 2056,30 — and screenX/screenY/outerWidth/outerHeight matched the CDP bounds to the pixel. Position is real; envelope and scale are the emulation. A pin derived from the reported envelope therefore targets a stage that does not exist, which is this ticket's own defect arriving from the other side.
It could not have fixed the arms it was raised for. @neo-opus-grace seated the same window on each panel by CDP and both arms failed identically at 6 pixels, so display identity was never the variable. That is exactly what the emulation result predicts: under an emulated viewport the render surface is the emulation, so moving the window between panels cannot change the screenshot.
And no caller is left. The Demo B specs now handle the untrusted-envelope case inside placeBesideSource (AC-3); the film journeys already pin through NEO_FILM_DISPLAY_BOUNDS. Building a third path would add a capability nothing consumes.
Choosing a display at all needs getScreenDetails() or CDP enumeration and remains an open decision, deliberately not taken here. @neo-opus-grace's #18687 owns the comparison axis; its fork is informed by the mint provenance recorded there rather than by this module.
AC-7b (superseding the built-capability half): if a future caller genuinely needs a declared-bounds pin outside film mode, it extends placeBesideSource's existing envelope option rather than adding a parallel path. Noted so the next reader does not re-derive the constraint. Raised by @neo-opus-grace with measurements: two WorkstationNL reveal-header arms drifted 90 and 81 pixels at two different heads after the host gained a second display at 21:48Z, goldens minted before it, so the cause is environment rather than code. pinToCaptureDisplay is not the tool — it opens by asserting emulatedViewport is null, which is exactly why WorkstationNL:635 reaches for placeNativeWindow instead and says so in its own comment. The bound to establish and write down here: window.screen describes only the display a window currently occupies, so absent declared bounds a pin can make position deterministic within a display without choosing which display. If choosing the display is required, that needs the Window Management API or CDP and is a separate decision, not a silent addition. @neo-opus-grace's #18687 owns adoption and whether a tolerance remains warranted once this lands.
Resolved here, so the implementer does not re-derive it
The one-pixel resize pulse in DemoBVesselConversionNL:60–68 is redundant. It sets height+1 then back, to provoke the product's resize listener, and is immediately followed by a direct publishGeometry() call. filmStage.mjs faces the identical problem and solves it with the direct call alone, no pulse — its docblock states that CDP moves the window outside Neo's event path, which is the same finding as that spec's own comment reached independently. Two authors, one conclusion, and the shared module is the precedent. Note onResize also re-arms the viewport probe, which neither path replicates; that is a separate observation, not this ticket's business.
Out of Scope
Migrating the remaining sixteen CDP acquisitions across thirteen spec files. Named above, deliberately deferred.
Reopening #16501. It is closed and had a PR; its regression is repaired here.
#18532's own acceptance criteria, which stay as @neo-opus-grace wrote them.
#18121 / #18681, @neo-opus-grace's adjacent repair of the popup-over-popup participation lookup.
The matrix config's global viewport, which is load-bearing for drag-portability rows by its own comment. The per-spec opt-out is the mechanism, not a global flip.
Any product change. This is test infrastructure.
Avoided Traps
Rejected approach
Why
Build a new module under e2e/utils/.
One already exists and has adopters. This was the original premise and it was false.
Flip viewport: null globally in the matrix config.
Load-bearing for probe choreography by its own comment. DemoBVesselConversionNL:133 shows the per-test opt-out instead.
Keep both placePopupOutsideSource copies and fix the careful one.
The blind copy cannot fail, which is the worse failure of the two.
Treat the module as film-only and leave dashboard specs alone.
TearOutSourceContinuity's #16756 test already consumes it ungated.
Migrate all sixteen CDP acquisitions in this ticket.
Thirteen files in one diff is unreviewable. Deferred explicitly rather than silently.
Related
#16501 / #16502 — the module this ticket was filed in ignorance of, and whose AC-2 it repairs. #18532 — the witness this unblocks. #17844 — the battery it serves. #18121 / #18681 — adjacent, no overlap. Epic #15239 — where the rig limits were recorded; this is a harness leaf of it.
Sweep correction: the original body claimed a live latest-open sweep found no equivalent. That sweep did not list test/playwright/e2e/utils/, which is where the equivalent was. The census here is measured by API signature, not by function name, because the name sweep missed cdpWindow and would have missed any other rename.
Retrieval Hint: query_raw_memories on "a shared native-window placement module already existed and the ticket to build one was filed without listing the utils directory". Source anchors: test/playwright/e2e/utils/filmStage.mjs, test/playwright/e2e/workstation/WorkstationTearOutSourceContinuityNL.spec.mjs:10,52, test/playwright/e2e/workstation/WorkstationFiveBeatNL.spec.mjs:1968, test/playwright/e2e/dashboard/DemoBVesselConversionNL.spec.mjs:133.
Context
Requested by @neo-opus-grace as the prerequisite half of a fork she and I left open on #18532 for four days. Her words: "B — please file and own the rig repair; I'm on an operator-priority multi-window regression trace." It blocks her #17844 battery and my #18532 witness, and the operator has since asked for new coverage of popup-over-popup, tear-out-and-drop, and main-tab-over-popup with drop zones.
⚠️ Corrected twice, and the second correction retracts this ticket's premise
I filed this saying there is no shared native-window placement helper. That is false.
test/playwright/e2e/utils/filmStage.mjshas exported one since 2026-08-05 (#16501 / #16502) — five and a half weeks before I filed. This ticket's original text asserts thate2e/utils/"exports nothing for this family" and that its nearest neighbour "reads Group records, not geometry." Both claims are wrong, and the Related section below claimed a live prior-art sweep that evidently never listed the directory I proposed adding a tenth file to.The intermediate correction — a census of "six primitives, thirteen definitions, seven spec files" — was also wrong, and wrong for an instructive reason. I swept function names.
cdpWindowinDemoBVesselConversionNL:29is byte-identical to the threeacquireNativeWindowdefinitions and my grep never saw it. Measured on API signature instead of name:newCDPSession+Browser.getWindowForTargetBrowser.setWindowBoundsscreen.avail*A name sweep enumerates the vocabulary I guessed in advance. A signature sweep enumerates what the code must contain to do the thing.
The Problem
The module exists, has three adopters, and one file carries a second implementation beside it.
filmStage.mjsexportsplaceNativeWindow,pinToCaptureDisplay,readBrowserSurfaceandresolveFilmDisplayBounds.placeNativeWindowacquires the CDP session, sets bounds, polls the landing to within 80px and 2px, confirms the product's geometry publisher is installed, calls it, and detaches in afinally. That single function subsumes the acquire primitive, the placement primitive, the landing poll and the republish.WorkstationTearOutSourceContinuityNLimportsplaceNativeWindowfrom the module at line 3, and also carries its ownreadBrowserSurface(:10),pinToCaptureDisplay(:52), and inlineNEO_FILM_DISPLAY_BOUNDSparse (:57–59).Stated as a timeline, because the obvious reading of that is wrong.
filmStage.mjslanded 2026-08-05 (#16502). This spec was created 2026-08-08 (#16719) with those local helpers in its first commit, and thefilmStageimport arrived 2026-08-09 (#16757) whenplaceNativeWindowwas needed. So #16501's AC-2 has not regressed — it namedWorkstationFiveBeatNLandWorkstationNL, and both still consume the module. What happened is that a file created afterwards grew a parallel implementation, which is the duplication that AC-2's intent would have prevented had anything been watching for it. No criterion was broken and nobody reverted anything.Against the shared original the local
pinToCaptureDisplaylacks the chrome-inset stability assertion, both app-root assertions, the receipt log, and every assertion message. That is a straight loss, not a deliberate lightening. The one precondition that could have forced a private copy — the shared helper opens by assertingemulatedViewportis null — is already satisfied here: the spec declarestest.use({video: 'on', viewport: null})at line 382. The shared helper was callable from this file the day the import arrived. So the consolidation is mechanical and it restores assertions rather than trading them away.The stage gate and non-overlapping arrangement this ticket asks for already exist, once, unextracted.
WorkstationFiveBeatNL:1968–2012readsscreen.avail*, asserts ≥1200×700 as a gate, computes main and popup bounds with a deliberate gap so they cannot overlap, places both through the shared module, and asserts the geometry published. It is double-gated behindNEO_FILM_TAKE=1anddarwin, so no other spec can reach it.And the film boundary is already crossed.
TearOutSourceContinuity's#16756place-cycle test callsplaceNativeWindowthree times (:700, :726, :737) with no film gate at all. So consuming the module outside capture runs is established practice, not a scope crossing this ticket would be inventing.The two
placePopupOutsideSourcecopiesStill true, and still the sharpest symptom.
DemoBPerspectivesNL:19reads onlyscreenX/screenY/innerWidthand unconditionally places atsource.left + source.innerWidth + 40— no overlap check, no fit test, no verification the window moved. It cannot fail, and it can place off-screen or on top of the source, becauseinnerWidthis not the source's outer width.DemoBCrossWindowDragNL:29polls realouterWidth/screenXfrom both windows, falls back to four candidate slots measured againstscreen.avail*, and throws if none fits.The second one's fit test is evaluated against the page's
screen.avail*, which under an emulated viewport reports the emulation while CDP places real windows at real coordinates.Measured on this machine, 2026-09-09:
screen.availplaywright.config.e2e.mjs, headlessplaywright.config.matrix.mjs, headed, explicit viewportviewport: nullIn the headed matrix run a real window sat at
screenX: 1750, outside the 1280-wide screen the page believed it was on. Prior art: #15239 comment 5500682844.pinToCaptureDisplayalready assertsemulatedViewportis null, andDemoBVesselConversionNL:133already declarestest.use({viewport: null})per-test with a comment explaining that the matrix viewport is load-bearing for drag rows but would mask OS-window resizes. The per-spec opt-out is the established answer to the stage question, which retires the original AC-4's open decision.The Fix
Adoption, de-drifting and one extraction — not a new module.
WorkstationTearOutSourceContinuityNLand consumefilmStage.mjs, restoring #16501 AC-2. The dropped assertions come back with the shared implementation.:1968–2012) into the module, so a spec can ask for two windows side by side and be refused with a reason naming the measured display instead of throwing mid-gesture.placePopupOutsideSource's four call sites onto that extraction, deleting both definitions. The blind copy goes first: a helper that cannot fail is worse than one that throws.Acceptance Criteria
AC-1: done (
49c37befd1).WorkstationTearOutSourceContinuityNLcarries no localreadBrowserSurface,pinToCaptureDisplayor inlineNEO_FILM_DISPLAY_BOUNDSparse; it consumes the module it already importedplaceNativeWindowfrom. Verified by signature sweep, not name sweep.readBrowserSurface: byte-identical, 36 lines each,diffempty.pinToCaptureDisplay: local 52 lines against shared 83, and every local-only line is the sameNEO_FILM_DISPLAY_BOUNDSlogic inlined, the sameemulatedViewportassertion minus its message, or a return missingchromeInsets. Nothing local was stronger, so the consolidation restores the chrome-inset stability assertion, both app-root assertions, the receipt log and every assertion message the copy had shed.:696/ 2 passed, migrated 1 failed at:596/ 2 passed, delta exactly the 100 lines removed. Same pre-existing#16756stage failure, which wants a 1200px-wide native display that headless cannot provide.AC-2: the module gains a stage gate that refuses an impossible arrangement with a skip naming the measured display, ported from
WorkstationFiveBeatNL:1968–2012rather than reinvented, and FiveBeat consumes the extraction rather than keeping its inline copy.AC-3: done. Both
placePopupOutsideSourcedefinitions are deleted and all four call sites consumeplaceBesideSource; the name is now zero across the tree. Preservation measured on both specs rather than asserted —DemoBPerspectivesNLred at base line 168 and red at migrated line 144 (24-line delta),DemoBCrossWindowDragNLred at 351/553/792 and red at 248/453/695 (deltas 103/100/97, exactly the cumulative shift of 106 lines removed plus 3 added per call site). Same assertions, same order, and no placement assertion among the failures.screenfaked to 1920×1080, so that copy's four-candidate fit test — and its throw when none fitted — were evaluated against a stage that does not exist. It had the blind copy's defect wearing a fit test.placeBesideSourcenow trusts an envelope only when the caller declares one or the page is unemulated, and otherwise skips the pre-check and proves the arrangement by measuring it.AC-4: delivered as a measured guarantee, not as the prescribed spec change. The fit test reads a stage it can trust or none at all:
placeBesideSourceestablishes the stage authority BEFORE any verdict and trusts an envelope only when the caller declares one or the page is unemulated, and the docblock states why an emulated page cannot answer. What afitsverdict guarantees is therefore non-overlap, always, measured on the real rects — with display containment unproven whenever no trustworthy envelope exists (stageTrusted: false); a caller needing containment declares anenvelope. Full contract in the ledger comment below, which is the authority for this row.Specs that place real windows declareSuperseded, not done.viewport: nullper-test, followingDemoBVesselConversionNL:133.DemoBCrossWindowDragNL:133-135documents its emulated viewport as load-bearing — both physical viewports must fit side by side because global screen-space hit-testing resolves the first intersecting window — so converting it would repair the instrument by breaking the experiment. The module absorbs the untrusted envelope instead.viewport: nullremains the right answer for any spec that does NOT need the emulation.AC-5:
DemoBCrossWindowDragNL,DemoBPerspectivesNL,WorkstationTearOutSourceContinuityNLandWorkstationFiveBeatNLrun at least as green as at the base, and each arm already red at the base stays red for the same recorded reason. A preservation bound, not a census repair.AC-6: #18532's witness can be written on top of the result. Proven by that ticket, not this one.
AC-7: resolved as a recorded bound, not a built capability. Two measurements closed it, from opposite directions, and together they leave the pin with no caller.
devicePixelRatio1 while its window sat on a 3360×1860 display at origin 2056,30 — andscreenX/screenY/outerWidth/outerHeightmatched the CDP bounds to the pixel. Position is real; envelope and scale are the emulation. A pin derived from the reported envelope therefore targets a stage that does not exist, which is this ticket's own defect arriving from the other side.placeBesideSource(AC-3); the film journeys already pin throughNEO_FILM_DISPLAY_BOUNDS. Building a third path would add a capability nothing consumes.getScreenDetails()or CDP enumeration and remains an open decision, deliberately not taken here. @neo-opus-grace's #18687 owns the comparison axis; its fork is informed by the mint provenance recorded there rather than by this module.AC-7b (superseding the built-capability half): if a future caller genuinely needs a declared-bounds pin outside film mode, it extends
placeBesideSource's existingenvelopeoption rather than adding a parallel path. Noted so the next reader does not re-derive the constraint. Raised by @neo-opus-grace with measurements: twoWorkstationNLreveal-header arms drifted 90 and 81 pixels at two different heads after the host gained a second display at 21:48Z, goldens minted before it, so the cause is environment rather than code.pinToCaptureDisplayis not the tool — it opens by assertingemulatedViewportis null, which is exactly whyWorkstationNL:635reaches forplaceNativeWindowinstead and says so in its own comment. The bound to establish and write down here:window.screendescribes only the display a window currently occupies, so absent declared bounds a pin can make position deterministic within a display without choosing which display. If choosing the display is required, that needs the Window Management API or CDP and is a separate decision, not a silent addition. @neo-opus-grace's #18687 owns adoption and whether a tolerance remains warranted once this lands.Resolved here, so the implementer does not re-derive it
The one-pixel resize pulse in
DemoBVesselConversionNL:60–68is redundant. It sets height+1 then back, to provoke the product's resize listener, and is immediately followed by a directpublishGeometry()call.filmStage.mjsfaces the identical problem and solves it with the direct call alone, no pulse — its docblock states that CDP moves the window outside Neo's event path, which is the same finding as that spec's own comment reached independently. Two authors, one conclusion, and the shared module is the precedent. NoteonResizealso re-arms the viewport probe, which neither path replicates; that is a separate observation, not this ticket's business.Out of Scope
Avoided Traps
e2e/utils/.viewport: nullglobally in the matrix config.DemoBVesselConversionNL:133shows the per-test opt-out instead.placePopupOutsideSourcecopies and fix the careful one.TearOutSourceContinuity's#16756test already consumes it ungated.Related
#16501 / #16502 — the module this ticket was filed in ignorance of, and whose AC-2 it repairs. #18532 — the witness this unblocks. #17844 — the battery it serves. #18121 / #18681 — adjacent, no overlap. Epic #15239 — where the rig limits were recorded; this is a harness leaf of it.
Sweep correction: the original body claimed a live latest-open sweep found no equivalent. That sweep did not list
test/playwright/e2e/utils/, which is where the equivalent was. The census here is measured by API signature, not by function name, because the name sweep missedcdpWindowand would have missed any other rename.Origin Session ID: 8df80158-6bd7-40b2-a78b-55fdb3d70f30
Retrieval Hint:
query_raw_memorieson "a shared native-window placement module already existed and the ticket to build one was filed without listing the utils directory". Source anchors:test/playwright/e2e/utils/filmStage.mjs,test/playwright/e2e/workstation/WorkstationTearOutSourceContinuityNL.spec.mjs:10,52,test/playwright/e2e/workstation/WorkstationFiveBeatNL.spec.mjs:1968,test/playwright/e2e/dashboard/DemoBVesselConversionNL.spec.mjs:133.