mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-09-22 08:02:24 +00:00
* fix(workspace): stop switching workspaces from destroying live sessions Switching workspaces rebuilt every pane it was asked to restore, and a window that rebuilt nothing then deleted the workspace outright — tree and store both. Three separate guesses, each one authorizing an irreversible act: - `session_from_tree` erased a pane's id when the tree said `live: false`. That flag is a cached observation from another process, reloaded as false on every server start, so a quiet pane read as dead while its shell was running. The restore had nothing to attach to and spawned a fresh shell over it. - Two servers could start against one config dir. `run_with` decided another server was dead by failing to connect once, then unlinked its socket and bound its own. The loser kept `control.sock` with an empty pane registry, so `MachineGet` reported every pane dead and nothing logged an error. - `finish_hydration` marked a window informed before the rebuild and without looking at the result. `tabs_from_session` drops any tab whose panes all fail to start, which is every tab when the pane socket is unreachable — leaving a window that was empty and authoritative at once, and the next switch deleted a workspace with ten live tabs. Each is now settled by whoever holds the truth: attaching decides whether a pane is there, an advisory lock decides which process is the server, and a deletion needs the machine's own mirror to agree that the workspace is empty. * fix(state): quarantine a corrupt views.json instead of silently discarding it machine.json already sets a corrupt file aside before falling back to defaults; views.json just logged and returned None, and the next save overwrote whatever the file held. Move the quarantine helpers to config so both loaders share them. Also make the no-lock-primitive fallback in the daemon singleton report Unavailable rather than Taken, so a platform without flock still gets a server instead of one that refuses to start. * fix(restore): a failed List no longer reads as every pane being dead Review follow-ups on #410, all three the same shape the PR exists to stamp out: - alive_panes_on flattened a failed List RPC into an empty alive-set, which made pane_attachable respawn every pane in the batch over its running session. The failure now surfaces as None and the attach itself decides, the way session_from_tree already leaves it to. - pub fn run() bypassed the singleton lock entirely; it had no callers, so a future one would have silently reintroduced the split-brain. Removed. - Singleton::path() and the field behind it were unused. Removed. --------- Co-authored-by: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com>