Sub of #16498. After a native titlebar return, an invisible empty proxy is left in main's DOM and in the embodiment's state. What the user sees works. This was the last red between WorkstationFiveBeatNL scene 2 and #16498's human-QA arm.
Context
Scene 2 under the on-contract corner aim (#19776), 2026-10-15. The return commits exactly as the retained preview predicts (:2412). Then :2456, "native terminal cleanup must leave no preview or proxy residue", read {preview: false, proxy: true} for its full 5 s poll. The leftover is DIV.neo-dock-dragproxy.workstation-vessel-dragproxy: 460×353, no children, opacity: .7, and still the embodiment's active generation (probe at d921de0cff: generation 1, pane proxy, ownsPane: false, settled: true).
Timing probes, relative to the OS mouse-up:
| phase |
t |
| pane proxy opens in main |
+1089 ms |
| drop commits, documents adopted |
+1301 ms |
| main's projection refresh settles |
+2095 ms |
| vessel close dispatched |
+2097 ms |
the vessel's release restores the proxy |
+2096 ms: matched, refused, no retire |
| the drop settles |
+2097 ms: committed: true, current: false, so the promote was skipped |
The Problem
The vessel's close fires the coordinator's native release, clearNativeWindowDropCandidate → DragTarget#onRemoteDragLeave. That leave path calls restoreDragEmbodiment and clears the payload unconditionally. By then the commit has adopted the pane, so VesselEmbodiment#restore refuses: the placeholder's parent is gone, and it keeps its record. When the owner commit then settles, DragTarget's settle (src/dashboard/dock/window/DragTarget.mjs:438) gated its promote on current, the payload being the current one. It found the payload cleared and skipped. Neither retire path ran, so the generation stayed live.
The Architectural Reality
- Design authority: the
VesselProxyEmbodiment#promote description says "The proxy is retired without destroying the pane", and scene 2's cleanup contract (:2456) forbids residue.
resolveRecord matches the active record by item, source window and target window only. The identity names no generation, so after a successful leave restore, a successor under the same identity would match a predecessor's late promote (RA-1 on #19779).
Decision Record impact: none.
The Fix
DragTarget's leave path remembers a payload whose restore the embodiment refused. A late committed completion promotes only that payload's generation, and only while no successor hovers the target. A restored generation, and a successor's, is never touched by a predecessor's commit. A destroyed target still settles nothing, and the coordinator still sees no commit (current ? committed : null).
Acceptance Criteria
Out of Scope
- #19776 (scene 2's oracles and hand).
- #19778 (the lingering vessel).
Related
#16498 (parent) · #19773 / #19776 · #19778 · #19764 / #19767 · defect-note fingerprint a2564a59623a3d5a
Origin Session ID: d224fd7e-cf9a-4197-8413-2871327ec30b
Retrieval Hint: "native titlebar return empty workstation-vessel-dragproxy residue committed promote"
Sub of #16498. After a native titlebar return, an invisible empty proxy is left in main's DOM and in the embodiment's state. What the user sees works. This was the last red between
WorkstationFiveBeatNLscene 2 and #16498's human-QA arm.Context
Scene 2 under the on-contract corner aim (#19776), 2026-10-15. The return commits exactly as the retained preview predicts (
:2412). Then:2456, "native terminal cleanup must leave no preview or proxy residue", read{preview: false, proxy: true}for its full 5 s poll. The leftover isDIV.neo-dock-dragproxy.workstation-vessel-dragproxy: 460×353, no children,opacity: .7, and still the embodiment'sactivegeneration (probe atd921de0cff: generation 1, pane proxy,ownsPane: false,settled: true).Timing probes, relative to the OS mouse-up:
restores the proxycommitted: true,current: false, so the promote was skippedThe Problem
The vessel's close fires the coordinator's native release,
clearNativeWindowDropCandidate→DragTarget#onRemoteDragLeave. That leave path callsrestoreDragEmbodimentand clears the payload unconditionally. By then the commit has adopted the pane, soVesselEmbodiment#restorerefuses: the placeholder's parent is gone, and it keeps its record. When the owner commit then settles,DragTarget's settle (src/dashboard/dock/window/DragTarget.mjs:438) gated its promote oncurrent, the payload being the current one. It found the payload cleared and skipped. Neither retire path ran, so the generation stayed live.The Architectural Reality
VesselProxyEmbodiment#promotedescription says "The proxy is retired without destroying the pane", and scene 2's cleanup contract (:2456) forbids residue.resolveRecordmatches theactiverecord by item, source window and target window only. The identity names no generation, so after a successful leave restore, a successor under the same identity would match a predecessor's late promote (RA-1 on #19779).Decision Record impact: none.
The Fix
DragTarget's leave path remembers a payload whose restore the embodiment refused. A late committed completion promotes only that payload's generation, and only while no successor hovers the target. A restored generation, and a successor's, is never touched by a predecessor's commit. A destroyed target still settles nothing, and the coordinator still sees no commit (current ? committed : null).Acceptance Criteria
DockCrossWindowParticipation.spec.mjsruns the real participation and proxy embodiment through the pane and header-successor cases.:2456(b137d5b029, stacked on #19776).Out of Scope
Related
#16498 (parent) · #19773 / #19776 · #19778 · #19764 / #19767 ·
defect-notefingerprinta2564a59623a3d5aOrigin Session ID: d224fd7e-cf9a-4197-8413-2871327ec30b Retrieval Hint: "native titlebar return empty workstation-vessel-dragproxy residue committed promote"