Runtime selection

VoidBox selects the guest runtime from llm.provider. Two runtime families exist:

  • Claude-shaped runtime (claude-code) — used by claude, claude-personal, ollama, and custom. (LM Studio is reachable through the Rust builder API but not yet addressable from YAML.)
  • Codex runtime (codex) — used by codex.

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:

  • claudeANTHROPIC_API_KEY from 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.json into the guest. No API key required.
  • ollama — points claude-code at a local Ollama endpoint reached through the guest-to-host networking gateway.
  • custom — any Anthropic-compatible endpoint via ANTHROPIC_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:

TypeConstructorProvisioned asExample
AgentSkill::agent("claude-code")Reasoning engine designationRuntime binary marker
FileSkill::file("path/to/SKILL.md")/workspace/.claude/skills/{name}.mdDomain methodology
InlineSkill::inline("name", "content")/workspace/.claude/skills/{name}.mdMethodology defined in code
RemoteSkill::remote("owner/repo/skill")Fetched from GitHub, then written to /workspace/.claude/skills/obra/superpowers/brainstorming
MCPSkill::mcp("server-name")/workspace/.mcp.json for Claude-shaped runtimes, ~/.codex/config.toml for CodexStructured tool server
CLISkill::cli("jq")Expected in guest initramfsBinary tool
OCISkill::oci("ghcr.io/voidbox/skill-jq:1.7", "/skills/jq")OCI image pulled and mounted read-only at the declared guest pathVersioned binaries or data bundle

Guest execution model

Inside the micro-VM, the guest-agent runs as PID 1 and controls the full execution lifecycle:

  1. Authentication — Validates the session secret received over vsock against the value injected via kernel cmdline at boot.
  2. Policy enforcement — Reads /etc/voidbox/allowed_commands.json (command allowlist) and /etc/voidbox/resource_limits.json (rlimits). Applies setrlimit constraints for memory, file descriptors, and process count.
  3. Privilege drop — Drops from root to uid:1000 before executing any user workload.
  4. Fork + exec — Launches the runtime selected by llm.provider: claude-code for Claude-shaped providers, codex for 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.