LearnNewsExamplesServices
Frontmatter
id15635
titleTorn-out dock pane strands in dead vessel tree on window close
stateClosed
labels
bugai
assigneesneo-opus-vega
createdAtJul 21, 2026, 2:49 PM
updatedAtJul 24, 2026, 9:32 PM
githubUrlhttps://github.com/neomjs/neo/issues/15635
authorneo-kimi-iris
commentsCount5
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[ ] 15650 Kinetic demo follow-up: the N-window mailbox beat + gesture-drive decision
closedAtJul 24, 2026, 9:32 PM

Torn-out dock pane strands in dead vessel tree on window close

neo-kimi-iris
neo-kimi-iris commented on Jul 21, 2026, 2:49 PM

Context

Found during #15631's AC1 live verification (2026-07-21, this host, real headed Chrome): tearing a dock pane out to an OS window works end-to-end, but closing that window strands the live pane in the dead vessel's view tree — the dock model reintegrates (the tab header returns), the instance does not (its tab page is empty). The click pop-out → reattach path (popOutAgentDetail/reattachAgentDetail) is unaffected and works daily; this is specifically the gesture tear-out → vessel-death return leg.

Live latest-open sweep: checked the live tracker (created-desc, 12 latest) at 2026-07-21T13:05Z; no equivalent. A2A in-flight sweep: no claim on this scope (Clio's #15243 is the tear-out matrix lane — this is runtime evidence inside her #15239 epic's G4 leaf scope, filed as a bug, not a duplicate). KB ticket sweep: #13158/#14610/#14789 cover the design intent; none track this defect.

The Problem (live Neural Link receipt chain)

Reproduced on the Fleet Cockpit with the operator (operator-mailbox) dock item:

  1. Reveal → Pin → scripted tear-out gesture (NL simulate_event: mousedown + arming moves + progressive boundary-crossing moves + terminal mouseup). Vessel born mid-gesture: AgentOSWidget window a2d1e383-… registered in get_window_topology; tearOutPanes.operator = {windowName: 'fm-tearout-operator-…', windowId: 'a2d1e383-…'} committed; the OperatorMailbox instance mounted in the vessel (windowId: a2d1e383). The outbound journey is fully healthy.
  2. Close the vessel window (real OS close).
  3. onWindowDisconnect fires the tear-out branch: tearOutPanes/tearOutPlacements are consumed exact-once, the model op re-adds the tab — the Operator tab header re-projects into the tab bar.
  4. But the live pane never comes home: OperatorMailbox.parentId = neo-viewport-2 — the dead vessel's main view. The docked tab page is empty (no stand-in, no fm-pane-placeholder), the pane's windowId still names the dead window, and get_dom_rect on it times out (its DOM node exists in no live document). The instance is stranded on the shared heap in a zombie tree.

Workaround: a page reload restores everything (fresh projection from the default document) — acceptable for scripted takes, wrong for users.

The Architectural Reality

  • apps/agentos/view/fleet/FleetCockpit.mjs adoptTearOutPane JSDoc is explicit: "Close-after-adoption reintegration is the G4 vessel-lifecycle leaf's scope, deliberately not handled here." The G4 leaf is open in epic #15239 (per its lane broadcast: "G3/G4/teardown… open for self-select").
  • The design for the same-instance return exists: tearOutPaneHandles JSDoc — "a window disconnect never destroys the popup's view tree, so the LIVE instance survives and comes home same-instance through returningTearOutPanes" — and onWindowDisconnect's tear-out branch does call reintegrateTearOutItem(itemId, pane). The model leg (addTab to the remembered placement) executed in my run; the instance re-parent leg did not complete (pane never re-adopted by a live parent).
  • Unit coverage (fleetCockpitTearOut.spec.mjs) asserts the model-level reintegration (addTab/placements); no e2e witness covers the live-instance return on the cockpit. The dockdemo childapp's tear-out round-trip is e2e-proven (DemoBDockTearOutNL.spec.mjs) — the cockpit's vessel-death return is the uncovered sibling.
  • Unknowns (honestly untested): whether the gap is item-specific (operator) or general (detail gesture tear-out vs its click path); whether the drag-back-home gesture (vessel dragged over the main window → in-gesture reattach) works and only vessel-death strands.

The Fix

Complete the G4 vessel-lifecycle leaf on the cockpit: on vessel death, reparent the captured live pane into a live tree in its remembered placement (the returningTearOutPanesresolveDockComponentRef handoff must end with the pane mounted in the re-projected tab page), and add the e2e witness (cockpit NL tear-out round-trip: vessel death → same-instance home, parentId/windowId on the main window, pane body rendered).

Acceptance Criteria

  • Closing a tear-out vessel returns its live pane to its remembered docked tab — same instance (id unchanged), parentId in the main window's tree, pane body rendered (NL-observable).
  • Verified for at least the operator and detail items (or the item-specific delta documented).
  • e2e witness committed (sibling of fleetCockpitTearOut.spec.mjs / DemoBDockTearOutNL.spec.mjs); the model-level specs keep passing.
  • The drag-back-home leg's behavior is established and recorded (works or explicitly descoped).

Out of Scope

  • The click pop-out vessel lifecycle (popOutAgentDetail/reattachAgentDetail) — healthy.
  • The dockdemo childapp surfaces (proven by DemoBDockTearOutNL).
  • The #15631 film take itself (works around this via reload-restore).

Related

#15239 (epic — G4 vessel-lifecycle leaf scope) · #15243 (tear-out portability matrix lane) · #15631 (surfacing lane; AC1 evidence) · #14610 (vessel admission state machine — the healthy sibling) · DemoBDockTearOutNL.spec.mjs (dockdemo round-trip proof)

Origin Session ID: 557fd3c7-7307-499b-9c35-d07fe1c2efcd

Retrieval Hint: tear-out vessel death pane stranded zombie tree returningTearOutPanes G4 reintegration FleetCockpit operator mailbox

tobiu referenced in commit b4c4289 - "fix(agentos): torn-out pane strands in dead vessel tree on window close (#15635) (#15823) on Jul 24, 2026, 9:32 PM
tobiu closed this issue on Jul 24, 2026, 9:32 PM