A coding agent that dies when your laptop sleeps is a demo. A workspace that reconnects, freezes evidence, and still refuses to publish itself is closer to a product.
Today we shipped Appaloft 1.4.0. The release notes list remote agent workspaces, task runs, collaboration, hibernation, portable recovery, reusable snapshots, remote terminal attach, and the first slice of a declarative Agent Adapter surface. This post is the architecture behind those bullets — what we own, what Cloud injects, where we stop, and how that shape differs from OpenSandbox, E2B, Modal, and friends.
If you already read The agent that builds your app should not publish it and How we built the delivery evidence chain, this is the layer underneath: the durable place the agent works before anything becomes shippable.
The problem we kept hitting
Local agent loops fail in boring ways:
- The human closes the lid. The agent process is gone.
- Two people want to watch the same run. Sharing a laptop session does not scale.
- The agent can show a
localhost:3000preview that nobody else can open. - When the work looks good, the same identity that wrote the files still wants to deploy them.
So we needed a remote execution surface that is more than “spin up a container and exec.” It had to reconnect, isolate tenants, expose temporary previews, survive planned compute release, and hand off to an evidence chain that an agent principal cannot walk through alone.
What an Agent Workspace is in Appaloft
An Agent Workspace is not a new Cloud aggregate. It is a public entry workflow over existing Sandbox operations:
Sandbox
+ Agent Runtime (Pi / OpenCode today)
+ reconnectable Terminal Session
+ expiring Sandbox Port exposure
+ durable Agent Task Run
+ Workspace Collaboration (lanes, writer lease, handoff)
The identity rule is deliberate: workspaceId = sandboxId. Self-hosted, Cloud, and future Enterprise distributions speak the same CLI, SDK, and operation catalog. Cloud does not invent a second Workspace table or a parallel REST family.
flowchart LR
subgraph Clients
CLI["CLI workspace *"]
SDK["SDK workspaces.*"]
Console["Console /workspaces"]
end
subgraph Public["Public Appaloft"]
WF["Workspace entry workflow"]
SBX["Sandbox<br/>workspaceId = sandboxId"]
RT["Agent Runtime<br/>Pi / OpenCode"]
TERM["Terminal Session"]
PORT["Port Preview<br/>TTL + revoke"]
TASK["Agent Task Run"]
COLL["Collaboration<br/>writer lease"]
DELIVER["Source Artifact → Preview → Promote"]
end
subgraph Cloud["Cloud overlay injects"]
AUTH["authz / quota"]
SERVER["registered Server"]
GW["gateway / attach"]
REC["recovery + snapshot policy"]
ADAPT["Adapter approval"]
end
CLI --> WF
SDK --> WF
Console --> WF
WF --> SBX
SBX --> RT
SBX --> TERM
SBX --> PORT
SBX --> TASK
COLL --> SBX
TASK --> DELIVER
Cloud -.->|"composition only"| Public
That diagram is the whole product bet. Clients call Public Appaloft. Cloud’s job is composition: registered servers, gateway attach, model access, quota, recovery mounts, snapshot policy, adapter approval. Dashed line, not ownership.
How the pieces connect
Create path, mechanically:
sandboxes.createsandboxes.agents.runtimes.createagainst a registered harness- optional terminal, preview port, task run, collaboration lane
CLI shape for humans and agents:
appaloft workspace create
appaloft workspace connect
appaloft workspace terminal
appaloft workspace preview
appaloft workspace task run
appaloft workspace pause
appaloft workspace resume
Canonical ops still live under sandboxes / terminals / ports / collaborations. The workspace commands are a workflow façade, not a second domain language.
Collaboration is also public and explicit. Each human or agent gets its own Sandbox identity. A lane can have observers reading a real PTY stream, but writes go through a renewing writer lease with generation fencing. We are not stuffing a team into one shared checkout and hoping tmux etiquette holds.
Hibernation, drain, and snapshots
1.4 makes the lifecycle durable enough to leave your laptop:
| Mechanism | What it keeps | What it does not claim |
|---|---|---|
process-frozen pause |
Processes + filesystem | Useful mainly for short holds |
compute-released hibernation |
/workspace and documented persistent paths; releases CPU/memory |
Arbitrary PTY memory, unfinished model streams |
| Portable drain | Same SandboxId onto another server in a shared recovery family |
Bytes never written to the recovery store |
| Reusable Snapshot | One-to-many restore under a lifecycle policy | Shared-mount HA SLAs we do not operate for you |
Resume re-signs capabilities. Old terminal attach tokens and preview URLs die on purpose. That is annoying once and correct forever.
We already ran a dual registered-server acceptance on 2026-07-26 (Yundu → Hostinger planned drain, same-identity continuity, snapshot restore, exact cleanup). That is enough to publish the architecture. It is not enough to invent RPO numbers. Where the docs refuse a promise, this post refuses it too.
Where work becomes shippable
Workspace is mutable. Shipping is not. The handoff is the same evidence chain we already wrote about:
flowchart LR
W["1. Workspace<br/>mutable FS + agent run"] --> F["2. Freeze<br/>Source Artifact digest"]
F --> P["3. Candidate Preview<br/>expiring URL + digest"]
P --> G["4. Promote / deliver<br/>external actor only"]
subgraph AgentReachable["Agent-reachable"]
W
F
P
end
subgraph HumanGate["Human / delegated gate"]
G
end
Sandbox-scoped principals prepare. They do not accept promotion. If that boundary feels strict, good — see the earlier posts on agent publish boundaries and the evidence chain.
How this compares to OpenSandbox and peers
The market uses “sandbox” for several different products. A fair comparison needs axes, not vibes. Sources below are public docs and repos as of 2026-07-27; we did not re-benchmark cold starts.
| Axis | Appaloft Agent Workspace | OpenSandbox | E2B | Modal Sandboxes |
|---|---|---|---|---|
| Primary job | Durable coding workspace + delivery control plane | General sandbox platform (exec, agents, eval, RL) | Isolated Linux for agents (cloud) | Secure containers for untrusted code |
| Identity model | workspaceId = sandboxId workflow over public ops |
Sandbox lifecycle API + execd | Sandbox objects with pause/snapshot | Sandbox objects in Modal |
| Isolation (documented) | Provider/template policy; gVisor-backed execution path in our stack | Docker/runc default; optional gVisor / Kata / Firecracker |
Firecracker microVM | gVisor |
| Agent coupling | Harness adapters (Pi, OpenCode; declarative Adapter next) | Harness-agnostic SDK / MCP examples | Harness-agnostic SDKs | Harness-agnostic |
| Self-host | Public control plane + your servers | First-class Docker / Kubernetes | Cloud + BYOC | Modal-hosted |
| Preview | Expiring sandbox port exposure + candidate preview for artifacts | Port endpoints / proxy | Sandbox domain / envd | Connect tokens / tunnels |
| Ship path | Freeze → candidate preview → external promote / deliver | Out of scope as a deploy control plane | Out of scope | Out of scope |
A few contrasts that matter for architecture reviews:
1. Lifecycle owner. OpenSandbox and E2B own a sandbox object with TTL, pause, and snapshot APIs. Appaloft owns a Sandbox too — then layers workspace, task, collaboration, and promotion workflows on the same identity. If you only need “run this untrusted command,” a pure sandbox API is thinner and fine. If you need “reconnect tomorrow and still refuse to self-publish,” you need the workflow layer.
2. Default isolation vs configurable isolation. E2B and Modal document a strong default (Firecracker / gVisor). OpenSandbox keeps the API neutral and lets operators pick secure_runtime. Appaloft is closer to the latter: isolation is a provider/template property, not a marketing noun on the Workspace type. Do not read “workspace” as “we invented a new microVM.”
3. Credential story. OpenSandbox’s Credential Vault and similar egress-injection designs keep real secrets out of the guest. We care about the same failure mode, but our current hard line for shipping is different: secrets must not enter an immutable Source Artifact, and promotion is not available to sandbox principals. Guest-secret injection and artifact-secret scanning solve adjacent problems; both belong in the threat model.
4. Product layer. Cloudflare’s Sandbox SDK (Linux containers + preview URLs) and Dynamic Workers (V8 isolates) are easy to conflate. Only the former is in the same conversation as a coding workspace. DevPod and Codespaces sit on the human IDE axis. OpenHands’ sandbox is agent-bundled. Comparing feature matrices across those layers produces nonsense.
5. Open source path. OpenSandbox is Apache-2.0 and self-host oriented. E2B publishes open SDKs with a separate BYOC story. Daytona’s public repo stopped maintenance in June 2026 as core moved private — treat “open self-host” claims carefully when you read older READMEs. Appaloft’s public core remains the Workspace source of truth; Cloud is an overlay.
We are not claiming to be the only pauseable sandbox, the only gVisor option, or the only MCP-friendly exec API. Those exist. Our claim is narrower: a remote agent workspace that stays on the same operation language as deployment evidence.
Architecture that is correct before every exit gate is green
Some 1.4 surfaces are closed. Some are not. The unfinished ones still have a direction we intend to keep.
Done enough to describe without hedging the shape
- Remote Workspace entry for Pi and OpenCode
- Task Run process manager (
taskRunId = runId) - Collaboration writer lease / observer / handoff
- Compute-released hibernation, capability re-sign, planned drain, reusable snapshots (dual-server acceptance recorded)
Directionally committed, still finishing exit gates
- Hosted go-live for real GitHub PR write against a test-owned repository (idempotent retry + exact cleanup). The Task Run architecture is in; that acceptance is not closed.
- Open Adapter / Workspace Profile platform: declarative manifests, tenant install approval, profile pinning, credential grants. The contract is public (
appaloft.agent-adapter/v1,appaloft.agent-workspace-profile/v1). A full Codex-on-registered-server smoke and any marketplace story are later chapters, not today’s claim.
flowchart TD A["Declarative Adapter / Profile"] --> B["Harness resolution<br/>no tenant control-plane code upload"] B --> C["Pinned Workspace instance<br/>digest + installation id"] C --> D["Same Sandbox / Task / Collaboration / Promote ops"]
That sketch is intentional incomplete product, not vapor. Cloud will approve and audit installations. It will not execute tenant-uploaded control-plane packages. If we ever blur that line, this post becomes the thing we were wrong about.
Tradeoffs we are living with
- Same identity for workspace and sandbox simplifies ops and cleanup. It also means every Workspace feature must respect Sandbox expiry, network policy, and provider limits — there is no escape hatch aggregate.
- Harness adapters instead of one blessed agent keeps the control plane honest. It costs conformance work for every new runtime.
- Filesystem-first hibernation is operable. Promising full TUI memory resurrection is not.
- Evidence before publish slows demos. It is the only reason we are willing to put agents near delivery.
Try the surface
Public docs and CLI:
- Agent workspaces (path may track docs nav; use the Appaloft docs agent section if the slug moves)
- Release: v1.4.0
- Related reading: AI-native control plane, Skills and MCP, CLI auth handoff
If you are building a competing or complementary sandbox, the feedback we want is specific: does workspaceId = sandboxId help or hurt your mental model? Where would you put secrets — guest vault, host inject, or artifact gate? And which harness should Adapter profiles support next once the Codex acceptance path is green?