Skip to content

Roadmap

What's shipped and what's planned, roughly in order. Each section is a coherent milestone — items inside a section are the ones that landed (or are expected to land) together. A [x] is actually working on main; a is planned. Nothing is called "done" until it ships.

For the motivation and design principles behind these choices, see VISION.md.


Shipped

v0.1 — Core runtime

The minimal usable thing: boot a sandbox, run a command inside it, get a structured result back, and fork it cheaply.

  • Firecracker orchestration in Go (boot a microVM via the Firecracker API), under the jailer (chroot + mount/PID namespaces + privilege drop)
  • HTTP API: create / list / inspect / delete sandboxes, exec, snapshot, fork
  • Snapshot + fork primitives — a fork serves guest memory lazily from the snapshot via userfaultfd (no per-fork RAM copy)
  • Clone-safety — per-fork kernel RNG reseed and machine-identifier rotation, applied before a fork is reachable
  • Default-deny networking — each sandbox in its own netns, egress limited to a DNS-proxy hostname allowlist with range-filtered resolved addresses
  • Per-request resource ceilings (vCPU, memory, fork fan-out) plus a per-sandbox lifetime and a per-exec deadline
  • Structured execution record per exec (exit code, timing, signal, timeout/OOM flags, and CPU/memory/page-fault/context-switch/IO usage)
  • Durable sandbox registry with reconcile-on-restart, and structured JSON lifecycle logs
  • Host-side cgroup quotas (cpu.max / memory.max / pids.max) sized per sandbox, on by default under jailer
  • Prometheus /metrics endpoint — sandboxes_created_total, sandboxes_active, fork_duration_seconds, snapshot_restore_duration_seconds
  • Native language rootfs profiles (base, python, node, go, versioned) — built from official language images via make profile (profiles.md)
  • CLI over the REST API — sandbox, snapshot, fork, profile ls, and a run one-shot, on a reusable typed Go client; -o json everywhere (cli.md)
  • Install script + systemd unit — install.sh drops the binary, a crucible.service unit, and a config template

v0.1.2 — MCP server + API-key auth

  • MCP server (crucible mcp serve) — a stdio Model Context Protocol server so any MCP agent (Claude Code, Cursor, …) drives crucible as native tools, with operator guardrails the agent can't widen. Built on the sdk Go package, so an MCP call and the CLI hit the identical path and can't drift (mcp.md).
  • Daemon API-key auth — bearer keys hashed at rest; once any key exists every request must present it, and binding a non-loopback address is refused without keys and TLS (SECURITY.md).

v0.1.3 — Scoped / policy tokens

  • Bind a key to a policy the daemon enforces — allowed operations, an egress ceiling, a profile allowlist, resource caps, and an expiry — so a handed-out key is worthless beyond its bounds. crucible policy validate/show, GET /whoami (policy.md).

v0.2.0 — TUI + fork lineage

  • TUI (crucible tui) — a live terminal dashboard: running sandboxes, the fork tree, and interactive streaming exec, with create/snapshot/fork/delete gated on the token's scope. A thin consumer of the sdk Go package (tui.md).
  • Fork lineage on the APIsource_snapshot_id records which snapshot a sandbox was forked from, so the fork genealogy is reconstructable by any client (this is what the tree view draws).

v0.3.x — The safe docker run for untrusted/AI code

  • OCI image bootcrucible run <image> boots an unmodified image's entrypoint in a microVM; crucible build builds a Dockerfile and loads it into the store (daemon stays Docker-free). Publish host ports with -p.
  • Interactive shellcrucible shell <id> / sandbox exec -i: a real long-lived /bin/sh over a hijacked full-duplex vsock stream (state persists; line-buffered, no PTY). The TUI gains a scrollback + tab-to-shell session view.
  • --disk per-sandbox writable sizing (resize2fs the clone, never the shared image); top-level stop/rm ops verbs; durable logs.
  • MCP for the wedgeimage/pull/publish/disk_mib on create_sandbox/run, plus logs and stop_sandbox tools (mcp.md).
  • Complete orphan reaping — startup sweeps live orphan processes and empty orphan cgroups; a killed daemon leaves no lingering firecracker.

v0.4.0 — Durable, self-healing apps (current)

  • Durable app modelcrucible app create <name> --image … promotes a workload to a named app the daemon keeps a healthy instance of. Desired state lives in a bbolt control-plane store; the ephemeral sandbox primitive is unchanged (apps.md).

  • Survives restart — the app reconciler re-creates each app's instance from spec after a daemon restart or host reboot (desired-state reconcile, the Fly/k8s model — re-created, not live-re-attached; in-VM memory is lost, cost is one cold boot).

  • Self-heal — daemon-side restart-on-failure with exponential backoff + a crash-loop guard, plus http/tcp health checks (declarative always/on-failure/never policy).

  • Full surfacecrucible app ls|get|rm|logs|exec|shell, REST /apps, the Go SDK (CreateApp/ListApps/GetApp/DeleteApp + an App handle), and four MCP tools (create_app/list_apps/get_app/delete_app, → 19 tools).

  • crucible fork -p HOST:GUEST — publish a host port on a fork (a running server, forked and exposed on its own port).

  • Durability contract: an app survives a daemon restart (re-created from desired state); a bare sandbox does not (it stays the throwaway primitive). Live-VM re-attach (avoiding the cold boot) is later trajectory work.

