How Grok Bot works: VM, Sand host, gateway, agents, subagents, tools, persistence, and failover A developer has reconstructed the deployed architecture of Grok Bot, a stateful agent service that runs inside a Linux container, from recovered JavaScript bundles and runtime scripts. The reconstruction, covering 1,804 modules at commit 8740c03c8c6f14f28d1af653c2f0869da021b359, documents a host process (host-main.cjs) that owns conversations and checkpoints each turn, plus a separate exec-daemon providing controlled access to shells, files, terminals, MCP servers, browsers, and virtual desktops. The system is described as a durable coordinator connected to replaceable services, with inference handled by a Cursor-backed service. Grok Bot is a stateful agent service that runs inside a Linux "box." The model is only one part of it. A host process accepts commands, owns conversations, assembles prompts, calls an inference backend, delegates tool work, checkpoints each turn, and publishes events. A separate execution daemon gives the host controlled access to shells, files, terminals, MCP servers, browsers, and virtual desktops. This document explains the deployed system recovered from the Grok Bot image and the local VM built to preserve and run that image. It keeps those two systems separate. The recovered source describes the original runtime. The clone-lab code describes the recovery VM, its routing, and its known parity gaps. The source reconstruction comes from the deployed host-main.cjs , five auxiliary host bundles, the separate exec-daemon bundle, exact unbundled runtime scripts, protocol reflection, and native binaries. The original TypeScript source maps were not present. Recovered JavaScript bodies are strong evidence of behavior, but they do not recover erased TypeScript annotations or every original import spelling. This document uses four labels: - Exact runtime source is a byte-identical script captured from the image. - Recovered source is a body extracted from a deployed JavaScript bundle. - Derived means a relationship can be reproduced mechanically from recovered files or protocols. - Inference means several sources support an architectural conclusion that no single source states as a contract. The canonical recovered tree contains 1,804 modules. The clean developer-facing projection divides them into sand-host , exec-daemon , dune , and 36 @anysphere/ workspace packages. These counts come from the reconstruction at commit 8740c03c8c6f14f28d1af653c2f0869da021b359 . Grok client or control plane | | authenticated HTTP command | long-lived SSE event stream v +----------------------- Linux box ------------------------+ | | | host-main.cjs | | +---------------- SandHost ---------------------------+ | | | gateway - transcript manager - per-agent runner | | | | | | | | | | | +- inference RPC | | | | | +- Task children | | | | | +- approvals | | | | | +- tools | | | | v | | | | store.db + blob DB + transcript projections | | | +------------------------------------------------------+ | | | authenticated ConnectRPC/WS | | v | | exec-daemon | | +- shell and file operations | | +- PTY and tmux sessions | | +- MCP subprocesses | | +- X11 computer use and screenshots | | | | sand-window-router - per-display exec daemons | | sand-supervisor - host, Xvfb, Chrome, VNC, noVNC | +-----------------------------------------------------------+ | | short-lived access token v Cursor-backed inference service The useful mental model is a durable coordinator connected to replaceable services. host-main.cjs decides what a turn means. The inference backend generates model steps. exec-daemon performs operating-system work. The gateway translates client commands and streams state changes. No one component is the whole bot. The captured deployment ran as a Docker-style container. /tini was PID 1 and started pod-daemon . pod-daemon created processes on demand and parented the long-lived Sand runtime. The observed process tree was: /tini └── /pod-daemon gRPC process creation, TCP 26500 └── sand-exit-watch top-level child ownership ├── supervise-exec-daemon │ └── exec-daemon ConnectRPC 1337, PTY WS 1338 ├── supervise-sand-supervisor │ └── sand-supervisor.mjs │ ├── host-main.cjs HTTP/SSE gateway 1340 │ ├── x11vnc children │ └── fork noVNC router TCP 6081 ├── sand-window-router.mjs TCP 1339 ├── sand-session-sync.mjs ├── browser authentication and cookie helpers ├── desktop :1 primary agent desktop └── desktops :2, :3, :4 forked task desktops pod-daemon is below the hosting control plane and above the application. It is useful for creating a process inside the box, but it is not the conversational API. The client experience enters through host-main.cjs on port 1340. The VM boundary matters. Same-user processes inside the box can often reach loopback listeners, inspect process metadata, and share X11 state. Display numbers separate desktops and browser profiles. They are not separate operating-system users or security principals. The recovered entry point recovered-monorepo-final/src/host/main.ts acquires a host lock, starts SandHost , resolves gateway settings, starts the server, writes discovery data, and installs shutdown handlers. The composition root in recovered-monorepo-final/src/host/sand-host.ts loads extensions, restores transcript state, creates runner services, wires events, and exposes the gateway API. The exact sand-supervisor.mjs script owns a wider dependency graph. It starts or re-adopts the host and desktop processes, writes health snapshots, detects crash loops, and probes the VNC path. supervise-exec-daemon separately restarts the primary execution daemon and checks its listener. The host adds an authenticated ping because an open TCP port does not prove that the daemon event loop can answer. Shutdown and upgrade are coordinated states. The host stops new work, expires pending approvals, checkpoints active turns at safe boundaries, records agents that need continuation, and lets the replacement process consume those resume markers. recovered-monorepo-final/src/host/gateway-server.ts provides HTTP authentication, body-size limits, JSON command routing, health, SSE, avatars, local-exec queues, WebAuthn queues, and upgrade preparation. The dispatch table in recovered-monorepo-final/src/host/gateway-protocol.ts maps command names to methods in recovered-monorepo-final/src/host/host-gateway-api.ts . The ordinary command path is: php POST /api/