mirror of
https://github.com/stablyai/orca.git
synced 2026-10-23 08:03:39 +00:00
A pane's xterm write pipeline can die while its shell keeps running: a synchronous throw escaping an unguarded write callback wedges WriteBuffer (issue #2836), and write() on a disposed terminal silently drops its completion callback (verified against vendored xterm 6.1.0-beta.287 — it does NOT throw, falsifying the output scheduler's disposed-race catch). Every recovery path we have (dead-session reconcile #6514/#7002, hibernation wake #7145, the allDead activation generation bump) gates on the PTY being dead, so these panes stayed fossils: last frame painted, every keystroke and byte of output silently dropped, delivery ack credits leaking, until the user reloaded the window (issue #8104 class). Detection is probe-certified, mirroring replay-guard.ts: - a scheduler write whose completion stalls gets an empty probe write; a probe that never parses certifies the pipeline dead (catches both the wedged WriteBuffer and the disposed-terminal case) and credits the queued deliveries so main's in-flight window no longer leaks - the replay guard's existing wedged release ("pane likely needs recovery") now actually hands the pane to recovery - user input rejected by an unbound transport (detached during a remount/move and never rebound) arms recovery after confirming the PTY is alive via pty:hasPty Recovery reuses the proven remount seam: bump the tab's generation so TerminalPane unmounts, detach() preserves the live PTY, and the remounted pane builds a fresh xterm that reattaches and replays the daemon snapshot — no shell restart, capped per tab to prevent remount storms. The new e2e spec pins both phenotypes end-to-end (wedge → recover, dispose-under-live-bindings → recover); both fail on main and pass with the fix, and the same arc was validated live in a pnpm dev instance.