Sessions and persistence
A session is a row in Sessions mode. The rows from every host you are connected to appear in one list, grouped by host; the machine in front of you is just another host.
Hosts, sessions, REPLs
A host is a machine running the backend daemon,
sotd.A session is one project directory on one host. The backend calls it a workspace, and the words mean the same thing: one session is one row in Sessions mode and one entry in the session strip along the bottom edge.
Shift+Right/Shift+Leftmove between sessions.Each session has its own agent pane (Claude Code, Codex or a plain shell), its own Julia REPL, and its own kernel, the Julia process that serves Modules mode and file previews. The REPL and kernel start the first time something needs them, running the
juliathatSOT_JULIA_BINnames, else juliaup's default channel, else ajuliaonPATH. The REPL runs your code in the project's environment when the project has aProject.toml; the kernel reads your sources without running them and does not load that environment.
sotdsurveyMain)kernelanalysisMain)kernelTwo sessions never share a Julia Main: each REPL is its own process. Inside one session, you (from the REPL drawer), the session's agent and any helper agents it starts all run code in that session's one REPL. It runs one evaluation at a time and does not queue: a request that arrives while another is running comes back as busy and nothing runs, as long as the running evaluation yields; one that never yields leaves the request waiting until it ends (see The REPL). The julia-repl skill tells agents to use separate julia processes for parallel runs.
Capsules: what a session survives
Each session's agent runs in a capsule: a small supervisor process (sot-capsule) that owns the agent's terminal and records the session to disk (its voyage). The frontend attaches to the capsule to draw the pane; the daemon starts capsules and lists them, but does not hold them up.
| What goes away | What happens to the session |
|---|---|
| the network, or the laptop lid | nothing — the frontend reconnects on its own when the network is back; F5 retries at once |
| the last window on this computer (closed, crashed or killed) | it ends, with the backend; the next window starts with none. Ctrl+Q (⌘Q on macOS) from any pane but the agent and the Terminal drawer asks first and can keep them running |
| one of two windows on this computer | nothing — sessions end with the last window |
| a window relaunch (update) | nothing, if the new window opens within a minute |
| a window on another computer | nothing — the next window reattaches |
| your window, when the sessions run on a remote host | nothing — a remote backend's sessions outlive any window |
| the daemon (restart, upgrade) | the capsule keeps running and the restarted daemon re-adopts it |
When a session's agent restarts, or a session is reopened after it ended, the agent starts a fresh conversation, which first reads the session's handoff file (dev/output/handoff-<handle>.md in the project, when it has one). An earlier conversation comes back only when asked: /resume inside Claude Code, ccb --continue / ccx --continue from a terminal, or a reauth (/reauth), which continues the same conversation on the new account.
On Linux each capsule supervisor runs in its own transient systemd --user scope, outside the daemon's unit, which is what lets it survive a daemon restart. On a host with no reachable user systemd manager it runs in a degraded mode that shares the daemon's lifetime, and the daemon log says why.
Where the state lives
The daemon's state root is ${XDG_STATE_HOME:-~/.local/state}/sot (%LOCALAPPDATA%\sot on Windows): the capsule records and the daemon's own sotd.log. It must be a local, durable filesystem — the daemon refuses to start a capsule on a network or volatile filesystem rather than risk the record. On a home directory shared across servers, give each host its own local state root (see Troubleshooting).
Closing a session from the session list ends its capsule and removes its folder under workspaces/, with the terminal recording (its voyage). The conversation itself lives with the agent, so it stays resumable with /resume in the same project folder. The default row only ends its run and keeps its folder, and a session ended by closing the window keeps its folder for now. When the daemon starts, it removes the leftovers of closed sessions, and a folder that no registry names, if nothing runs in it and nothing in it was written for 24 hours; it skips that second part when it cannot read every registry that start. Each removal is one line in sotd.log.
Switching and restarts
Switching the active session is a frontend state change: it never restarts a REPL or kernel, so each session's Julia state is where you left it, and two sessions can run different versions of the same package side by side.
The kernels and REPLs are children of the daemon, so a daemon restart restarts them. The agents survive it; Julia state does not.
Reconnecting
Every connect sends the client's session id and the last revision it saw; the daemon replays the missed events from a bounded ring, or sends a fresh snapshot if the client is too far behind. That is why a reconnect puts you back exactly where you were. Protocol details are in Design: backend and sessions.