Planned

v0.3.x — Copy files into/out of a sandbox (crucible cp) (next)

The most-requested gap in the agentic iteration loop: get your files in and run them, with no image build and no Dockerfile. A small follow-up to v0.3.0, independent of the v0.4 work.

  • crucible cp <local> <sbx>:<path> — copy a file or directory into a running sandbox (tar over vsock; the safe-copy model, not a host bind-mount, so the guest gets files it can't use to reach back). Turns any sandbox into a scratch workspace: run python:3.12cp ./script.py <sbx>:/app/exec/shell. Pairs with snapshot + fork — cp a project in once, then fork N variations that all inherit it.
  • crucible cp <sbx>:<path> <local> — copy artifacts back out. The security-sensitive direction: the tar comes from untrusted guest code, so host-side extraction is tar-slip-safe and size-bounded (adversarial-input handling).
  • MCP write_files / read_file — the "drop code in and run it" primitive for agents, alongside exec.

v0.4.1 — Reach an app by name

The durable app object exists (v0.4.0); v0.4.1 makes it addressable by a stable name rather than an ephemeral instance id.

  • Name → instance routing + ingress proxy. A host-header/SNI proxy that keys on app identity, so a stable name (later a hostname) is how you address a workload.
  • Inbound isolation policy on the app's published surface.
  • PTY / full terminal. The interactive shell is line-buffered today; a real PTY adds full-screen programs, colors, and Ctrl-C job control.

v0.4.2 — Production polish

  • Private / authenticated registry pull — credentialed pulls from private registries (ghcr.io, ECR, …).
  • Pause / freeze-for-forensics. crucible pause <id> freezes a suspicious workload and snapshots it for analysis before you kill it — Firecracker pause + snapshot already exist under the hood; this surfaces them as a security-ops action.
  • Growable live disk + accounting. --disk sizes the writable rootfs at create today; this adds growing a live sandbox's disk and per-sandbox disk accounting.

v0.4.x — Hardening & ecosystem

  • More language profiles — Rust, Java, Ruby, Swift, C/C++, bash-only, minimal-alpine.
  • policy.yaml. A single versionable artifact that supersets scoped tokens — quotas, syscall rules, network allowlists, and mount policies.
  • Per-language seccomp policies. Hand-tuned syscall allowlists per runtime; generic policies are too loose.
  • DNS-layer allowlist filtering and packet capture on demand (crucible sandbox tcpdump … → a pcap of everything the sandbox did on the network).

v0.5 — Observability and debugging

Turn the per-exec records into first-class, exportable telemetry.

  • OpenTelemetry export. Every lifecycle event, exec, and snapshot as OTel spans with stable semantic conventions; OTLP to Jaeger / Tempo / Datadog / Honeycomb / Grafana.
  • Prometheus histograms. Proper latency histograms on the /metrics endpoint, plus reference Grafana dashboards as code.
  • Syscall tracing. Optional per-sandbox syscall log via ptrace or eBPF — expensive to enable, valuable when you need to know exactly what an agent's code did.
  • Filesystem diff. crucible fs diff sbx_… shows every file created, modified, or deleted vs. the starting rootfs.
  • Record and replay. Capture a full execution trace (stdin/stdout, env, filesystem writes, network bytes) and replay it deterministically in a new sandbox.

v0.6 — Fork trees

Make parallel agent exploration a first-class workflow, not just a primitive. Fork lineage (v0.2.0) and the TUI tree view are the groundwork.

  • Fork tree API. Explicit parent/child relationships between snapshots, with depth limits and branch pruning.
  • Scoring hooks. Attach a scoring function to a fork tree; crucible prunes the lowest-scoring branches and keeps exploring the best. Beam search for code.
  • Shared memory reads. Children forked from the same snapshot read shared pages without duplication, cutting memory cost per fork.

Longer term

Directions that matter once the core is solid. Not committed to a version or order yet.

  • Persistent workspaces & richer interactive sessions. Bidirectional stdin ships (crucible shell / exec -i) and a full PTY is v0.4.1; what's left is longer-lived named workspaces an agent reattaches to, and first-class REPL / language-server ergonomics on top of the shell.
  • First-party agent integrations. Native hooks and ready-made examples for Claude Code, Cursor, and common agent frameworks, building on the MCP server, plus a typed SDK (Python/TS) so the fork/snapshot workflow isn't hand-rolled over HTTP.
  • Snapshot sharing. A registry for warm setup-snapshots — boot a "Django project, dependencies installed" snapshot and run against it instantly.
  • Published regression benchmarks. The harness ships (make bench, benchmarks.md); tracking cold-start / fork-latency / throughput numbers over releases in CI is the remainder.
  • Stable API + external security audit. A versioned API with a deprecation policy and a published third-party audit — the bar for v1.0.
  • WASM profiles. WebAssembly sandboxes alongside VM sandboxes, for workloads where full-VM isolation is overkill.
Was this page helpful?