Context
2026-10-07: in the installed Fleet Manager, the operator and @neo-gpt-sophie tore a tab out of the app, dropped it outside, then dragged the new window back over the app. The main app showed no drop zones. Workstation, which publishes a cross-window sort group, docked a committed popup moved over main back into it in @neo-fable's 2026-09-26 probes. The difference is configuration that nothing checks.
The Problem
A workspace can turn tear-out on and still have no way back, and nothing says so:
enableDockTearOutLifecycle: true makes Workspace#getDockProjectionOptions return {enableDockTearOut: true, ...tearOutHandlers} (src/dashboard/dock/Workspace.mjs). Tear-out works.
- The way back needs a cross-window sort group.
LayoutAdapter threads crossWindowSortGroup into each tab zone's sortGroup, the key DragCoordinator registers zones under. The workspace composes its default cross-window Participation only when it publishes one (Workspace.mjs:61, window/Participation.mjs:636). Without it, a window dragged back finds no registered target, and no drop zones are painted.
LayoutAdapter defaults the group to null. The base hook publishes none.
Fleet Manager's cockpit (apps/agentos/view/fleet/cockpit/Container.mjs, VesselContainer.mjs in neomjs/neo-agent-institution) enables the lifecycle but publishes no group. Workstation publishes one explicitly (apps/workstation/view/VesselWorkspace.mjs, PopupWorkspace.mjs). WebStudio hit the same omission on 2026-09-03; its fix added the group. #18197 closed the sibling case, a lost enableDockTearOut, with a throw at projection. The sort group has no such guard.
The Fix
Make "tear-out on, no way back" impossible to ship silently. Two shapes:
- Guard (smallest; safe for 13.2): at projection, when
enableDockTearOut is on and no crossWindowSortGroup is published, report it once (console.warn naming the workspace class), so the omission shows in the first manual test. #18197's throw is the precedent for escalating later. A throw now would break every consumer that upgrades before publishing a group.
- Default: when the lifecycle is on and no group is published, use a default group. Whether unrelated workspaces may then share a group is a design decision for the docking design record's §2.3 owner, not this ticket.
Recommendation: ship 1 with 13.2, and decide 2 after the cut.
Acceptance Criteria
Out of Scope
- Fleet Manager's own fix, publishing its group (Institution; routed to its owner).
- A default group (shape 2): decided after the cut.
Related
#18197 (the sibling guard for enableDockTearOut) · #19350 (the default cross-window participation for a published group) · neomjs/neo-agent-institution#12 (where the operator met it)
Live latest-open sweep: org search "crossWindowSortGroup" and "tear-out no way back drop zones" (open): only neomjs/neo-agent-institution#12, which mentions it; no equivalent. A2A: no claim on the dock sort group.
Origin Session ID: 9aa8aa9b-2502-458b-976b-eec8a223218e
Retrieval Hint: "dock tear-out crossWindowSortGroup no drop zones drag back Participation silent"
Context
2026-10-07: in the installed Fleet Manager, the operator and @neo-gpt-sophie tore a tab out of the app, dropped it outside, then dragged the new window back over the app. The main app showed no drop zones. Workstation, which publishes a cross-window sort group, docked a committed popup moved over main back into it in @neo-fable's 2026-09-26 probes. The difference is configuration that nothing checks.
The Problem
A workspace can turn tear-out on and still have no way back, and nothing says so:
enableDockTearOutLifecycle: truemakesWorkspace#getDockProjectionOptionsreturn{enableDockTearOut: true, ...tearOutHandlers}(src/dashboard/dock/Workspace.mjs). Tear-out works.LayoutAdapterthreadscrossWindowSortGroupinto each tab zone'ssortGroup, the keyDragCoordinatorregisters zones under. The workspace composes its default cross-windowParticipationonly when it publishes one (Workspace.mjs:61,window/Participation.mjs:636). Without it, a window dragged back finds no registered target, and no drop zones are painted.LayoutAdapterdefaults the group tonull. The base hook publishes none.Fleet Manager's cockpit (
apps/agentos/view/fleet/cockpit/Container.mjs,VesselContainer.mjsin neomjs/neo-agent-institution) enables the lifecycle but publishes no group. Workstation publishes one explicitly (apps/workstation/view/VesselWorkspace.mjs,PopupWorkspace.mjs). WebStudio hit the same omission on 2026-09-03; its fix added the group. #18197 closed the sibling case, a lostenableDockTearOut, with a throw at projection. The sort group has no such guard.The Fix
Make "tear-out on, no way back" impossible to ship silently. Two shapes:
enableDockTearOutis on and nocrossWindowSortGroupis published, report it once (console.warnnaming the workspace class), so the omission shows in the first manual test. #18197's throw is the precedent for escalating later. A throw now would break every consumer that upgrades before publishing a group.Recommendation: ship 1 with 13.2, and decide 2 after the cut.
Acceptance Criteria
crossWindowSortGroupreports the omission once, naming the workspace class (unit).VesselWorkspace, reports nothing (unit).Out of Scope
Related
#18197 (the sibling guard for
enableDockTearOut) · #19350 (the default cross-window participation for a published group) · neomjs/neo-agent-institution#12 (where the operator met it)Live latest-open sweep: org search "crossWindowSortGroup" and "tear-out no way back drop zones" (open): only neomjs/neo-agent-institution#12, which mentions it; no equivalent. A2A: no claim on the dock sort group.
Origin Session ID: 9aa8aa9b-2502-458b-976b-eec8a223218e
Retrieval Hint: "dock tear-out crossWindowSortGroup no drop zones drag back Participation silent"