rig is growing a second family of roles, and once a 'staging' role can mean either a fleet machine or a box tenant, the bare name stops naming anything. rig's answer is a suffix on the role (heavy-duty/rig#76): '-server' for fleet machines, '-box' for box tenants. box's answer is that a template keeps being named for the role it converges, so the tenant templates move with it: claude -> claude-box codex -> codex-box grok -> grok-box staging -> staging-box Templates are the only surface that spells a rig role out loud (BOX_BOOTSTRAP_ROLE, auto-run at mint since #81), so a directory that says one thing and a role key that says another is a trap with a 15-minute fuse: it mints clean and dies at convergence. Renamed with 'git mv' so the history of each seed follows it. 'blank' keeps its name. It seeds no tenant role and sets no BOX_BOOTSTRAP_ROLE, so it has nothing to agree with — renaming it would only churn the default template's name for symmetry's sake. Two namespaces move apart here and only one of them moved: the template name and the role are now claude-box, while the seed USER stays 'claude' — that is the user rig's role converges and the one 'box shell' lands in. test/cli.sh pins the pair per tenant rather than each half alone, because a later rename that moves one and forgets the other mints a box whose role dies looking for a user nobody created. drill.sh keeps its bare box NAMES ('codex', 'grok' — what the pre-flight banner announces and what teardown deletes) and only moves the --template it passes. The mint-time hints in cmd_new match both spellings of user.box.template, and that is not an alias for the role: 'rig bootstrap claude' is gone and nothing here softens the cut. The stamp is a fact about an INSTANCE, written at its own mint time and carried forward by every clone; refusing the old spelling would cut nothing over and only drop the login hint on boxes that predate today — the same reason user.claudebox is honored everywhere else. migrate-host.sh stamps re-homed legacy boxes claude-box, the name the template has today, so a re-homed box looks like a fresh mint rather than a fossil. Ordered AFTER rig's rename, and that is not a preference. The seeds install rig from RIG_REPO/RIG_REF, defaulting to heavy-duty/rig@main and unpinned until rig#32's releases, so these templates ask whatever main happens to be for 'rig bootstrap claude-box'. Against a pre-rename rig that role does not exist and cmd_new refuses to call the box ready. Merged in the other order the window closes instead of opening: rig's cut is hard, with no aliases, so the day it lands every unmerged box seed naming a bare role is the broken one. Closes #123 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3.5 KiB
The .box/ convention
box mints trust-less, creds-free, isolated VMs with a coding agent already
installed (box new/shell/snapshot/restore/exec/down/start/rm/status) — the
claude-box, codex-box, and grok-box templates each ship a CLI agent. The
tool knows nothing about your project. There is no install step and no
host-run setup script.
A project makes itself easy to stand up inside a box by shipping an optional
.box/ folder. This folder is agent-facing documentation — read and
acted on by the box's coding agent (the reasoning agent) running inside the
box, whichever template you minted. It is not shell that the host executes.
The folder was named
.claudebox/before the 0.5.0 rename. Repos that still ship.claudebox/keep working — the agent is told to read either — but new projects should use.box/.
What it is / what it is not
- Optional. No
.box/is a perfectly valid state. - Agent-facing. You are writing instructions to a reasoning agent, not a machine. Prose is fine; the agent adapts.
- Not a host contract. The host never parses, sources, or runs anything in here. There is no enforced schema and no required filenames.
- Old model: a host-executed
.devbox/setup.sh. New model: a runbook the agent reads and decides how to act on.
How it's consumed
Every coding-agent box ships a global agent-context file — ~/.claude/CLAUDE.md
for claude, ~/.codex/AGENTS.md for codex, ~/.grok/AGENTS.md for grok —
telling the agent it is inside a box and to treat a repo's .box/ folder as its
bootstrap runbook. So the whole flow is (shown with claude; the other agents
follow the same shape):
box new # get a box
box shell # get in
git clone <repo> && cd <repo>
claude # the agent reads .box/ and brings the project up
The operator can also just say: "set this project up per .box".
Suggested contents (all optional)
Author everything here for a reasoning agent.
.box/SETUP.md— the prose runbook. Prerequisites, how to install deps, how to start services, how to template the env, how to seed data, and how to smoke-test. Written as instructions to the agent.- Helper scripts (e.g.
.box/dev-up.sh) that the runbook tells the agent to run. The agent decides to run them; the host never does. .box/env.template— example env the runbook explains how to fill. Staging values the operator pastes in. Never commit real secrets..box/compose.yml— optional services the runbook starts.
Worked example
A minimal .box/SETUP.md for a Node + Postgres app:
# Setup
This is a Node service backed by Postgres.
1. Install deps: `npm ci`
2. Start Postgres: `docker compose -f .box/compose.yml up -d`
3. Create the env file: copy `.box/env.template` to `.env` and ask the
operator to fill in `DATABASE_URL` and `API_KEY` (staging values).
4. Run migrations: `npm run migrate`
5. Start the app: `npm run dev`
6. Smoke-test: `curl -sf localhost:3000/health` should return `{"ok":true}`.
That's it — the agent reads it top to bottom and adapts if reality differs.
Guidance
- Keep it declarative and resilient. State intent and steps; let the agent adapt when the repo has drifted. Don't hard-code brittle assumptions.
- Never put real credentials in
.box/. Templates and staging placeholders only. The operator pastes real values at runtime. - No
.box/is fine. The operator can stand the project up by hand, or let the agent infer the steps from the repo'sREADME/CLAUDE.md.