# Site Architecture

> Capsem Architecture

- Skill: `google/site-architecture` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add google/site-architecture`
- Raw SKILL.md: https://api.skillmd.com/api/skills/google/site-architecture/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Google (https://skillmd.com/u/google)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/google/site-architecture

---


# Capsem Architecture

## System overview

Capsem sandboxes AI agents in air-gapped Linux VMs on macOS using Apple's Virtualization.framework (with a KVM backend for Linux). It runs as a daemon service (like Docker). The system has these layers:

**Host-side:**
- **capsem-service** (daemon): always-running background service. Axum HTTP server over Unix Domain Socket (`~/.capsem/run/service.sock`). Manages VM lifecycle, routes API calls to per-VM processes.
- **capsem-process** (per-VM): one process per sandbox. Boots the VM, bridges vsock connections (terminal + control), manages structured jobs (exec, file I/O) via a job store.
- **capsem** (CLI): user-facing CLI. Sessions are created from profiles and
  named by the service (`<profile-id>-N` unless the user supplies a name).
  `capsem shell` opens the TUI/session picker, creates or attaches through the
  service, and talks to capsem-service over UDS HTTP. User-facing copy says
  sessions; implementation/debug output may say VM when describing the
  virtualization layer.
- **capsem-mcp** (MCP server): stdio-based MCP server for AI agents (Claude Code, Gemini CLI). Bridges MCP tool calls to capsem-service HTTP API.
- **capsem-gateway** (HTTP gateway): TCP-to-UDS reverse proxy (default port 19222). Bearer token auth, CORS, 10MB body limit. Provides an explicit route table plus `/status` (cached 1s) and `/terminal/{id}` (WebSocket relay to per-VM UDS). Unknown routes return 404; the frontend and tray app connect through the gateway. Writes runtime files to `~/.capsem/run/` (gateway.token, gateway.port, gateway.pid).
- **capsem-app** (Tauri GUI): thin webview shell. Connects to gateway at `http://127.0.0.1:19222`. No VM logic, no capsem-core dependency. Only 2 IPC commands: `open_url` (opens URL in system browser) and `check_for_app_update` (Tauri updater). Bundles `web/app/dist` so the app can render the service-unavailable screen when gateway is unreachable.
- **capsem-tray** (system tray): menu-bar companion process. Polls the gateway for VM status, shows running/stopped counts, and provides quick actions (open dashboard, quit). Non-standalone: refuses to run without `--parent-pid` pointing at a live capsem-service, acquires a system-wide singleton lock at `~/.capsem/run/tray.lock` (only one tray ever in the menu bar), and self-exits within 500ms when its parent dies. Contract enforced by `capsem-guard` on the companion side, not the spawner.
- **capsem-guard** (shared library): parent-watch + singleton primitives used by capsem-tray and capsem-gateway. Provides `watch_parent_or_exit`, `Singleton::try_acquire`, and the umbrella `install(parent_pid, lock_path)`. Guarantees companions die with their parent and can't run standalone or as multiple instances -- closes the orphan-accumulation class of bug that `kill_on_drop(true)` alone cannot cover under SIGKILL/OOM/test-harness termination. See `/dev-rust-patterns` lesson 18.

**Guest-side:**
- **capsem-init** (`capsem-init`): PID 1, sets up air-gapped networking, mounts filesystems, deploys guest binaries, launches daemons, writes boot timing JSONL
- **capsem-pty-agent** (`capsem-pty-agent`): main guest agent -- PTY bridge, control channel, exec, file I/O, shutdown handler (see "Guest agent architecture" below)
- **capsem-sysutil** (`capsem-sysutil`): guest suspend helper. Opens its own vsock:5004 connection independently of the agent, so suspend works even if the agent is hung. Symlinked by capsem-init only to `/usr/local/bin/suspend`; in-VM shutdown commands are disabled.
- **capsem-net-proxy** (`capsem-net-proxy`): redirects HTTPS traffic to host MITM proxy via vsock
- **capsem-mcp-server** (`capsem-mcp-server`): guest MCP stdio-to-framed-vsock relay for tool calls to the host MITM MCP endpoint

## Reference routing

- Read `references/service-and-guest-protocols.md` before changing the
  service/process topology, CLI or MCP execution paths, gateway/service routes,
  host IPC, vsock framing or ports, or any guest agent binary.
- Read `references/storage-network-and-lifecycle.md` before changing VM storage
  or forks, network interception, security or logger ownership, ephemeral
  sessions, installation, service registration, companion launch, or updates.
- Read `references/crate-and-privilege-model.md` before moving responsibilities
  between crates, changing capsem-process permissions or environment, changing
  session/socket/share boundaries, or changing MITM CA-key handling.
- Read `references/key-files.md` before locating the implementation owner for
  an architectural change; it is the full annotated source map.
- Read `references/tauri-v2.md` before changing capsem-app or its Tauri v2
  configuration and IPC. The app remains a thin webview shell: only
  `open_url` and `check_for_app_update`; VM operations route through gateway.

## Core invariants

- All VM operations route through `capsem-service` to one `capsem-process` per
  session. No other host binary boots a VM or talks to guest vsock directly.
- The service and gateway expose an explicit route table. Unknown routes return
  404; do not add compatibility aliases or generic forwarding. Every public
  method/path pair is approval-locked in `config/public-surface.toml`.
- Terminal bytes, control messages, lifecycle requests, and exec output use
  distinct vsock responsibilities. Preserve the port and framing contract in
  `references/service-and-guest-protocols.md`.
- The guest is air-gapped: it has no real NIC, DNS, or direct internet. HTTPS
  reaches the host only through the guest net proxy and the MITM/security path.
- Corp config owns enterprise constraints; profiles own VM assets and runtime
  policy; settings own UI preferences. All enforcement and detection compiles
  into one `SecurityRuleSet` over `SecurityEvent`.
- Credential capture/injection belongs to the credential broker. Durable
  ledger storage belongs to `capsem-logger`; routes, MCP helpers, UI handlers,
  benchmarks, and network formatters must not open SQLite or own projection
  caches. Missing tables or columns are schema failures, never empty data.
- Sessions run profiles. Workspace and overlay bytes are session state, never
  a hidden image-authoring rail; package changes go through profile-owned
  inputs and the profile-derived asset build.
- `capsem-process` stays low privilege: a cleared allowlisted environment,
  0600 sockets, a 0700 session directory, read-only assets and guest binaries,
  and only `session_dir/guest/` shared with the VM.
- capsem-app contains no VM logic or `capsem-core` dependency. Gateway and tray
  are service-owned companions and must self-exit with their parent.

## Key source files

Read `references/key-files.md` for the full annotated source map.

## Tauri v2 reference

Read `references/tauri-v2.md` for Tauri v2 patterns. capsem-app is a thin webview shell -- only 2 IPC commands (`open_url`, `check_for_app_update`). All VM operations route through the gateway.

