Context
Found in manual testing of apps/workstation on dev (2026-10-22): resorting tab headers in the pane that holds 12 tabs. In @tobiu's screen recording (about 39.4–41.6 s), "Runtime Health Envelope" is dragged and the pointer rises toward the workspace's top edge. Meanwhile the only other visible header, "Distributed Trace Explorer", leaves its strip. It rises above its row, is clipped by the pane's top border, disappears, and reappears above the strip further left. The headers "fly away" toward the top-left.
A further frame from the same drag (the operator's screenshot follows in a comment) shows "Priority Alert Observatory" being dragged inside its pane. Meanwhile the other header's teal active-tab underline sits outside the pane, over the neighbouring pane's header to the left.
Measurements
Headless Chromium, 2200×1000, at 8bb3574d0f (its src/, apps/ and resources/scss/ are identical to dev at 84b711878a). A requestAnimationFrame sampler records every tab button's rect against the strip box.
| gesture |
tab buttons outside the strip during the drag |
| 2nd visible tab, 180 px left, in-strip |
none |
| 2nd visible tab, into the pane body and back |
none |
| 2nd visible tab, 45 px rise above the strip and back, leftwards |
none |
| 3rd visible tab ("Workspace Topology Inspector"), 120 px right, 45 px rise and back |
126 frames, 2 of 2 runs: the button is absolutely positioned and travels from the strip (y 105) to (−180, 0), the window's top-left corner offset by its own width |
The reproduction moves the dragged tab's own strip button; the recording moves its sibling. Both are strip headers absolutely positioned and sent toward the top-left during an in-window drag.
The Problem
During a tab drag the strip's SortZone positions its items absolutely, freezing their rects for the gesture. A 45 px rise takes the roughly 32 px proxy fully out of the 33 px strip. That is the base container.SortZone's boundary-exit condition (detachThreshold, then isWindowDragging and dragBoundaryExit), and the dock's TabSortZone layers its window-drag embodiment on top (startWindowDrag / endWindowDrag). That this path is entered during the reproducing gesture is inferred, not traced.
At least one header gets coordinates that are not its strip slot, and a CSS transition makes the move a visible flight across the window. Which write does it is not yet traced.
Design authority: the dock TabSortZone#startWindowDrag docblock. "No dashboard layout re-flow: a tab strip's geometry is owned by the committed model projection, which this gesture has not touched." A header leaving its strip while the gesture is still in-window contradicts that.
The Architectural Reality
src/draggable/container/SortZone.mjs: the absolute-positioning setup for sortable items, the boundary-exit / window-drag transition (detachThreshold, reattachThreshold, dragBoundaryExit), and the cleanup that restores item styles.
src/dashboard/dock/interaction/TabSortZone.mjs: startWindowDrag / endWindowDrag (in-window proxy hidden or restored, base reorder parked or un-parked), plus the cross-zone events on every move.
- Prior art: a returned tab header kept absolute drag positioning (
top: 0) outside its strip after a drag, on 2026-10-07 in another consumer. That is the same item-styles seam, after the drag rather than during it.
The Fix
First trace which write sends the button to (−180, 0): the base SortZone's park or window-drag path, or the dock's startWindowDrag. Then keep every strip header inside its strip slot for the whole in-window gesture. Hiding a header that is not shown (e.g. the dragged original) must not move it across the window, and its transition must not animate it there.
Acceptance Criteria
Out of Scope
- The flash after the drop: #19987, the overflow plugin's recapture window.
- Cross-pane and edge-preview behaviour of a docked pane's tab drag, which is legitimate in a docked pane. For the maximized case see #19986.
Related
- #19986: a tab drag in a maximized pane targeting the layout behind it. Same gesture family, maximized.
- #19533 (closed): a vessel parked at the display's top-left during a cross-window drag.
Live latest-open sweep: checked latest 20 open issues at 2026-10-22T09:52:58Z; no equivalent found.
Keyword sweep: as for the sibling ticket filed with this one; closed adjacent only.
A2A claim sweep: no overlapping lane-claim.
MC sweep: "tab header resorting flickers on drop… headers fly to the top-left…", 6 results; the 2026-10-07 retained-absolute-position finding is adjacent, not a decision.
Own-assignment sweep: none overlapping.
Origin Session ID: 70e59a84-efd6-4e7a-9262-c5478bd314ff
Retrieval Hint: "tab drag strip header flies to top-left, SortZone absolute positioning, window-drag boundary exit"
Context
Found in manual testing of
apps/workstationondev(2026-10-22): resorting tab headers in the pane that holds 12 tabs. In @tobiu's screen recording (about 39.4–41.6 s), "Runtime Health Envelope" is dragged and the pointer rises toward the workspace's top edge. Meanwhile the only other visible header, "Distributed Trace Explorer", leaves its strip. It rises above its row, is clipped by the pane's top border, disappears, and reappears above the strip further left. The headers "fly away" toward the top-left.A further frame from the same drag (the operator's screenshot follows in a comment) shows "Priority Alert Observatory" being dragged inside its pane. Meanwhile the other header's teal active-tab underline sits outside the pane, over the neighbouring pane's header to the left.
Measurements
Headless Chromium, 2200×1000, at
8bb3574d0f(itssrc/,apps/andresources/scss/are identical todevat84b711878a). ArequestAnimationFramesampler records every tab button's rect against the strip box.The reproduction moves the dragged tab's own strip button; the recording moves its sibling. Both are strip headers absolutely positioned and sent toward the top-left during an in-window drag.
The Problem
During a tab drag the strip's
SortZonepositions its items absolutely, freezing their rects for the gesture. A 45 px rise takes the roughly 32 px proxy fully out of the 33 px strip. That is the basecontainer.SortZone's boundary-exit condition (detachThreshold, thenisWindowDragginganddragBoundaryExit), and the dock'sTabSortZonelayers its window-drag embodiment on top (startWindowDrag/endWindowDrag). That this path is entered during the reproducing gesture is inferred, not traced.At least one header gets coordinates that are not its strip slot, and a CSS transition makes the move a visible flight across the window. Which write does it is not yet traced.
Design authority: the dock
TabSortZone#startWindowDragdocblock. "No dashboard layout re-flow: a tab strip's geometry is owned by the committed model projection, which this gesture has not touched." A header leaving its strip while the gesture is still in-window contradicts that.The Architectural Reality
src/draggable/container/SortZone.mjs: the absolute-positioning setup for sortable items, the boundary-exit / window-drag transition (detachThreshold,reattachThreshold,dragBoundaryExit), and the cleanup that restores item styles.src/dashboard/dock/interaction/TabSortZone.mjs:startWindowDrag/endWindowDrag(in-window proxy hidden or restored, base reorder parked or un-parked), plus the cross-zone events on every move.top: 0) outside its strip after a drag, on 2026-10-07 in another consumer. That is the same item-styles seam, after the drag rather than during it.The Fix
First trace which write sends the button to
(−180, 0): the base SortZone's park or window-drag path, or the dock'sstartWindowDrag. Then keep every strip header inside its strip slot for the whole in-window gesture. Hiding a header that is not shown (e.g. the dragged original) must not move it across the window, and its transition must not animate it there.Acceptance Criteria
test/playwright/e2e/workstation/(e.g.WorkstationTabDragHeadersStayNL.spec.mjs) drags the 12-tab pane's 3rd visible tab with the reproducing gesture (120 px right, a 45 px rise above the strip, back down) using a real pointer. It samples every frame and asserts all tab buttons stay inside the strip. It must be red ondev(126 frames outside,(−180, 0)) and green with the fix, and it joins the hosted Workstation tier (#19655).Out of Scope
Related
Live latest-open sweep: checked latest 20 open issues at 2026-10-22T09:52:58Z; no equivalent found. Keyword sweep: as for the sibling ticket filed with this one; closed adjacent only. A2A claim sweep: no overlapping lane-claim. MC sweep: "tab header resorting flickers on drop… headers fly to the top-left…", 6 results; the 2026-10-07 retained-absolute-position finding is adjacent, not a decision. Own-assignment sweep: none overlapping.
Origin Session ID: 70e59a84-efd6-4e7a-9262-c5478bd314ff Retrieval Hint: "tab drag strip header flies to top-left, SortZone absolute positioning, window-drag boundary exit"