Files
hermes-agent/apps
Zeus-Deus 0cb3e4cfd8 fix(desktop): pin a branch child's owning socket for the tile's lifetime
Routing the create and stamping the optimistic row still left a
remote-owned branch child flickering into "Couldn't open this session —
Session keeps losing its backend runtime right after resuming". The RPCs
were right and every resume succeeded; the OWNING SOCKET was the
casualty. Three gaps, one cause — nothing durable named the owner:

- openSessionTile persisted ownerRoute only for workspaceMode==='bots',
  so the branch tile pinned nothing in the gateway keep-set
  (openTileGatewayScopes / foregroundSessionScopes). The pruner closed
  the owner socket, the backend orphan-reaped the draft runtime,
  session.reclaimed unbound the tile, resume re-armed and succeeded on a
  fresh socket the next recompute closed again — until the resume-storm
  breaker (#93892) latched the error card at TILE_RESUME_STORM_LIMIT.
  Persist the route for sessions-mode tiles whose opener knows the exact
  owner, and stop a route-less re-scope from clobbering it.

- forkBranch, unlike both sibling routed creates in the same file, never
  called setSessionOwnerHint/holdSessionOwnerUntilForeground — so in the
  gap between session.branch returning and the tile publication landing,
  no keep-set rung named the owner and a prune could reap the just-minted
  draft runtime before the first prompt. Add both, mirroring the
  siblings; the hold retires once the tile's own route covers the scope.

- resetTileRuntimeBindings preserved cross-connection runtimes only for
  bot tabs, so a flapping sibling connection (an SSH source re-dialing)
  dropped the branch tile's healthy binding on every reconnect, re-arming
  resume each time — the same storm by another path. Preserve any
  owner-routed tile; the owner's own reconnect still rebinds.

Also keep open tiles' rows in sessionsToKeep: a branch child is a draft
the aggregator cannot return until its first turn persists it, so the
next background refresh silently dropped the optimistic "draft: branch
#N" row and the sidebar showed no trace of the branch until first send.

Each fix verified RED by reverting its line. Live acceptance against a
remote-owned parent branched from another connection: draft row visible
immediately and stable across refreshes, tile carries the owner route,
first turn accepted and completed by the owning backend, and no
storm/error card through the full 120s storm window — before the fixes
the card latched at ~20s.
2026-09-01 22:58:48 -05:00
..