Roadmap
| Status date | 2026-10-28 |
| Evidence rule | Done means implemented and covered by automated tests, most of which run in-process with fakes. Validated means run against real infrastructure or live accounts; today only the opensandbox adapter with OpenSandbox’s Docker runtime is validated. |
| Detail | Tasks and acceptance criteria in backlog.md; experiments in proof-of-concepts.md |
| Runtime change | Differently’s own Firecracker node agent was removed; OpenSandbox is the default private runtime. |
Legend: ✅ done (tested in-process) · ✅ live: also run against a real backend · 🧪 implemented against published specs, fake servers only · 🟡 partial · 📋 planned · ⛔ obsolete
flowchart LR P0["Phase 0<br/>Foundations<br/>✅"] --> P1["Phase 1<br/>Private runtime<br/>🟡 OpenSandbox (Docker runtime live)"] P0 --> P2["Phase 2<br/>Hybrid placement and<br/>external providers<br/>🟡 implemented, not validated"] P1 --> P3["Phase 3<br/>Solidification<br/>📋 next: Fast Sandbox spike"] P2 --> P3 P3 --> P4["Phase 4<br/>Scale and ecosystem<br/>📋"]
Differently’s deliverables are the parts above the runtime: one vendor-neutral API, tenancy and scoped keys, quotas and fair queueing, policy-gated placement across providers, the adapter contract and plugin protocol, the tamper-evident audit chain, placement explanations and the trust report. Running sandboxes is the backends’ job.
Phase 0: Foundations
Section titled “Phase 0: Foundations”Goal. A vendor-neutral API and a control plane that enforces tenancy, quota and placement policy, runnable on a laptop.
| Item | Status | Where / notes |
|---|---|---|
/v1 API, error codes, OpenAPI 3.1 document |
✅ | pkg/api, api/openapi.yaml; TestOpenAPICoversRoutes |
| API keys, scopes, tenancy, no-escalation grants | ✅ | internal/auth; TestScopedKeyIsolation |
| Organizations, projects, quotas, fair queueing | ✅ | internal/store; store conformance suite |
| Placement policy engine (filter, rank, fail-closed external) | ✅ | internal/policy |
| Scheduler, retries, reconciler | ✅ | internal/scheduler (no package-level tests; covered by server tests) |
| Memory store | ✅ | internal/store/memory.go |
| Postgres store, migrations, advisory-lock leadership | 🟡 | Implemented; the conformance suite needs DIFFERENTLY_TEST_POSTGRES_URL and runs in the CI postgres conformance job; multi-replica failover not yet run (E5) |
| CI and release workflows | 🟡 | .github/workflows/ci.yml, release.yml; encode the branch model |
| Tamper-evident audit chain, verify endpoint, JSON-lines mirror | ✅ | internal/audit, internal/auditlog |
Dev mode with devhost pool |
✅ | differently-server --dev |
| CLI, dashboard, admin console | ✅ | cmd/differently, internal/dashboard, console/ |
| TypeScript and Python SDKs | ✅ | Tested against mock servers (sdk/*/test*) |
| Go client | 🟡 | pkg/client, used by the CLI; not yet a polished SDK (E15) |
| Prometheus metrics, structured logs | ✅ | internal/metrics |
Exit criteria. Met, except a recorded multi-replica run against Postgres (E5).
Phase 1: Private microVM backend
Section titled “Phase 1: Private microVM backend”Goal (revised by the move to OpenSandbox). A private runtime on infrastructure the
operator controls, under Differently’s policies. Originally this was
Differently’s own Firecracker node agent; it is now OpenSandbox, installed
with its own tooling and registered as a pool with trust: private.
| Item | Status | Where / notes |
|---|---|---|
opensandbox adapter |
✅ live (Docker runtime) | internal/adapters/opensandbox; fake-server tests plus TestLiveOpenSandbox against OpenSandbox server release-1.2.0 and execd v1.1.0 (arm64, Colima); a manual run through Differently (spike) |
| OpenSandbox as the default private runtime | ✅ decided | The Helm chart’s opensandbox: values render a pool named opensandbox |
| OpenSandbox Kubernetes runtime | ✅ live (single node) | Single-node k3s on Azure: e2e 14/14 with a snapshot registry (stop/start, snapshots, fork), signed port URLs and egress policy, and recorded adapter runs; multi-node and drain not run (POC 12) |
| OpenSandbox Fast Sandbox (Firecracker microVMs) | ✅ live (single node) | Single-node k3s on Azure under nested KVM: the recorded adapter scenario and Workbot’s desktop (streamed, paused and resumed with memory, idled and woken); pause takes minutes; e2e suite not run yet (E18) |
| End-to-end suite against a real OpenSandbox server | ✅ | test/e2e runs Postgres, differently-server and OpenSandbox 1.2.0 on the Docker runtime (14/14, arm64 Colima) and the Kubernetes runtime (14/14, k3s on Azure, Helm install), 2026-10-29 (results). Fast Sandbox not yet |
| Sandbox egress control | 🟡 | Per pool: egress: none or allowlist, enforced by OpenSandbox’s egress sidecar (checked live on the Kubernetes runtime); placement and per-request allow-lists not yet (E19) |
Node agent: lifecycle, capacity, heartbeat, doctor |
⛔ | Removed (internal/agent, cmd/differently-agent) |
| Firecracker API client | ⛔ | Removed (internal/firecracker) |
| Guest agent over vsock | ⛔ | Removed (internal/guest, cmd/differently-guest); the command runner moved to internal/localexec for devhost |
| Per-VM tap, /30, iptables isolation | ⛔ | Removed; isolation and egress are the runtime’s |
| Stop/start, disk snapshots, fork pinned to node | ⛔ | OpenSandbox has pause/resume and snapshots, no stop/start |
| Restart recovery (POC 2) | ⛔ | Backend outages are now POC 13 |
| Firecracker pool adapter (multi-agent placement, routing) | ⛔ | Removed (internal/adapters/firecracker) |
| Helm chart with agent DaemonSet | ⛔ | The chart now deploys the control plane only, with an egress rule to OpenSandbox on port 80 |
| Terraform for AWS | 🟡 | deploy/terraform/aws; creates EKS with a KVM node group, which only Fast Sandbox needs; not run |
| Kernel and rootfs build scripts, systemd unit | ⛔ | Removed (deploy/images, deploy/systemd) |
| Any run on real KVM (POC 1, E1) | ⛔ | The agent’s e2e suite booted real microVMs under nested virtualization on Colima before removal; KVM through OpenSandbox is E18 |
| Jailer (E4) | ⛔ | Differently no longer launches a VMM |
| Authenticated agent channel (E3) | ⛔ | No agent channel; pools hold a backend credential by reference |
| Inbound ports on Firecracker (E6) | ⛔ | OpenSandbox pools expose ports when OpenSandbox serves them without request headers |
Exit criteria (revised). The end-to-end suite passes against a real
OpenSandbox server with the Docker runtime; E18 (Fast Sandbox) and POC 12
(Kubernetes runtime) recorded. The original criteria (POC 1, 2 and 9 on
.metal) are obsolete.
Phase 2: Hybrid placement and external providers
Section titled “Phase 2: Hybrid placement and external providers”Goal. Policy-gated use of external providers next to private pools, with an operator-visible record of what left private infrastructure.
| Item | Status | Where / notes |
|---|---|---|
| Classifications, overflow, explicit external approval | ✅ | internal/policy, internal/config |
| Placement explanation per sandbox | ✅ | GET /v1/sandboxes/{id}/placement |
| Trust report | ✅ | GET /v1/admin/trust-report; per-pool declared isolation; limitations from limitations in internal/server/admin.go |
| Daytona adapter | ✅ live (container class) | internal/adapters/daytona; TestLiveDaytona and a Differently server against a live account, 2026-10-29; the VM class (pause, memory snapshots) not run; resources not sent, because Daytona refuses them with a snapshot |
| Freestyle adapter | ✅ live | internal/adapters/freestyle; TestLiveFreestyle and a Differently server against a live account, 2026-10-29, on the default snapshot |
| OpenSandbox as an external pool | ✅ | trust: external pools follow the usual approval rules; trust must be declared |
HTTP plugin protocol and remote pools |
🟡 | pkg/adapter/adapterhttp; untested since the agent tests, its only coverage, were removed (E0.34); no protocol-version check yet |
| Usage and cost estimates | ✅ | GET /v1/usage; estimates only, no invoice reconciliation |
| Live-account verification | 🟡 | POC 7, E2 |
Exit criteria (not met). POC 7 complete; Daytona and Freestyle rows in feature-parity.md moved from 🧪 to ✅.
Phase 3: Solidification (next)
Section titled “Phase 3: Solidification (next)”Goal. Make what exists trustworthy on real infrastructure, close the security gaps, and add the features users hit first.
E18 Fast Sandbox spike ran on 2026-10-29 on one node under nested KVM, through the adapter and with Workbot’s desktop; on 2026-10-29 the end-to-end suite passed on a two-node cluster (azure-vms.md). Next: node drains and more than one KVM node.
Ordered by priority. P0 items gate any production recommendation.
Exit criteria. All P0 epics done; POC 6, 7 and 10–13 run with results
published; release gates in
reliability-and-performance.md §7
automated; first release candidate tagged from pre-release.
Phase 4: Scale and ecosystem
Section titled “Phase 4: Scale and ecosystem”Goal. Grow capacity, backends and integrations once the core is proven. All planned; order to be set after Phase 3 measurements.
| Item | Notes |
|---|---|
| GPU sandboxes | Through a backend that offers them; Firecracker (and so Fast Sandbox) has no VFIO passthrough |
| InfrastructureAdapter: scale private pools from queue pressure | Design sketch in adapters/specification.md §8 |
| Warm pools and pause-to-disk density | Depends on the runtime (Fast Sandbox templates and snapshots, E18) |
| Image policy: allowed registries, signature verification | Enforced by the runtime today, if at all |
| Shared or replicated snapshot storage | Restores across OpenSandbox servers |
Sharded or SKIP LOCKED scheduling |
Only if POC 10 shows one leader is the limit |
| OIDC/SSO for humans; key lineage | Builds on E0 key-lifetime tasks |
| More adapters (flintlock, E2B runtime, Modal, Kubernetes RuntimeClass) | Through the HTTP protocol where possible |
| Multi-region and federation | Several installations with a shared policy view |
Source: docs/roadmap.md