Runtime selection
VoidBox selects the guest runtime from llm.provider. Two runtime families exist:
- Claude-shaped runtime (
claude-code) — used byclaude,claude-personal,ollama, andcustom. (LM Studio is reachable through the Rust builder API but not yet addressable from YAML.) - Codex runtime (
codex) — used bycodex.
Each family ships as its own rootfs (scripts/build_claude_rootfs.sh or scripts/build_codex_rootfs.sh); the provider picks which binary the guest-agent execs.
LLM providers
Claude-shaped runtime
All of these run the claude-code binary in the guest and differ only in how credentials and endpoints are provisioned:
claude—ANTHROPIC_API_KEYfrom the host environment is injected into the guest. This is the CLI default because an agent needs a provider and the Claude API is available out of the box; it is not a recommendation.claude-personal— stages host OAuth credentials from~/.claude/.credentials.jsoninto the guest. No API key required.ollama— pointsclaude-codeat a local Ollama endpoint reached through the guest-to-host networking gateway.custom— any Anthropic-compatible endpoint viaANTHROPIC_BASE_URL.
LM Studio is supported programmatically through the Rust builder (LlmProvider::lm_studio(...)) and shares the Claude-compatible proxy path, but YAML’s llm.provider: lm-studio is not wired yet — unknown provider strings fall back to claude.
Codex runtime
codex switches runtimes entirely. The guest execs the bundled codex binary and parses its JSON event stream directly. Auth is ~/.codex/auth.json (ChatGPT login) or OPENAI_API_KEY.
Overriding the provider per run
VOIDBOX_LLM_PROVIDER and VOIDBOX_LLM_MODEL override the spec at launch — useful for swapping providers without editing YAML:
# Run as declared in the spec
voidbox run --file examples/hackernews/hackernews_agent.yaml
# Same spec, Ollama endpoint through the claude-code runtime
VOIDBOX_LLM_PROVIDER=ollama \
VOIDBOX_LLM_MODEL=qwen3-coder \
voidbox run --file examples/hackernews/hackernews_agent.yaml
# Switch the guest runtime to codex
VOIDBOX_LLM_PROVIDER=codex \
voidbox run --file examples/hackernews/hackernews_agent.yaml
Skill types
Skills are the composable units of capability injected into a VoidBox. Each type is provisioned differently in the guest environment:
| Type | Constructor | Provisioned as | Example |
|---|---|---|---|
| Agent | Skill::agent("claude-code") | Reasoning engine designation | Runtime binary marker |
| File | Skill::file("path/to/SKILL.md") | /workspace/.claude/skills/{name}.md | Domain methodology |
| Inline | Skill::inline("name", "content") | /workspace/.claude/skills/{name}.md | Methodology defined in code |
| Remote | Skill::remote("owner/repo/skill") | Fetched from GitHub, then written to /workspace/.claude/skills/ | obra/superpowers/brainstorming |
| MCP | Skill::mcp("server-name") | /workspace/.mcp.json for Claude-shaped runtimes, ~/.codex/config.toml for Codex | Structured tool server |
| CLI | Skill::cli("jq") | Expected in guest initramfs | Binary tool |
| OCI | Skill::oci("ghcr.io/voidbox/skill-jq:1.7", "/skills/jq") | OCI image pulled and mounted read-only at the declared guest path | Versioned binaries or data bundle |
Guest execution model
Inside the micro-VM, the guest-agent runs as PID 1 and controls the full execution lifecycle:
- Authentication — Validates the session secret received over vsock against the value injected via kernel cmdline at boot.
- Policy enforcement — Reads
/etc/voidbox/allowed_commands.json(command allowlist) and/etc/voidbox/resource_limits.json(rlimits). Appliessetrlimitconstraints for memory, file descriptors, and process count. - Privilege drop — Drops from root to
uid:1000before executing any user workload. - Fork + exec — Launches the runtime selected by
llm.provider:claude-codefor Claude-shaped providers,codexfor Codex.
Skills are pre-provisioned before execution: file skills are written to /workspace/.claude/skills/, MCP discovery is written to /workspace/.mcp.json or ~/.codex/config.toml depending on runtime, and OCI skill images are mounted read-only at their declared paths.
Matching rootfs to provider
The host does not pre-flight whether the loaded rootfs actually contains the runtime binary the provider needs. If you run a Codex spec against a Claude rootfs (or vice versa), the guest-agent’s exec call fails at spawn time with a diagnostic error listing the missing binary, the guest PATH, and candidate paths probed — enough to identify the mismatch, but only surfaced after VM boot.
Build the matching rootfs for your provider before running examples — scripts/build_claude_rootfs.sh for Claude-shaped providers, scripts/build_codex_rootfs.sh for Codex. Auto-pulled GHCR images already carry the correct runtime for each flavor.