Concepts

  1. Host vs guest
  2. Kernel vs disk
  3. Three files
  4. Host brokers
  5. Protocol version
  6. Tools
  7. Source snapshot

Host vs guest

  Host (your process) Guest (abox-guest)
Runs pkg/abox or abox, abox-vmm, LLM broker, MCP broker Agent loop, five tools
Sees Session dir on the host, config.yaml, credentials /work/repo inside the VM
HTTPS Provider and MCP Streamable HTTP None. No guest NIC, no TSI inet
Must not Execute model-authored commands itself Import internal/tui, internal/provider, or cmd/abox

The SDK never runs the agent loop on the host. It sends user_turn over vsock and renders agent_event frames. When the guest needs a model or an MCP tool, it names a configured alias; the host broker dials the network.

Isolation claims stay Planned. The device plan is vsock-only (krun_add_vsock with flags 0), no guest NIC, no host-path virtio-fs. That is an intended allowlist, not a passed hardware suite. Linux/KVM needs independent Phase 0.5 and Phase 18 evidence on both pinned distributions; macOS evidence does not cover it.

Kernel vs disk

The .raw file is only a disk: ext4 userspace (Alpine, git, patch, abox-guest). No kernel, no bootloader.

The guest kernel is libkrunfw (Homebrew on macOS or the pinned distro package on Linux). abox-vmm attaches host files as virtio-blk:

host:  ~/.abox/sessions/<id>/root.raw      host file (ext4)
         ↓ libkrun virtio-blk
guest: /dev/vda  →  /                      Alpine + abox-guest + /work/repo

host:  ~/.abox/sessions/<id>/config.raw
         ↓
guest: /dev/vdb                            session id + model alias
                                           (no secrets, no MCP URLs)

Three files

  1. Golden image — ~/.abox/images/abox-guest-linux-<arch>.raw. Packed once (make image). Template plus adjacent manifest. Not attached to a running VM.
  2. Session disk — ~/.abox/sessions/<id>/root.raw. Clone of (1). This is /dev/vda. Destroy the session dir and this disk is gone; the golden stays.
  3. Config disk — sessions/<id>/config.raw. ~1 MiB, read-only /dev/vdb. Not cloned from the golden image. Model profile only; credentials stay on the host.

Open copies (1)→(2) and writes (3). Resume boots the existing (2) and rewrites (3) without secrets. Startup also scrubs leftover plaintext keys out of old config.raw / guest-config.json files.

The image manifest records schema, architecture, image ID, protocol, and SHA-256. Open rejects an architecture/protocol mismatch or changed image. Linux also rejects metadata-free legacy images and sessions rather than guessing their architecture.

A guest that still finds secrets or mcp_servers in that config refuses to boot. Rebuild the image and start a new session.

Host brokers

Two host-side clients sit between the guest and the network:

Broker Guest may send Host does
LLM (internal/llmbroker) model alias + messages + tool schemas Resolves the key, dials base_url
MCP (internal/mcpbroker) configured server name + tool name + args Resolves the token, dials that server’s URL

The guest cannot supply a URL, header, or credential. connectivity.mode: offline disables both remote MCP and provider HTTPS.

LLM traffic does not use connectivity.mode for routing. direct vs agentgateway applies to MCP servers. The LLM broker always hits the selected model’s base_url.

Protocol version

This is the host↔guest RPC version (HelloParams.Protocol), not the GitHub release tag. Current guest binary sends 4. Open / Resume require 4.

Guest What it added SDK today
v1 Plain Turn Rejected (ErrGuestTooOld)
v2 Cancel, TurnOpts, usage / rich events. Secrets still pushed into the guest Rejected
v3 Host LLM broker; secretless provider path Rejected
v4 Host MCP broker + run_command approval Required

Resume always uses that session’s disk. Updating the golden image does not upgrade old sessions. Check sess.Capabilities(). After a successful Open, Protocol is 4 and Cancel, RichEvents, TurnOptions, Approvals, and MCPBroker are all true.

Details: Protocol versions.

Tools

Five builtins in the guest: list_files, read_file, search, apply_patch, run_command. Paths cannot escape /work/repo. No write_file.

MCP tools are discovered on the host and advertised to the model as server__tool. Optional per-server tool_allowlist in config.yaml.

Model-authored run_command asks the host before exec. Default is deny. Approvals. MCP tools do not prompt yet.

Host-initiated Session.RunCommand / abox --probe-vm are supervisor RPCs, not model tool calls, and do not go through that gate.

Source snapshot

Open discovers the enclosing Git worktree and snapshots its repository root. A clean worktree archives committed HEAD. A dirty or commitless worktree is copied into a private host-side repository using tracked files and non-ignored untracked files, then archived from a private commit. This preserves local changes without modifying host Git while omitting ignored caches, build output, and local secrets. .git metadata and the active ABox state directory are not copied; symlinks and special files are rejected. Resume(id) boots the existing disk and does not recopy the host repository.