scosh keeps one PTY on the server, uses OpenSSH for identity, and reconnects the running client to that same terminal state when the network changes. Your terminal remains the UI: its scrollback, search, selection, copy, mouse input, and terminal applications stay where they already work.
The problem with a normal SSH session
An SSH session normally owns the connection and the PTY together. If the connection disappears, the channel closes. Depending on what is running, the shell may exit, the process may receive a hangup, or the output you did not see is simply gone from the client.
tmux and screen solve this by moving the process into a multiplexer that survives outside SSH. That is the right answer when you need panes, windows, shared access, or public session ownership. It is extra machinery when all you wanted was for one remote shell to survive a network change.
One shell, two planes
scosh separates identity from transport. Each part has one job.
- OpenSSH authenticates the user. Host keys, agents, aliases, and the existing SSH configuration remain in charge. The bootstrap exchange is deliberately bounded.
- A separate data plane carries the session. The default path uses QUIC on one configured UDP port. When UDP is unavailable,
--tcpcarries the same session protocol over SSH stdio. - The server worker owns the PTY. The PTY process and the authoritative terminal state stay on the server. The client is a view and an input path, not the owner of the shell.
- The client applies state. It starts from a complete snapshot, then applies contiguous updates. If it detects a gap or a cold reconnect, it asks for a new snapshot instead of guessing.
What happens when the network changes
The important property is that a short disconnect does not create a replacement shell. The original client keeps its reattach authority in memory. When the transport is available again, it authenticates a new data connection for the same server-side session and requests the state it needs.
The recovery path is intentionally conservative:
- the server does not accept a public session ID as a takeover handle;
- stale writers are fenced instead of being allowed to race the current connection;
- a missing or non-contiguous update falls back to a complete snapshot;
- an explicit user detach ends that client instead of silently creating another owner.
There is no public session dashboard. Reattach authority stays in the client process that created the session; there are no public session IDs, list, or takeover APIs. That keeps the control surface small and avoids ownership races. Use tmux or screen when a shell needs to be shared.
Why the terminal stays native
scosh does not put a custom history screen in front of your terminal. The host terminal still receives terminal output and input, so the familiar interactions remain native:
- scrollback and the scrollbar belong to the terminal application;
- search and selection use the terminal's own commands;
- mouse, focus, bracketed paste, PageUp, and PageDown are forwarded to the PTY;
- full-screen programs can switch to the alternate screen and restore the primary screen.
The server maintains structured terminal state so it can recover accurately. That state is implementation machinery, not a second user interface.
Why QUIC is not the whole reliability story
QUIC provides an encrypted, connection-oriented transport with reliable streams and datagrams. It does not know whether a terminal effect has been applied, whether a snapshot has been rendered, or whether a client has crossed a screen-mode transition.
scosh therefore keeps a small application-level state protocol:
- revisions make updates contiguous and detectable;
- complete snapshots repair gaps and cold reconnects;
- screen changes, modes, resize, and primary scroll use the reliable path;
- the client acknowledges a reliable state effect only after it has applied and flushed it.
This is not a second byte transport. It is the minimum semantic layer needed to keep a terminal state machine from silently drifting.
Security boundaries
OpenSSH remains the identity and host-trust boundary. The data plane is separately authenticated using the bootstrap-delivered server identity and a short-lived, one-time session token. The token is not a public session handle and is not intended to be copied into another client.
There is no hosted relay, account service, or cloud session registry in the current design. The server is a Linux service that owns the PTY; the client process owns the authority to recover its session.
What scosh is not
Try it
# normal path
scosh dev@example.com
# keep the session on SSH when UDP is unavailable
scosh --tcp dev@example.com
scosh is currently v0.1.0. The production server targets Linux x86_64 with the native terminal engine; clients target macOS and Linux. See the installation page and deployment guide for the current boundary.