Context
Live operator QA on 2026-07-29 falsified the visual-completion claim made by PR #16096, which resolved #16090. During the real human gesture—drag one Workstation popup over another—the screen continues to show two fully opaque native popup windows. No target-local proxy is visible and the popup below exposes no usable drop-zone language.
PR #16096 proved a narrower mechanism: its scripted Scene 3 path found one target-window DragProxyContainer and read opacity: 0.7 from that element. That is not proof that the ordinary human gesture reaches the conversion, that the source popup yields early enough, or that the target zones are simultaneously legible. A single computed-style read at a contrived geometry cannot close this successor.
The geometry and lifecycle premises are not new: #15395 specified the dual-window conversion law and was resolved by PR #15567; #15396 specified park-don't-close and was resolved by PR #15573. The current observation is therefore a post-merge regression/integration failure. Both predecessors remain closed.
The Problem
The intended popup-over-popup grammar is not perceivable in the live product. Progressive partial overlap does not visibly transition from the native source popup to an in-app proxy. The user instead sees two real opaque windows, and the upper window obscures the target's drop zones.
A transition that occurs only at or near 100% overlap would still be the wrong interaction: by then the source has hidden the target and its choices. The conversion must become visible early, while enough target content remains visible to understand and select a drop outcome.
The trigger cannot use one window's extent or creation-time geometry. Source and target popups can have different live sizes and can be resized mid-session. #15395 established the reachable metric:
rx = overlapWidth / min(sourceWidth, targetWidth)
ry = overlapHeight / min(sourceHeight, targetHeight)
The composed score must use live rectangles, a calibrated convert-in/convert-out hysteresis pair, and pointer intent inside the target's dock-accepting region. Full overlay is neither necessary nor acceptable as the only positive point.
The current observation does not establish the exact failing owner. Candidate boundaries include the already-landed conversion sensor's production feed, claim/admission, native source parking, target-local proxy materialization, or stale/equal-size assumptions in the composed geometry path. The first deliverable is a human-path failing witness that distinguishes them.
The Architectural Reality
Current source contains the pieces, but their existence does not prove the live composition:
- #15395 / PR #15567 owns the dual-window conversion geometry contract: live rects, smaller-extent per-axis normalization, hysteresis, and pointer gating.
- #15396 / PR #15573 owns the in-gesture source-vessel lifecycle: park, re-show, and exact-source recovery.
apps/workstation/view/Workspace.mjs#resolveProxyConfig adds workstation-vessel-dragproxy only after a target-local proxy has been admitted.
resources/scss/src/apps/workstation/Viewport.scss assigns that proxy opacity: .7; this rule cannot affect either native popup and is irrelevant when no proxy materializes.
src/dashboard/DockVesselEmbodiment.mjs#createDockVesselProxyEmbodiment() owns target-local proxy stage/move/restore/promote lifecycle.
Workspace#parkTearOutVessel() owns the native focus → park → refocus effect and fails closed when its route or geometry contract rejects the transition.
Neo.manager.DragCoordinator selects and feeds the target; its native-titlebar and active pointer-drag paths are distinct.
- PR
#16096 exercised a scripted Scene 3 boundary and inspected the target DOM. It did not retain a progressive, actual-pointer visual sequence proving that the live user path transitions before target occlusion.
The repair belongs at the earliest failing owner above. Do not paper over a missing conversion with native window alpha or a second drag coordinator.
The Fix
- Add a headed macOS Chromium regression that uses the real dock-tab pointer gesture and real popup windows; it must not call a conversion helper directly.
- Retain a visual/semantic sequence across approach, pointer-gated target entry, partial overlap, proxy motion, and commit or convert-out. Record both live native rectangles,
rx, ry, composed score, hysteresis state, selected target/claim, park admission, proxy census, preview/indicator state, and exact window identities at the same frames.
- Exercise at least small-over-large, large-over-small, near-equal, and post-resize asymmetric popup pairs. Each must reach conversion while the target remains readable.
- Repair the failing composition owner—sensor feed, admission, park, target proxy, or geometry use—so the source popup yields and exactly one target-local proxy moves with the pointer above still-visible drop indicators.
- Preserve cancel/convert-out, exact source-window restoration, commit-before-close, same-instance/store continuity, and stale-generation/disconnect cleanup.
Contract Ledger
| Target surface |
Source of authority |
Required behavior |
Failure fallback |
Evidence |
| Dual-window conversion sensor |
#15395 / PR #15567 |
Use both live source and target rects; normalize each overlap axis by the smaller corresponding extent; apply calibrated in/out hysteresis |
Invalid geometry or no pointer intent remains non-converting |
Same-frame rects, rx, ry, composed score, pointer gate, transition |
| Human popup-over-popup gesture |
Real pointer stream + live native windows |
Target entry visibly transitions the dragged vessel to one target-local proxy during partial overlap |
Keep the exact source popup recoverable; never commit an unshown target |
Actual-pointer headed sequence on current dev red, fixed head green |
| Native source vessel |
#15396 / PR #15573 + Workspace#parkTearOutVessel() |
Yields behind the target only after the local proxy path is ready |
Refuse conversion and preserve/restore the same popup |
Identity, rect, park result, and visibility/z-order receipt |
| Target-local embodiment |
createDockVesselProxyEmbodiment() |
One moving proxy carries the live pane |
Zero proxy means the visual claim fails closed |
Proxy identity/window/parent/rect plus retained frames |
| Drop target language |
Existing DockDropIndicators + preview owner |
Indicators and preview remain legible concurrently with the proxy |
No visually hidden commit target |
DOM state plus same-frame visual proof |
Acceptance Criteria
Out of Scope
Overflow-menu skin · ordinary tab-header drag-proxy skin · drop-indicator thickness symmetry · same-gesture re-entry freeze after initial tear-out · dragging an already-dropped native popup over the main app · popup first-paint/white-canvas defects · video production.
Avoided Traps
- Do not reopen #15395, #15396, or #16090; this is their post-merge regression/integration successor.
- Do not replace the two-live-rectangle metric with one-window, stale, or equal-size geometry.
- Do not infer usability from
opacity: .7 on an element the human path may never create.
- Do not accept a full-overlay-only transition; it defeats the target-choice affordance.
- Do not replace the in-app baseline with unsupported native popup alpha.
- Do not use film/tour executors as the only evidence for an ordinary human interaction.
Decision Record impact
depends-on ADR 0029 §§2.3 and 2.8.2–2.8.3; no amendment expected. If the failing witness reveals that the recorded ownership state cannot express progressive target entry, stop and revalidate the ADR premise before implementation.
Related
Post-merge successor to #15395 (PR #15567), #15396 (PR #15573), and #16090 (PR #16096) · parent #15239 · QT-parity epic #13158.
Freshness evidence: Memory Core recovered the original dual-size operator exploration and exact geometry contract; live GitHub confirmed #15395 and #15396 are completed predecessors, closed by PRs #15567 and #15573. Knowledge Base semantic sweep, live current-source/PR inspection, latest 20 open GitHub issues, exact-title/scope search, and latest 30 all-state A2A messages were also checked on 2026-07-29; no equivalent open successor or competing claim was found.
Origin Session ID: abce4d75-7dcb-4145-8afc-b0ff2cdc51e6
Retrieval Hint: dual-window conversion geometry popup proxy min-axis hysteresis human path two opaque popups PR 16096
Context
Live operator QA on 2026-07-29 falsified the visual-completion claim made by PR #16096, which resolved #16090. During the real human gesture—drag one Workstation popup over another—the screen continues to show two fully opaque native popup windows. No target-local proxy is visible and the popup below exposes no usable drop-zone language.
PR
#16096proved a narrower mechanism: its scripted Scene 3 path found one target-windowDragProxyContainerand readopacity: 0.7from that element. That is not proof that the ordinary human gesture reaches the conversion, that the source popup yields early enough, or that the target zones are simultaneously legible. A single computed-style read at a contrived geometry cannot close this successor.The geometry and lifecycle premises are not new: #15395 specified the dual-window conversion law and was resolved by PR #15567; #15396 specified park-don't-close and was resolved by PR #15573. The current observation is therefore a post-merge regression/integration failure. Both predecessors remain closed.
The Problem
The intended popup-over-popup grammar is not perceivable in the live product. Progressive partial overlap does not visibly transition from the native source popup to an in-app proxy. The user instead sees two real opaque windows, and the upper window obscures the target's drop zones.
A transition that occurs only at or near 100% overlap would still be the wrong interaction: by then the source has hidden the target and its choices. The conversion must become visible early, while enough target content remains visible to understand and select a drop outcome.
The trigger cannot use one window's extent or creation-time geometry. Source and target popups can have different live sizes and can be resized mid-session. #15395 established the reachable metric:
rx = overlapWidth / min(sourceWidth, targetWidth)ry = overlapHeight / min(sourceHeight, targetHeight)The composed score must use live rectangles, a calibrated convert-in/convert-out hysteresis pair, and pointer intent inside the target's dock-accepting region. Full overlay is neither necessary nor acceptable as the only positive point.
The current observation does not establish the exact failing owner. Candidate boundaries include the already-landed conversion sensor's production feed, claim/admission, native source parking, target-local proxy materialization, or stale/equal-size assumptions in the composed geometry path. The first deliverable is a human-path failing witness that distinguishes them.
The Architectural Reality
Current source contains the pieces, but their existence does not prove the live composition:
apps/workstation/view/Workspace.mjs#resolveProxyConfigaddsworkstation-vessel-dragproxyonly after a target-local proxy has been admitted.resources/scss/src/apps/workstation/Viewport.scssassigns that proxyopacity: .7; this rule cannot affect either native popup and is irrelevant when no proxy materializes.src/dashboard/DockVesselEmbodiment.mjs#createDockVesselProxyEmbodiment()owns target-local proxy stage/move/restore/promote lifecycle.Workspace#parkTearOutVessel()owns the native focus → park → refocus effect and fails closed when its route or geometry contract rejects the transition.Neo.manager.DragCoordinatorselects and feeds the target; its native-titlebar and active pointer-drag paths are distinct.#16096exercised a scripted Scene 3 boundary and inspected the target DOM. It did not retain a progressive, actual-pointer visual sequence proving that the live user path transitions before target occlusion.The repair belongs at the earliest failing owner above. Do not paper over a missing conversion with native window alpha or a second drag coordinator.
The Fix
rx,ry, composed score, hysteresis state, selected target/claim, park admission, proxy census, preview/indicator state, and exact window identities at the same frames.Contract Ledger
rx,ry, composed score, pointer gate, transitiondevred, fixed head greenWorkspace#parkTearOutVessel()createDockVesselProxyEmbodiment()DockDropIndicators+ preview ownerAcceptance Criteria
devwith the reported two-native-popup/no-local-proxy state; no direct executor or conversion-helper call may stand in for the human gesture.opacityvalue, DOM census, semantic receipt, or single final screenshot alone is insufficient.Out of Scope
Overflow-menu skin · ordinary tab-header drag-proxy skin · drop-indicator thickness symmetry · same-gesture re-entry freeze after initial tear-out · dragging an already-dropped native popup over the main app · popup first-paint/white-canvas defects · video production.
Avoided Traps
opacity: .7on an element the human path may never create.Decision Record impact
depends-on ADR 0029 §§2.3 and 2.8.2–2.8.3; no amendment expected. If the failing witness reveals that the recorded ownership state cannot express progressive target entry, stop and revalidate the ADR premise before implementation.
Related
Post-merge successor to #15395 (PR #15567), #15396 (PR #15573), and #16090 (PR #16096) · parent #15239 · QT-parity epic #13158.
Freshness evidence: Memory Core recovered the original dual-size operator exploration and exact geometry contract; live GitHub confirmed #15395 and #15396 are completed predecessors, closed by PRs #15567 and #15573. Knowledge Base semantic sweep, live current-source/PR inspection, latest 20 open GitHub issues, exact-title/scope search, and latest 30 all-state A2A messages were also checked on 2026-07-29; no equivalent open successor or competing claim was found.
Origin Session ID:
abce4d75-7dcb-4145-8afc-b0ff2cdc51e6Retrieval Hint:
dual-window conversion geometry popup proxy min-axis hysteresis human path two opaque popups PR 16096