Sub of #18304 (Workspace decomposition). Blocked by #18303 — needs the popup-as-Workspace claim path.
The Problem
This is the lead datum of D#18150, and it falsified two options on its own: src/dashboard/dock/window/TearOut.mjs exists, is imported, and the tear-out cluster stayed in Workspace.mjs anyway. A destination existing is not a mechanism for behaviour reaching it — which killed Option C, and then Option D when its own author noticed the same fact refuted the proposal he had just made.
By member span (@neo-fable's census): ~280 lines of capture / adopt / reparent / release / settle / return hooks and their fields, plus ~60 lines that fold into resolvePane rather than moving.
The Fix
Move the choreography into the existing window/TearOut.mjs; fold the ~60 resolver-shaped lines into resolvePane. tearOutPlacements (capture :892, consume :1347, wipe :1357/:1504 inside retireTearOutState :1470) travels with the concern.
Why this is gated: what step 4 still needs is the popup that is a Workspace, born through the claim — #18303's ownership decision. The popup arm already proved identity survives a real hop for a nested subtree (same component, provider and store ids, 20 descendants, 0 lost), and A1 proved same-instance adoption by projection in-window. What is not yet proven is birth-through-claim, and that is #18303's to land.
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
window/TearOut.mjs |
D#18150 lead datum |
receives capture/adopt/reparent/release/settle/return + tearOutPlacements |
— |
class docblock |
~280-line member span |
Workspace#resolvePane |
D#18150 step 4 |
absorbs the ~60 resolver-shaped lines |
— |
method docblock |
span census |
Workspace tear-out surface |
the Ownership test |
deleted, not forwarded |
none — zero-backcompat ruling |
— |
counts fall in-PR |
Acceptance Criteria
Out of Scope
- The lifecycle subscription (
Workspace:535 worker connect/disconnect) — that is its own leaf and the Group deletes it.
- Popup birth semantics — #18303.
manager.Window geometry — untouched, and it stays geometry-only.
Avoided Traps
- Assuming destination-exists means the move is mechanical. It has existed for months. Whatever kept the cluster in place is the actual work; name it in the PR body.
- Moving the resolver lines wholesale. ~60 of them fold into
resolvePane; moving them into TearOut.mjs recreates the split one level down.
- Starting before the claim path exists. Without birth-through-claim the adopt half has no counterpart and the extraction encodes today's shape.
Related
#18304 (epic) · #18303 (blocker) · window/TearOut.mjs (the destination that already exists) · D#18150 step 4 · Workspace.mjs :892, :1347, :1357, :1470, :1504
Live latest-open sweep: latest 20 open issues at 2026-09-04T18:12Z; no equivalent. A2A claim sweep: no claim. Own-assignment sweep: none on this surface. Memory Core: stale-2025 recall degradation today — null, not clean.
Decision Record impact: depends-on — consumes #18303's claim path.
Origin Session ID: b983b2a8-18bc-4dd0-a63f-23380dc3a49d
Sub of #18304 (Workspace decomposition). Blocked by #18303 — needs the popup-as-Workspace claim path.
The Problem
This is the lead datum of D#18150, and it falsified two options on its own:
src/dashboard/dock/window/TearOut.mjsexists, is imported, and the tear-out cluster stayed inWorkspace.mjsanyway. A destination existing is not a mechanism for behaviour reaching it — which killed Option C, and then Option D when its own author noticed the same fact refuted the proposal he had just made.By member span (@neo-fable's census): ~280 lines of capture / adopt / reparent / release / settle / return hooks and their fields, plus ~60 lines that fold into
resolvePanerather than moving.The Fix
Move the choreography into the existing
window/TearOut.mjs; fold the ~60 resolver-shaped lines intoresolvePane.tearOutPlacements(capture :892, consume :1347, wipe :1357/:1504 insideretireTearOutState:1470) travels with the concern.Why this is gated: what step 4 still needs is the popup that is a Workspace, born through the claim — #18303's ownership decision. The popup arm already proved identity survives a real hop for a nested subtree (same component, provider and store ids, 20 descendants, 0 lost), and A1 proved same-instance adoption by projection in-window. What is not yet proven is birth-through-claim, and that is #18303's to land.
Contract Ledger Matrix
window/TearOut.mjstearOutPlacementsWorkspace#resolvePaneWorkspacetear-out surfaceAcceptance Criteria
tearOutPlacementslive inwindow/TearOut.mjs; the ~60 resolver-shaped lines are folded intoresolvePane, not moved wholesale.Workspace.mjsretains no tear-out method, config or state field — no forwarding wrappers; counts fall in this PR.enableDockTearOutLifecycle: falseregisters zero tear-out state — the declinability the whole vehicle question turned on.retireTearOutStatestill wipes on the paths it wipes today; no placement outlives its workspace.Out of Scope
Workspace:535worker connect/disconnect) — that is its own leaf and the Group deletes it.manager.Windowgeometry — untouched, and it stays geometry-only.Avoided Traps
resolvePane; moving them intoTearOut.mjsrecreates the split one level down.Related
#18304 (epic) · #18303 (blocker) ·
window/TearOut.mjs(the destination that already exists) · D#18150 step 4 · Workspace.mjs :892, :1347, :1357, :1470, :1504Live latest-open sweep: latest 20 open issues at 2026-09-04T18:12Z; no equivalent. A2A claim sweep: no claim. Own-assignment sweep: none on this surface. Memory Core: stale-2025 recall degradation today — null, not clean.
Decision Record impact:
depends-on— consumes #18303's claim path.Origin Session ID: b983b2a8-18bc-4dd0-a63f-23380dc3a49d