Skip to content

Blog

Remote agent workspaces that outlive your laptop

Appaloft 1.4 turns Agent Workspace into a public Sandbox entry workflow: remote harnesses, collaboration leases, hibernation, and an evidence-gated path to ship. Here is the architecture, how it compares to OpenSandbox and peers, and what we are still finishing.

AppaloftAIAgentsSandboxArchitectureAgent Workspace

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:3000 preview 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:

  1. sandboxes.create
  2. sandboxes.agents.runtimes.create against a registered harness
  3. 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:

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?