Local development
host has the least setup and does not inject vault env. It cannot provide an isolated
conversation office, so it also needs an explicit trusted door policy.
Compare mikan's supported host, container, image, microVM, Firecracker, and Cloudflare sandbox modes.
Local development
host has the least setup and does not inject vault env. It cannot provide an isolated
conversation office, so it also needs an explicit trusted door policy.
Mainline isolation
image:<image> lets mikan manage lifecycle, workspace mounts, vault env, and resource limits.
Gondolin preview
gondolin:default runs a local Gondolin/QEMU microVM in mikan’s own process and is the planned
successor to managed image:* sandboxes.
| Mode | Execution location | Vault env injection | Vault key | Notes |
|---|---|---|---|---|
host | host machine | not injected | derived from the platform user | Local development only; needs an explicit trusted door policy |
container:<name> | existing Docker container | injected | derived from the container name | one container one vault; multiple people sharing one container also share its vault |
image:<image> | Docker managed by mikan | injected | the office key | Current recommended isolation mode; 1 conversation = 1 vault = 1 container |
gondolin:default | local Gondolin/QEMU VM | injected | the office key | Preview; single-host, in mikan’s own process; requires Node.js >=23.6 and QEMU |
firecracker:<vm-id>:<host-path>[:<ssh-user>[:<ssh-port>]] | Firecracker VM | injected | the office key | Very early alpha; you must start the VM and mount workspace at /workspace; not recommended yet |
cloudflare:<sandbox-id> | Cloudflare Worker | injected | the office key | Under construction; requires your own @cloudflare/sandbox bridge; host workspace is not synced |
The office key is the versioned v1-<platform>-<readable-id>-<hash> segment that also names the
conversation’s directory under the workspace. See Conversation offices.
Each conversation owns one directory under the workspace root — its office — named by office key
rather than by the platform’s raw conversation id. Sandbox mounts follow that directory, so inside
a runtime the office is at /workspace/<office-key>.
Which parts of the workspace a runtime sees is the door policy, a sandbox.workspace setting
the admin portal can set globally or per conversation (the /pi-sandbox door chat command does the
same for one conversation, but only under image:* and gondolin:*):
| Door policy / layout | Mounted under /workspace |
|---|---|
isolated (default) | only <office-key>/ |
trusted / shared-support | <office-key>/ plus the shared MEMORY.md, skills/, and events/ |
trusted / full | the entire workspace root |
Only image:* and gondolin:default can enforce the isolated projection. The other modes report
managedProjection: false, and because isolated is the default, they refuse to start a run until
someone explicitly chooses a trusted policy for that office. Field semantics and the legacy
sandbox.image.workspaceMount translation are documented in Configuration.
Workspaces created before the office layout hold directories named by raw conversation id. Every boot migrates them — workspace directories, conversation vault keys, and per-conversation host state — journaling each move so an interrupted run resumes instead of losing a conversation.
Two situations stop boot deliberately rather than guessing:
mikan office claim <conversationId> <platform> (daemon stopped);
the next start performs the move.Managed containers survive the rename: their binds are translated onto a snapshot of the running container, so the writable layer is preserved rather than rebuilt from the base image.
image:<image> recommended is the primary developed and recommended sandbox mode today; the other modes are kept for local development, compatibility, or experiments, and some capabilities will not be filled in.
| Capability | host | container:<name> | image:<image> | gondolin:default | firecracker:* | cloudflare:* |
|---|---|---|---|---|---|---|
| command execution | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| mikan-managed runtime lifecycle | not applicable | ❌ | ✅ | ✅ process-owned | ❌ | ❌ |
| per-conversation container / runtime | ❌ | ❌ | ✅ | ✅ | self-managed | bridge-derived id |
| per-conversation vault env | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ |
| automatic vault file projection / bind mount | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ |
| automatic workspace mount | host | self-managed | ✅ | ✅ | self-managed | ❌ |
| isolated conversation office | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ |
| idle auto-stop / recreate | not applicable | ❌ | ✅ | ✅ | ❌ | ❌ |
| default CPU / memory limits | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ |
/pi-sandbox boost | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ |
agent sandbox tool sets limits | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ |
| recommendation level | local dev | legacy / compatibility | mainline | preview | alpha | under construction |
Both ❌ rows above are refusals rather than silent downgrades. A mode that cannot enforce the
isolated projection raises Sandbox '<type>' cannot provide an isolated conversation office instead
of mounting more than the policy asked for, and a mode that cannot mount vault files raises
Sandbox type "<type>" does not support vault file mounts instead of running without the
credential. On the modes that cannot project files, keep vault credentials in env only.