box/docs/box-recipe.md

86 lines
3.6 KiB
Markdown
Raw Normal View History

# 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`, `grok-box`, and `kimi-box` templates each ship a
CLI agent. The tool knows **nothing** about your project. There is no `install` step and no
refactor(templates): the tenant seeds carry rig's -box family suffix 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>
2026-07-20 00:01:29 +00:00
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:
```markdown
# 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's `README` / `CLAUDE.md`.