Skip to content

adrs: boxd as an agent-computer substrate - #718

Closed
MichielMAnalytics wants to merge 3 commits into
yc-software:mainfrom
MichielMAnalytics:adrs-boxd-sandbox
Closed

adrs: boxd as an agent-computer substrate#718
MichielMAnalytics wants to merge 3 commits into
yc-software:mainfrom
MichielMAnalytics:adrs-boxd-sandbox

Conversation

@MichielMAnalytics

@MichielMAnalytics MichielMAnalytics commented Aug 28, 2026

Copy link
Copy Markdown

boxd × qm

adrs/boxd-sandbox.md is Michiel's (co-founder, boxd.sh) own words, per CONTRIBUTING.md. The implementation is included in this PR as the two commits after it, so it can be merged as-is or pulled apart if you'd rather implement it your way.

What it adds

  • SANDBOX_BACKEND=boxd: a durable per-scope agent computer on boxd microVMs via @boxd-sh/sdk (gRPC). Resident disk, process sessions, backup and blob staging through the existing exec helpers. Machines are addressed by id; reads above the 4 MiB gRPC cap are chunked; stopped machines are started, suspended/hibernated ones wake on exec.
  • "sandbox": { "backend": "boxd" } as a first-class deploy-config value on docker, fly and aws: validation, check, the secrets catalog (BOXD_API_KEY), env rendering and sandbox publish all know it.
  • npm run smoke:boxd-sandbox (live), dev instance --sandbox boxd.

Verification: 27 backend unit tests against an in-process fake; CLI suite 529/529; full root suite green; typecheck/eslint/oxlint/knip clean; live smoke against production boxd; real claude-opus-5 turns through qm's orchestrator (execute/write/read on a boxd VM). Details are in the commit messages.

🤖 Generated with Claude Code

https://claude.ai/code/session_018SM8fz3TWnQCXXGEwDpHA4

MichielMAnalytics and others added 3 commits August 28, 2026 21:16
Human-written suggestion per CONTRIBUTING.md. A ready implementation
(SANDBOX_BACKEND=boxd plus first-class "sandbox": { "backend": "boxd" })
lives on MichielMAnalytics/qm@boxd-sandbox for the maintainers to pull
from if aligned.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018SM8fz3TWnQCXXGEwDpHA4
Adds a boxd (boxd.sh) sandbox backend next to sprites and smolmachines,
driven by the official @boxd-sh/sdk over gRPC. One persistent microVM per
scope, resident disk, process sessions, backup and blob staging through the
shared exec helpers.

Behaviour pinned against the production cluster:
- machines are addressed by id (name lookups 404 on get/exec/upload for both
  session tokens and API keys); the name→id map is a cache in front of
  `machines.list({org?})`, so a fresh core instance re-derives it
- exec runs `timeout N sh -c …` via the agent's `/bin/sh -c`; exit codes are
  exact, streamed output is unbounded, guest timeout reports 124
- uploads are server-side atomic (tmp + mv, parents created); reads stat
  first, then download up to 3 MiB and `dd | base64` chunks above the 4 MiB
  gRPC message cap
- suspended/hibernated machines wake on exec; stopped/failed ones get
  `start` and a poll to running (~12 s); a ConflictError naming a stopped
  machine is the only exec error retried, and only because it is raised
  before the command runs
- `restartComputer` reboots and waits; `teardown({destroy})` deletes; scratch
  boxes live under a separate name and are deleted at release

Env: BOXD_API_KEY (required), BOXD_BASE_URL, BOXD_ORG, BOXD_NAME_PREFIX,
BOXD_VCPU, BOXD_DISK_GB, BOXD_EGRESS_PROXY_URL, SANDBOX_TIMEOUT_SEC.

The three remote backends now share one options spread in wiring and one
table-driven branch in the dev-instance sandbox resolver instead of three
copies. `npm run smoke:boxd-sandbox` exercises the backend against a live
cluster.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018SM8fz3TWnQCXXGEwDpHA4
`qm.config.jsonc` now accepts `"sandbox": { "backend": "boxd" }` on every
hosting target (docker, fly, aws), alongside `local`, `sprites` and `aws`.
Until now boxd (like smolmachines) was reachable only through
`env.core.SANDBOX_BACKEND`, which the secrets catalog and the check gate
did not understand.

What "first-class" changes:
- validation: boxd is accepted everywhere and rejects the Fly layer-image
  settings (`app`, `image`, `baseImage`, `env`, `secretEnv`), the same way
  the aws substrate does, because nothing delivers them to a boxd machine
- `sandboxCoreEnv` renders `SANDBOX_BACKEND=boxd`, and the AWS renderer
  gets a boxd branch instead of falling into the Lambda MicroVM default
- `check` no longer demands `sandbox.app` on docker/fly for boxd
- the secrets catalog sees a declared `sandbox.backend` on every target
  (before, only the aws target consulted it), so `BOXD_API_KEY` is
  required exactly when boxd is declared and an explicit `sprites` now
  requires `SPRITES_TOKEN` on docker/fly too; the Fly sandbox token is
  demanded only when a Fly deployment actually runs Sprites
- `sandbox publish` refuses a boxd deployment before any docker work,
  on all three providers, with a message that says what to do instead
- derived Fly tomls drop the template's `FLY_SANDBOX_APP_NAME` /
  `FLY_BASE_IMAGE` when the stack does not provide them (registered as
  core stack keys); the checked-in acme toml is unchanged
- scaffold comments and the deploy-directory docs mention the option

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018SM8fz3TWnQCXXGEwDpHA4
@time-attack

Copy link
Copy Markdown
Collaborator

Thanks for this, @MichielMAnalytics — and sorry for the slow response.

We're closing this PR. Per CONTRIBUTING.md, since coding agents write most of the underlying code now, we'd rather receive feature ideas as a short human-written note in adrs/ — informal is great, just the idea in your own words — and bugs as a plain issue. If we're aligned we're happy to burn our own tokens on the implementation, and we'll credit you as co-author.

We don't want your idea to get lost, so we've captured it in #722 to triage on our side. Please feel free to open an adrs/ note if you feel strongly about the approach. Appreciate you engaging with the repo!

@MichielMAnalytics

Copy link
Copy Markdown
Author

thanks @time-attack, fair enough

opened the note as #859, just the adrs file in my own words. the tested implementation stays on my fork if it helps when you pick it up: main...MichielMAnalytics:qm:boxd-sandbox

happy to co-author or answer anything on the boxd side

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants