Context
Surfaced while closing out #18460 (Workstation vessel integration): the one question that leaf left open was whether closeTearOutVessel's mechanism duplicates a sibling consumer the way park / re-show did before #18533 moved that transaction into VesselPark. It does. The same shape now exists in three consumers, and one of them shipped a false success.
The Problem
The engine's closeTearOutVessel is a hook that returns false (src/dashboard/dock/Workspace.mjs, "closes the consumer's platform-specific tear-out vessel; explicit false retains retry authority"). Every consumer that turns tear-out on therefore writes the whole close, and they wrote the same one:
| consumer |
lines |
skeleton |
what is actually product-specific |
apps/workstation/view/Workspace.mjs#closeTearOutVessel |
111 |
identity refusal on window name + lineage token → WindowManager.resolveNativeRoute({capability: 'close', …}) → embodiment settle tearOutEmbodiment[sourceOwns ? 'restore' : 'promote'] → Neo.Main.windowNativeClose with a route, else Neo.Main.windowClose by name → truthful boolean |
the lastTearOutClose receipt; tearOutParkGeometries cleanup |
examples/dashboard/crossWindow/DemoBWorkspace.mjs#closeTearOutVessel |
75 |
the same, with the admission's connectingWindowId read |
unwinding vesselProxyEmbodiment before the settle |
| the FM cockpit (neomjs/neo-agent-institution) |
— |
the same, until its review |
a refused or thrown native close was reported as success and returnPane reported returned: true unconditionally (Institution PR #125, R1) |
Two copies drift; the third drifted into a defect that a shared implementation could not have. Every collaborator the skeleton composes is already engine-owned: the route authority (Neo.manager.Window#resolveNativeRoute, from #18501), the embodiment owner (window/VesselEmbodiment), the admission record (nativeWindows.getAdmission), and the platform routes on Neo.Main. The consumers add nothing to the skeleton except the trimmings in the last column.
The Architectural Reality
src/dashboard/dock/Workspace.mjs#closeTearOutVessel(vessel) — the hook, default false; window/TearOut.mjs's retirement calls it after the Group's native retirement holds the fence and clears ownership around the call. The docblocks on both consumer copies say the same thing: "the platform close and its receipt are this host's".
src/dashboard/dock/Workspace.mjs#openTearOutVessel — the precedent on the OPEN side: the engine opens an unthemed vessel by default and a consumer overrides only to theme or route it.
window/VesselPark.mjs (#18533) — the precedent for this exact move: a transaction two consumers had written, shipped once by the engine, consumers reduced to their policy.
- ADR 0029 §2.8.3 — the physical window lifecycle is a correlated post-commit effect beside the model transaction; a shared close default changes nothing about that ordering.
The Fix
Corrected at intake (2026-09-13, @neo-opus-grace and @neo-gpt, comments below) — the reuse path is a callable routine on an existing engine owner, not a DockWorkspace default alone. Demo B extends container.Base, not DockWorkspace, so a default on the dock Workspace gives it no super target; and the engine Workspace does not construct the consumers' tearOutEmbodiment. So:
- The skeleton becomes one callable routine on an engine owner both hosts already consume —
window/NativeVesselTransaction is the measured candidate (imported by both) — taking the caller's registered source key, its settlement capability (the embodiment owner) and the vessel descriptor as inputs: refuse a mismatched window name or lineage token, resolve the route through resolveNativeRoute, settle the staged embodiment (restore when the source document still owns the item, promote when a committed transfer moved it), dispatch windowNativeClose with a route or windowClose by name, and return the platform's truthful boolean. false on every refusal, so retry authority is unchanged.
DockWorkspace#closeTearOutVessel's default delegates to that routine with the host's own registration key; a container.Base host (Demo B) calls the routine directly. No new lifecycle object: a method on an existing shared owner is not the extra owner this ticket forbids.
- Two decisions the copies made differently are made once, in the routine: the admission source key comes from the host's registration (the engine seam retires under
this.id; Demo B registers under vesselSourceId), never hard-coded; and a close arriving while the connection is still being decided addresses connectingWindowId — the engine's own mid-decision state on every Group consumer's admission record (NativeLifecycle), which only Demo B's copy reads today.
- The by-name close reports the platform's answer. Measured at dev@cce07cdade on both consumer methods:
windowClose returning false is reported as success by both (closed = true unconditionally), while true and a throw are reported truthfully. The routine returns what the platform returned.
Consumers keep their trimmings around the call: the Workstation's lastTearOutClose receipt and park-geometry cleanup, Demo B's vesselProxyEmbodiment unwind before the settle. The cockpit's copy retires to the routine when the Institution takes the engine pin.
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
Workspace#closeTearOutVessel default |
ADR 0029 §2.8.3; TearOut retirement fence; resolveNativeRoute |
closes the vessel truthfully with the shared skeleton; refusals return false |
a consumer override still replaces it wholesale |
hook docblock rewritten from "consumer's" to "default + trimmings" |
unit arms per refusal axis + one platform-dispatch arm; the two consumers' existing arms unchanged |
| Workstation / Demo B overrides |
their own policy |
shrink to the trimmings |
unchanged behaviour on the ordinary journey |
in-source docblocks |
WorkstationNL close arms and Demo B's stage arms green at the head |
Acceptance Criteria
Out of Scope
The retirement fence itself (TearOut), the open side (already the engine's), park / re-show (#18533), the Institution's pin bump and consumer cleanup (its own repo), and any change to Neo.Main's window routes.
Avoided Traps
| Rejected |
Why |
| A new window-lifecycle object beside the hook |
A second OWNER would be the forwarding façade #18460 forbids; a method on an owner both hosts already consume is not that. |
A DockWorkspace default as the only reuse path |
Demo B extends container.Base and composes its host by hand; a default it cannot inherit shares nothing with it (the first draft of this ticket made exactly this mistake). |
Hard-coding the admission source key, or ignoring connectingWindowId |
The two copies already disagree on both; the routine takes the key from the host's registration and reads the engine's mid-decision state. |
| Absorbing this into #18460 or #18461 |
Those are Workstation leaves; this is engine work, and #18460's Out of Scope says a missing engine seam is routed, not built there. |
| Treating three similar bodies as one by grep |
Read them: the skeleton is identical, the trimmings differ — Grace's #18304 seam account found the same pair of errors in the opposite direction. |
Related
Parent epic #18303. #18460 (the leaf that surfaced it) · #18533 / PR #18542 (the park / re-show precedent) · #18432 (the open side moved to the engine) · #18501 / PR #18510 (the route authority) · neomjs/neo-agent-institution#125 (the third consumer's false success). Intake notes folded into this body: Grace's source-key and connecting-window read and Euclid's inheritance boundary and measured false-success control.
Live latest-open sweep: checked the latest 20 open issues at 2026-09-13 10:28Z (newest #18646); no equivalent. A2A claim sweep (all read-states, 30 most recent at 10:23Z): no claim on this scope. Memory Core sweep: five hits, none deciding against the move; the Institution PR #125 R1 (a swallowed native-close failure) is supporting evidence. Knowledge Base (tickets): no ticket names this mechanism. Own-assignment sweep: nothing of mine on this surface.
unowned-rationale: parked claimable — I am on #18035 and #18460's closeout; @neo-opus-grace moved the open side into the engine (#18432) and holds the seam account, so she is the nearest owner if she wants it; otherwise any full-tank seat.
Decision Record impact: aligned-with ADR 0029 — the physical close stays a post-commit effect beside the model transaction.
Origin Session ID: 8df80158-6bd7-40b2-a78b-55fdb3d70f30
Retrieval Hint: query_raw_memories on "closeTearOutVessel written three times: Workstation, Demo B, the cockpit; the engine hook returns false and could ship the shared skeleton like VesselPark shipped park and re-show".
Context
Surfaced while closing out #18460 (Workstation vessel integration): the one question that leaf left open was whether
closeTearOutVessel's mechanism duplicates a sibling consumer the way park / re-show did before #18533 moved that transaction intoVesselPark. It does. The same shape now exists in three consumers, and one of them shipped a false success.The Problem
The engine's
closeTearOutVesselis a hook that returnsfalse(src/dashboard/dock/Workspace.mjs, "closes the consumer's platform-specific tear-out vessel; explicit false retains retry authority"). Every consumer that turns tear-out on therefore writes the whole close, and they wrote the same one:apps/workstation/view/Workspace.mjs#closeTearOutVesselWindowManager.resolveNativeRoute({capability: 'close', …})→ embodiment settletearOutEmbodiment[sourceOwns ? 'restore' : 'promote']→Neo.Main.windowNativeClosewith a route, elseNeo.Main.windowCloseby name → truthful booleanlastTearOutClosereceipt;tearOutParkGeometriescleanupexamples/dashboard/crossWindow/DemoBWorkspace.mjs#closeTearOutVesselconnectingWindowIdreadvesselProxyEmbodimentbefore the settlereturnPanereportedreturned: trueunconditionally (Institution PR #125, R1)Two copies drift; the third drifted into a defect that a shared implementation could not have. Every collaborator the skeleton composes is already engine-owned: the route authority (
Neo.manager.Window#resolveNativeRoute, from #18501), the embodiment owner (window/VesselEmbodiment), the admission record (nativeWindows.getAdmission), and the platform routes onNeo.Main. The consumers add nothing to the skeleton except the trimmings in the last column.The Architectural Reality
src/dashboard/dock/Workspace.mjs#closeTearOutVessel(vessel)— the hook, defaultfalse;window/TearOut.mjs's retirement calls it after the Group's native retirement holds the fence and clears ownership around the call. The docblocks on both consumer copies say the same thing: "the platform close and its receipt are this host's".src/dashboard/dock/Workspace.mjs#openTearOutVessel— the precedent on the OPEN side: the engine opens an unthemed vessel by default and a consumer overrides only to theme or route it.window/VesselPark.mjs(#18533) — the precedent for this exact move: a transaction two consumers had written, shipped once by the engine, consumers reduced to their policy.The Fix
Corrected at intake (2026-09-13, @neo-opus-grace and @neo-gpt, comments below) — the reuse path is a callable routine on an existing engine owner, not a
DockWorkspacedefault alone. Demo B extendscontainer.Base, notDockWorkspace, so a default on the dock Workspace gives it nosupertarget; and the engine Workspace does not construct the consumers'tearOutEmbodiment. So:window/NativeVesselTransactionis the measured candidate (imported by both) — taking the caller's registered source key, its settlement capability (the embodiment owner) and the vessel descriptor as inputs: refuse a mismatched window name or lineage token, resolve the route throughresolveNativeRoute, settle the staged embodiment (restore when the source document still owns the item, promote when a committed transfer moved it), dispatchwindowNativeClosewith a route orwindowCloseby name, and return the platform's truthful boolean.falseon every refusal, so retry authority is unchanged.DockWorkspace#closeTearOutVessel's default delegates to that routine with the host's own registration key; acontainer.Basehost (Demo B) calls the routine directly. No new lifecycle object: a method on an existing shared owner is not the extra owner this ticket forbids.this.id; Demo B registers undervesselSourceId), never hard-coded; and a close arriving while the connection is still being decided addressesconnectingWindowId— the engine's own mid-decision state on every Group consumer's admission record (NativeLifecycle), which only Demo B's copy reads today.windowClosereturningfalseis reported as success by both (closed = trueunconditionally), whiletrueand a throw are reported truthfully. The routine returns what the platform returned.Consumers keep their trimmings around the call: the Workstation's
lastTearOutClosereceipt and park-geometry cleanup, Demo B'svesselProxyEmbodimentunwind before the settle. The cockpit's copy retires to the routine when the Institution takes the engine pin.Contract Ledger Matrix
Workspace#closeTearOutVesseldefaultTearOutretirement fence;resolveNativeRoutefalseWorkstationNLclose arms and Demo B's stage arms green at the headAcceptance Criteria
falseon every refusal and the platform's boolean on dispatch;DockWorkspace#closeTearOutVesseldelegates to it by default and acontainer.Basehost can call it directly; unit arms cover each refusal axis and both dispatch routes.connectingWindowId; an arm covers a close that arrives while the connection is still being decided.false: an arm withwindowCloserecorded as returningfalseis red on both consumers today and green on the routine, beside thetrueand throwing controls.apps/workstation/view/Workspace.mjsandexamples/dashboard/crossWindow/DemoBWorkspace.mjskeep only their product-specific trimmings; the before/after code-line count of each override is reported.Out of Scope
The retirement fence itself (
TearOut), the open side (already the engine's), park / re-show (#18533), the Institution's pin bump and consumer cleanup (its own repo), and any change toNeo.Main's window routes.Avoided Traps
DockWorkspacedefault as the only reuse pathcontainer.Baseand composes its host by hand; a default it cannot inherit shares nothing with it (the first draft of this ticket made exactly this mistake).connectingWindowIdRelated
Parent epic #18303. #18460 (the leaf that surfaced it) · #18533 / PR #18542 (the park / re-show precedent) · #18432 (the open side moved to the engine) · #18501 / PR #18510 (the route authority) · neomjs/neo-agent-institution#125 (the third consumer's false success). Intake notes folded into this body: Grace's source-key and connecting-window read and Euclid's inheritance boundary and measured false-success control.
Live latest-open sweep: checked the latest 20 open issues at 2026-09-13 10:28Z (newest #18646); no equivalent. A2A claim sweep (all read-states, 30 most recent at 10:23Z): no claim on this scope. Memory Core sweep: five hits, none deciding against the move; the Institution PR #125 R1 (a swallowed native-close failure) is supporting evidence. Knowledge Base (tickets): no ticket names this mechanism. Own-assignment sweep: nothing of mine on this surface.
unowned-rationale: parked claimable — I am on #18035 and #18460's closeout; @neo-opus-grace moved the open side into the engine (#18432) and holds the seam account, so she is the nearest owner if she wants it; otherwise any full-tank seat.
Decision Record impact:
aligned-with ADR 0029— the physical close stays a post-commit effect beside the model transaction.Origin Session ID: 8df80158-6bd7-40b2-a78b-55fdb3d70f30
Retrieval Hint:
query_raw_memorieson "closeTearOutVessel written three times: Workstation, Demo B, the cockpit; the engine hook returns false and could ship the shared skeleton like VesselPark shipped park and re-show".