ant
You know what arizuko is for; now meet the thing you actually talk to. An ant is one Claude Code process running inside a Docker container. There is one ant per group, and the group’s folder on disk IS the ant. Its diary, skills, and PERSONA.md are all files in that folder. Keep that picture in your head: every concept after this one is really about a file in that folder, or a rule about who may touch it.
the folder is the agent
Every group lives at /srv/data/arizuko_<instance>/groups/<folder>/ on the host. When a message arrives, runed spawns a container and mounts that folder at /home/node/ inside. Whatever’s in the folder is what the agent sees:
groups/solo/inbox/
PERSONA.md persona — name, tone, voice
CLAUDE.md runbook the agent reads each turn
skills/ SKILL.md files the agent can call
diary/ append-only log, survives restarts
facts/ durable knowledge
secrets/ folder-scoped credentials (env injection planned — spec 6/Y)
.claude/ Claude Code session state
Copy the folder, you copy the ant. Delete the folder, the ant is gone. There is no separate database row holding the persona.
one container per turn
The container is short-lived. runed starts it when a message arrives, the agent reads the prompt, replies, and the container exits. Nothing important lives inside the container — only inside the mounted folder. The next turn gets a fresh container with the same folder.
tier is path depth
A deeper folder gets fewer default permissions. The tier is just the slash count in the path, capped at 3: main is tier 0, solo/inbox is tier 1, corp/eng/sre/oncall is tier 3. grants.DeriveRules reads the folder path and that tier to decide which MCP tools the ant can call. A tier-1 ant in a public-facing room gets send, send_file, reply; a tier-0 root ant gets everything. Same agent shape at every depth — only the defaults shrink.
how the agent talks back
The agent calls MCP tools (like send or find_messages) over a unix socket. routd hosts one socket per group in-process at ipc/<folder>/gated.sock on the host; runed mounts it into the container at /run/ipc/gated.sock. Inside the container, Claude Code is wired up to that path via its mcpServers config. Every tool call is a JSON-RPC message over that socket, and routd runs the same grant check on it that it runs when a human calls the matching REST endpoint — one gate, agent or operator.
the migration trick
When arizuko ships a new version of the built-in skills, you don’t want every group’s folder to fall behind. routd reads ant/skills/self/MIGRATION_VERSION from the agent image, compares it to <group>/.claude/skills/self/MIGRATION_VERSION, and if the group is older it injects a /migrate prompt on next spawn. The agent runs /migrate, which copies the upstream skills into its own folder. Old groups catch up at their own pace; nothing is force-pushed.
what stays, what goes
- Stays — everything under
groups/<folder>/: diary, facts, skills, the JSONL session transcripts in.claude/. - Goes — the container itself, anything written to
/tmpinside, any process state held in RAM.
This is why “just edit the folder” works. Change PERSONA.md on the host (or via WebDAV) and the next spawn picks up the new persona — no restart, no reload.
arizuko vs standalone ant
Today: every arizuko group is an ant folder. arizuko chat <instance> [group] drops you into one for interactive use. runed spawns containers from the same folders for inbound chat messages.
Planned: a standalone ant <folder> CLI that runs one agent without arizuko anywhere on the system — no gateway, no scheduler, no router. Spec at specs/12/b-ant-standalone.md.
go deeper
- specs/12/b-ant-standalone.md — standalone CLI, container runtime, skill curation.
- route tokens — how to reach an ant from a browser or webhook.
- grants — how tier turns into per-tool permissions.
- jid — the addresses the agent uses to send messages back out.