Originally published at docs.cmdop.com/blog/execution-state-continuity-06-the-boundary — part of the series The Command-Operator Execution Layer.
The Boundary: What Execution-State Continuity Is Not
When Part 1 of this series named the execution-state continuity layer, two reviewers who had read only that first article raised the same fair objection from two angles. The blunt version: isn't this just session management plus sandbox persistence plus remote execution, rebranded with a grander name? The precise version: the founding tuple — "process tree, PTY, file descriptors, sockets, kept alive across client, transport, and device" — quietly lumped together a trivial case, a genuinely hard case, and a physically impossible case, and called the bundle one thing.
Both criticisms are correct, and both are answered the same way: by drawing the boundary. A category that absorbs everything explains nothing. A primitive is defined as much by what it refuses to own as by what it claims. This article does the unglamorous, load-bearing work of saying precisely where the layer ends — what it owns, what it reaches into at real cost, and what it hands off because no layer could honestly own it.
The spine of the answer is three continuity regimes.
Three regimes hiding in one tuple
The opening scenario of Part 1 — laptop lid, dropped socket, app restart, then later a crash, then a live database connection — was deliberately compressed. Decompress it and you find three distinct problems with three distinct owners. Conflating them is exactly the over-ontologization the critique named. Separating them is the category, drawn honestly.
These are not three grades of one difficulty. They are three different problems that happen to look alike from the client's chair, and the single most important thing a serious continuity layer can do is refuse to pretend they are the same.
Regime 1 — client detaches, host lives (the core)
This is the regime the layer owns, fully and without apology. A runtime is executing on a host. The client that opened it — a terminal, a desktop app, an agent's controller — goes away: the lid closes, the socket drops in a tunnel, the app ships an auto-update and restarts, the user moves from laptop to phone. The host never noticed. The process tree is still scheduled, the PTY still has its scrollback, the dev server is still bound to its port, the file descriptors still hold their offsets and locks.
The only thing that broke is the binding between the client and the runtime — and in most systems shipping today that binding is the runtime's whole reason for existing, so when it breaks the runtime is reaped. The continuity layer's job in regime 1 is exactly to break that coupling: keep the live runtime addressable and re-attachable as an object in its own right, so a later client — the same human, a different device, a returning agent, or a second human alongside the first — attaches to the same live execution rather than a fresh one. This is the regime Parts 1 through 5 are about. It is, deliberately, the simplest of the three to state, because it is the one that is genuinely and durably solvable: nothing has to be reconstructed, because nothing died. The runtime stayed live; the layer just kept it reachable.
This is also where the "rebranding" critique has the most bite and the cleanest answer, which we owe in full further down. The components here are old — tmux decoupled a PTY from its parent shell two decades ago. What is new is not the survival trick; it is a conjunction the old components do not compose — an ownerless live execution that heterogeneous clients can attach to and steer under attributed, transferable authority, outliving the client that spawned it. Stated as a falsifiable test further down.
Regime 2 — host dies or migrates (reached into, genuinely hard)
Now the easy assumption fails: the host itself goes away. It crashes, it gets evicted from a spot instance, it is drained for maintenance, or you simply need to move the running computation to a different machine. The runtime cannot "stay live" because the thing it was living on is gone. To preserve it you must capture its volatile state and restore it elsewhere — and this is checkpoint/restore territory, with a long and honorable lineage.
The canonical citizen here is CRIU (Checkpoint/Restore in Userspace). It is worth describing fairly and concretely, because it is the discipline that makes regime 2 tractable at all. CRIU uses ptrace to seize a process, then walks the kernel's view of it: it dumps the memory pages, the CPU register set, the file-descriptor table, the open files and their offsets, pipes, and — strikingly — even live TCP socket state through the kernel's TCP_REPAIR mode, which lets a privileged process read out and later re-inject the send/receive queues and sequence numbers of a connection. It serializes all of this to an image and restores it, page for page, on another host. Pause/resume sandboxes such as E2B and Daytona reach the same goal — hibernate a running environment, process tree, loaded memory, open files, and wake it later, possibly somewhere else — but by related-but-distinct means. E2B snapshots the whole guest as a Firecracker microVM rather than checkpointing one process tree in userspace the way CRIU does; snapshotting the entire kernel-plus-userspace as one VM actually sidesteps some of CRIU's hardest constraints (external references and matching-kernel requirements). Daytona persists a workspace and container lifecycle. CRIU is the canonical per-process citizen of this regime, but it is not the only lineage that serves it.
So regime 2 is solvable for process-and-memory state. But "solvable" comes with an itemized bill, and honesty about the bill is part of the boundary:
- It is not free. Capturing and restoring gigabytes of memory pages costs time and I/O; it is a stop-the-world operation on the captured tree, not a transparent live move.
- It is environment-bound. Restore generally demands a compatible kernel and the same instruction-set architecture; you do not casually thaw an x86 image on ARM, or against a wildly different kernel.
- It has edges that resist capture. External resources the process merely references — a GPU context, a device handle, a connection whose other end lives on a different machine — are not inside the image and do not come back by magic.
Regime 2 is best read as a spectrum rather than a single feat. At its near end is persisting and recovering session identity and state across a restart — re-establishing which execution a returning client is owed, and the durable record around it — which is broadly available across the field today. At its far end is faithful live-memory freeze-and-thaw of the running process tree (the CRIU and whole-VM-snapshot work), which carries the real cost and the hard limits itemized above. A given continuity layer may legitimately sit at the near, session-state end of this axis without shipping full live-memory checkpoint/restore; reaching into regime 2 does not require reaching all the way across it. But the near end has an honest price worth naming: what survives a host death there is identity plus durable session state, not the live heap — so a host death at the session-state end costs exactly the live, populated runtime (the loaded memory, the half-built in-memory work) that the regime-1 win advertised, and recovery re-establishes the session rather than resurrecting the process that was running inside it.
The continuity layer reaches into this regime: a runtime that can survive host loss has to participate in capture/restore in some form. But the layer is not CRIU and does not claim CRIU's job. CRIU answers "how do I freeze this one process tree." The layer's concern is keeping a live execution addressable as an identity across such events. The capture mechanism is a tool the regime-2 story uses; it is not the boundary of the category. (Part 3 drew this same line between a snapshot mechanism and a continuity architecture; here it marks the edge of regime 2.)
That third bullet — external resources whose other end lives elsewhere — is the seam where regime 2 ends and regime 3 begins. And regime 3 is where overclaiming becomes lying about physics.
Regime 3 — a live external connection survives host migration (handed off)
Here is the case the Part 1 tuple smuggled in, and the one no continuity layer can honestly own. Your runtime holds an in-flight TCP connection to something you do not control — a production database, an exchange's order gateway, a message broker, a peer service. The host migrates. The question is whether that live connection survives the move.
It cannot — not by anything the layer does locally — and the reason is not engineering weakness but the architecture of the network itself. A TCP connection is not a thing your kernel owns alone. It is a shared object whose state is split across two kernels. The remote peer holds its own half: its end of the 4-tuple (source IP, source port, destination IP, destination port), its receive and send sequence numbers, its retransmission timers, its congestion-control window, its understanding of which bytes have been acknowledged. None of that lives on your host. You can use TCP_REPAIR to perfectly reconstruct your half on a new machine — and the moment a packet arrives at the peer from a new source address, or with a sequence number its own state machine does not expect, the peer's kernel does the correct thing and rejects it. You cannot reach into a remote server's socket and rewrite its half. There is no API for editing another machine's kernel, and there should not be.
So regime 3 is not a layer problem at all. It is owned by the application protocol, and the toolkit is the one distributed systems have used for decades:
- Reconnect. Open a fresh connection from the new host. The old one is gone; accept that.
- Resync by sequence number. The application — not TCP — tracks where it was (a stream offset, a cursor, a last-acknowledged message ID) and resumes from there over the new connection.
- Idempotent operations. So that a retry after an ambiguous failure is safe. The standard tool is a client-supplied idempotency key: the client stamps each logically-distinct operation with a unique token, and the server deduplicates, so "did my write land before the connection dropped?" stops being a corruption risk.
There is one honest caveat, and it proves the rule rather than breaking it. MPTCP (Multipath TCP) and QUIC can carry a connection across a change of network path or address — QUIC by identifying a connection with a connection ID rather than the 4-tuple, so it can survive an address change; MPTCP by spreading one logical connection across multiple subflows. But both work only because both endpoints speak the protocol. QUIC connection migration is a property of QUIC, present on the server too; MPTCP needs MPTCP on both ends. That is precisely the point: surviving the move is achievable as a change to the protocol on both sides, never as something a continuity layer bolts on beneath an unmodified peer. If the database speaks plain TCP, no layer can keep its connection alive across your migration, and a layer that claimed it could would be lying about physics.
Naming regime 3 as out of scope is not the category conceding defeat. It is the category being true. The honest line is: the layer keeps the live execution addressable across regimes 1 and 2; the live external connection in regime 3 it deliberately hands to the protocol that owns the other end.
Where the layer ends and the neighbors begin
The three regimes draw the boundary along the time axis — what survives which kind of disappearance. The other half of a hard boundary is the layering axis: what sits below the continuity layer, beside it, and above it. This is where the "it's just X plus Y plus Z" critique gets its direct answer, because each X, Y, and Z is a distinct neighbor with a distinct job.
The OS kernel is below the layer, and the layer does not replace it. The kernel is what actually holds the process tree, the PTY's line discipline, the descriptor table, the socket buffers. The continuity layer observes that state and keeps it addressable; it is not a new kernel and it does not reimplement scheduling, memory management, or the TCP stack. It sits above the kernel, watching it, not standing in for it. (When regime 2 needs capture, the work happens through kernel facilities like ptrace and TCP_REPAIR, not around them.)
The container runtime is also below, and it is an isolation substrate, not a continuity one. A container draws a boundary — namespaces, cgroups, a root filesystem — around a process tree. That is necessary and useful, and it is orthogonal: a container with no continuity layer still evaporates its live runtime when the client detaches, and a continuity layer can keep a runtime addressable whether or not it happens to be containerized. Isolation answers "what can this runtime see and touch." Continuity answers "does this runtime outlive the client." Different questions.
The distributed scheduler sits beside the layer, not below it. A scheduler decides placement — when and where a unit of work runs, how to bin-pack hosts, when to evict. It is excellent at deciding that a runtime should move to host B (a regime-2 trigger). It does not, by itself, hold a live interactive session that heterogeneous clients attach to and steer. Placement is not session continuity; the scheduler hands the layer a where, and the layer is responsible for the live object that lands there.
This neighbor is friendlier on paper than at fleet scale, and the boundary should say so. Because the layer keeps state resident, routine cluster elasticity turns into regime-2 work at volume, not rarely: every scale-down, every bin-packing drain, every spot reclamation is a regime-2 checkpoint trigger. The scheduler's drive to pack and the layer's drive to pin are in genuine tension — paid in checkpoint cost on every drain. "Keep the live state resident" and "keep the cluster elastic" are not free to hold simultaneously; at scale this is the layer's standing bill, not an exceptional event. Which way the trade falls has a direction worth stating plainly: residency earns its cost where reconstruction is expensive and re-attach is frequent — interactive, stateful, frequently-resumed work — while replay's scale-to-zero wins for sparse, long-idle, deterministically-rebuildable workflows; the layer is the wrong tool precisely when idle time dominates live time. (And not every eviction signal is what it appears: a network partition can masquerade as host death — see Part 7's fencing invariant for why distinguishing the two is load-bearing.)
The workflow engine also sits beside the layer, and it is a different paradigm — the whole subject of Part 3. A durable-execution engine (Temporal, Orleans, Dapr, Azure Durable Functions) reconstructs a logical workflow by deterministic replay: it never holds live OS state, it derives logical state from an event journal. The continuity layer holds the live OS state and is steered, not replayed. They compose cleanly — a workflow can orchestrate over runtimes the continuity layer keeps live — precisely because they own different things. The engine owns what should happen next, logically; the layer owns the live thing it happens inside.
The application protocol sits above, and it owns regime 3, as established. The layer hands it the one job no layer can do: re-establishing the remote half of a live connection across a move.
Five neighbors, five clean lines. The "X plus Y plus Z" critique implicitly assumed the layer is a bundle of session management, sandbox persistence, and remote execution. The boundary shows it is none of those: it sits above the kernel and container (which provide the substrate), beside the scheduler and workflow engine (which provide placement and logical replay), and below the application protocol (which owns the remote connection). It is the thing in the middle that none of the neighbors own — the live runtime as a first-class, addressable, re-attachable object.
Isn't this just CRIU plus session management, rebranded?
This deserves a straight answer, because dodging it would forfeit the credibility the whole series is trying to earn.
What is incremental, conceded plainly. The mechanisms in the boundary are not new, and this article has named them as the prior art they are. PTY-detachment from a parent process is tmux, twenty years old. Multi-client attach to a relayed terminal is tmate. Decoupling a live heap from its UI is the Jupyter kernel. Freeze-and-thaw of a live process tree, TCP state included, is CRIU. Pause/resume of a whole sandbox — whether by whole-VM snapshot (E2B's Firecracker microVMs) or workspace lifecycle (Daytona) — is the productized form these vendors ship, a sibling lineage to CRIU rather than CRIU itself. Reconnect-resync-idempotency is textbook distributed-systems hygiene. If the claim were "we invented a way to keep a process alive after a disconnect," it would be false, and the critique would be entirely right.
What is new, defended. The contribution is not a survival trick, and — this is the part the rest of the series has circled without ever pinning down — it is not the first-class-object framing either, taken as a noun. Treating the live execution as a persistent, addressable object is the enabling move, not the contribution; the contribution is what that move makes composable. State it as a test that prior art must pass or fail:
The falsifiable claim. No composition of the named prior art produces a single live execution that is simultaneously (a) ownerless — no privileged participant or occupant, the spawner included, whose departure ends it, and no out-of-band control-plane owner (a host-process/console/root holder who is not a session participant but can unilaterally end it — the seat where authoritative game servers, notebook hubs, and collaborative IDEs all hide their privilege); (b) attach-able by heterogeneous client modalities it did not spawn — a CLI, a phone, a foreign-vendor agent, a service, joining the same live execution; and (c) mutable under per-actor attributed, transferable authority — each act traceable to an actor, and that authority grantable and revocable between actors. (a) is a property of the continuity identity — that no client or participant owns the session — and not a denial that a substrate host exists below the layer: that host can die (regime 2), and the series concedes the live graph may then be lost; ownerless means no participant is privileged, not that no substrate exists. Whence the corollary (d): because the spawner is just one participant, (a) entails that the execution outlives the very client that created it — (d) is the spawner-instance of (a), not an independent fourth test. Exhibit any prior system that holds (a)–(c) at once, and the category claim is falsified.
The point of stating it this sharply is that the bricks decompose against it cleanly, and none of them — alone or assembled — clears the three core conjuncts (and so none earns the corollary d either):
-
tmux/tmate/sshxgive an ownerless-ish, relayed terminal with multi-attach (a, partially d), but the attached thing is a terminal, not a cross-modality execution object, and there is no per-actor attributed, transferable authority — every attached client is the same undifferentiated viewer. The web-relay generation (tmate, andsshxfrom 2023 on) only re-ships the same model: the PTY still lives on the host that ran the client binary, so it is not truly ownerless (a) and does not survive that host (d) — the relay holds no execution. Fails (b) and (c). - CRIU gives cross-host live capture and restore (the strongest answer to d), but it is single-restorer: it thaws one tree for one process to resume, with no live concurrent multi-attach and no notion of multiple authorized actors. Fails (b) and (c).
-
Kubernetes Pod +
kubectl exec+ RBAC is the candidate a sharp infra reader reaches for first: a long-lived Pod is ownerless and outlives any client (a, d), and RBAC looks like attributed, transferable authority. Butkubectl execis stateless — each attach spawns a separate PTY/process, so there is no single shared live execution for heterogeneous actors to jointly steer under transferable authority; obtaining that means running a multiplexer (tmux) inside the pod, which reduces to the tmux case. Fails (b) and (c). - Live Share (and its kin) give heterogeneous, live, multi-actor steering of one shared thing (b, c partially) — but always under a privileged host-owner whose exit ends the session. The session is owned. Fails (a), and with it (d).
- OpenAI's publicly-described multi-agent shared-workspace system is the closest public approach to (b) and (c): humans and AI agents co-participate as peers in one workspace, posting into it the same way, which is genuine heterogeneous multi-actor co-membership. But the shared object is a ledger of commands — an append-only, operational-transform command log that is the workspace, reconstructed by replaying the posted commands — not a single canonical live OS execution object (process tree / PTY / fds / sockets). Recording intents-to-apply in a log is the document/OT/replay family, not a live execution being mutated in place; it fails the "one live execution" requirement. And because a coordinator agent brokers the actors under a "yield or act" turn discipline, the workspace has a privileged orchestrator rather than ownerless peers. Fails the one-live-execution reading of the conjunction, and fails (a).
Compose them and the gaps don't cancel: you can relay a terminal or checkpoint a tree or run a Pod or host a guest-laden session, but no assembly yields an execution that is ownerless and cross-modality-attachable and mutable under attributed, transferable authority — and so (because ownerless already entails it) outlives its spawning client — all at once. That absent conjunction is the category. It is a verb — what the live execution can withstand and admit — not the noun "first-class object," which is merely the framing that lets the conjunction exist at all. (How an implementation actually maintains that conjunction is a separate question; this series stays at the boundary — what the category must satisfy — not the mechanism.)
That is the honest ledger. Every brick is old, and conceded as old; the novelty is not any brick but their un-composable conjunction — ownerless, heterogeneous-attach, attributed-transferable-authority, survives-the-spawning-client — which prior art does not assemble and which long-horizon, multi-actor agentic work demands. The bricks are off the shelf; the conjunction is the category. Conceding the bricks is what makes the claim about the conjunction believable.
Why a boundary strengthens a category
It is tempting, when defending a new category, to make it absorb everything adjacent — to answer "what about host death?" and "what about the live database socket?" with "yes, that too." That instinct is exactly what produces vaporware. A primitive that claims regime 3 — a live remote connection surviving an unmodified peer's migration — has made a claim physics will falsify the first time someone tests it, and one falsified claim taints the true ones.
The opposite move is the strong one. By owning regime 1 outright, reaching into regime 2 with an honest bill of costs, and explicitly handing regime 3 to the application protocol, the layer becomes something you can actually build, ship, and reason about. The boundary is not a hedge; it is the precondition for the category being real. "Twelve-factor app," "serverless," and "the actor model" became durable categories because each said clearly what it was not. Execution-state continuity earns the same standing the same way.
So the boundary, stated once, cleanly: the execution-state continuity layer owns client-detach-with-live-host outright, reaches into host-death-and-migration through the checkpoint/restore lineage at real and bounded cost, and hands the survival of a live external connection to the application protocol that owns the other end — and it says so out loud.
cmdop (cmdop.com) is offered as one reference implementation that draws exactly this boundary: it owns regime 1, reaches into regime 2, and hands regime 3 to the application protocol — and states that boundary plainly rather than papering over it. That candor is not a limitation of the design; in a field crowded with systems that quietly overclaim, it is the point. A continuity layer worth trusting is one that tells you, precisely, where it ends.
Next in the series — Part 7 of 7: "Failure Modes of a Continuity Layer." Each disconnect, death, migration, fork, and half-applied write formalized as a failure mode, with what the layer guarantees and what it hands to the application in each.
Previous — Part 5 of 7: The Session as a Computational Primitive
Next — Part 7 of 7: Failure Modes of a Continuity Layer



Top comments (0)