Core Concepts

How upstream works -- sandboxes, templates, persistence, encryption, and the turn executor.

Sandboxes

A sandbox is an ephemeral Firecracker microVM. Each sandbox gets its own kernel, filesystem, and network namespace. There is no container escape vector -- Firecracker VMs are hardware-isolated via KVM.

Sandboxes go through a simple lifecycle:

creating → ready → running → stopped
                         
                      failed
  • creating -- VM is booting from the template snapshot.
  • ready -- Guest agent is connected via vsock. Commands can be executed.
  • running -- A command is currently executing.
  • stopped -- Sandbox was explicitly destroyed or timed out.
  • failed -- VM failed to boot or the guest agent did not connect.

Sandboxes are provisioned in under a second from cached template snapshots. When destroyed, all state is discarded -- the underlying rootfs is immutable.

Templates

Templates are pre-built ext4 rootfs images. They define what's installed in a sandbox before any user code runs: language runtimes, system packages, tools, environment variables.

upstream ships three built-in templates (claude-code, python, nodejs) and supports custom templates built from a declarative spec. See Templates for details.

Templates are content-addressable. Two identical specs produce the same hash, so you never rebuild an image that already exists in the cache.

Context persistence

The key difference between upstream and other sandbox providers: context accumulates across turns.

When you create a sandbox with a context_id, the platform tracks session state. Artifacts from one turn are available in the next.

# Turn 1: install dependencies and run analysis
with client.sandbox(image="python") as sb:
    sb.exec(["pip", "install", "pandas"])
    sb.exec(["python", "analyze.py"])
    # results written to /workspace/output/

# Turn 2: picks up where Turn 1 left off
with client.sandbox(image="python") as sb:
    # /workspace/output/ from Turn 1 is available
    sb.exec(["python", "report.py"])

This is implemented via a CoW (copy-on-write) overlay on the rootfs. The base template is immutable; each session's writes are captured in a separate diff layer that can be snapshotted and restored.

E2E encryption

Every sandbox session supports end-to-end encryption. When creating a sandbox, the client sends an X25519 public key. The server responds with its own public key. All subsequent data is encrypted with a shared secret derived from the Diffie-Hellman exchange.

# The client_public_key field in CreateSandbox
{
  "template": "claude-code",
  "client_public_key": "base64-encoded-x25519-public-key"
}

The platform never holds the plaintext of your agent's interactions. Even in a hosted deployment, the server cannot read the data flowing between your client and the VM.

Turn executor

The turn executor is upstream's original product -- a markdown-native CI pipeline runner.

You write a markdown document with YAML frontmatter and fenced bash code blocks. Each block is a step. Steps execute sequentially in an isolated container. Results are written back into the markdown.

---
image: python:3.12
---

# Data pipeline

```bash
pip install pandas
python transform.py
```

```bash
python validate.py
```

The pipeline format is the documentation format. After execution, step results are appended to each code block, so the markdown file becomes both the pipeline definition and the execution report.

Context accumulation

Across turns, the executor preserves artifacts. Turn 1's output directory feeds into Turn 2. This is what makes upstream suitable for long-running agent workflows -- a 14-hour research pipeline, a week-long code migration, or a multi-agent system where each agent builds on previous results.

Architecture

The platform has four layers:

LayerComponentWhat it does
APIsandcastle-apiConnectRPC gateway. JWT verification via Cloudflare Worker.
Controlsandcastle-controllerVM lifecycle, template cache, warm pool management.
Hostsandcastle-shimcontainerd shim that manages Firecracker processes.
Guestsandcastle-guest-agentvsock agent inside the VM. Handles exec, file ops, streaming.

All components are written in Rust. The guest agent is compiled as a static musl binary for minimal footprint inside the VM.