The tenant content that lived in claude/codex/grok's cloud-init — agent CLI
installs, docker, node, the per-template agent-context heredocs — moves to
rig's bootstrap roles (rig#31), where it is convergent, idempotent and
testable end to end. What remains per template is a thin seed: the tenant
user, tmux (#65), and rig preinstalled — nothing that joins a tailnet or
admits credentials.
- BOX_BOOTSTRAP_ROLE: a template names the creds-free rig role cmd_new
auto-runs inside the guest after cloud-init settles. The value is a role
NAME by allowlist — anything shell-shaped dies at parse time, on the
host. A failed role leaves the box up and names the re-run.
- render_userdata: the seed's ONE substitution. @RIG_REPO@/@RIG_REF@
resolve from the mint environment (default heavy-duty/rig @ main —
unpinned, the honest rig#29 treatment, until rig#32's releases); values
are whole-string-validated before touching the YAML, because they land
inside a runcmd shell line.
- templates/staging: the re-cut of #69's layering — user ops,
BOX_REQUIRE_VM=1, BOX_AUTOSTART=1, role staging. The tailnet workload
join holds a key and stays operator-run; cmd_new prints it as the next
step and box never sees the key.
- blank stays a box with nobody home: no rig, no role, nothing auto-runs.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two things:
1. The host scripts are first-class verbs now — 'box setup-host',
'box teardown-host [--purge-incus]', 'box migrate-host --box <n>'.
Nobody should have to run ~/.local/share/box/host/<script>.sh; that
read like an external script and exposed an install path. Each verb
execs the installed script with its flags passed through (same
pattern as 'box doctor'). README, doctor hints, and the uninstall
section point at the verbs now.
2. The repo-runbook convention is '.box/', not '.claudebox/'. Renamed
across docs and the templates' agent briefing; the briefing tells
the agent to read either, and box-recipe.md notes the rename, so
repos still shipping '.claudebox/' keep working through the
transition. (Consuming repos rename their own folder — tracked
separately.)
Also widened the help command column for the longer verb names, and
fixed one sed-casualty where a broad '.claudebox'→'.box' pass had
turned the README's legacy user.claudebox tag into user.box.
Two coding-CLI templates mirroring claude's shape: a box.env + verbatim
cloud-init, inheriting the box-net placement contract structurally, no
new design.
- codex: OpenAI Codex CLI via 'npm i -g @openai/codex' (the SCOPED
package; needs Node 22), symlinked onto the non-interactive exec PATH
via 'npm prefix -g' — the same PATH fix the claude template needed.
- grok: xAI Grok Build via the official 'curl x.ai/cli/install.sh',
run AS the grok user (the installer drops into $HOME); the binary is
found and symlinked to /usr/local/bin.
Install commands verified upstream at implementation time, per the
issue's rule (npmjs.com/package/@openai/codex, x.ai/cli). Each gets an
AGENTS.md-style context file telling the agent it lives in a
disposable, isolated, creds-free box.
Drill: templates listing now expects four; a compact per-template smoke
(mint, '<cli> --version' via box exec, remove) validates each payload
installs and lands on the exec PATH — the generic mechanic is already
proven by blank+claude and not repeated.
Closes#54