The Untrusted-Inbound Harness

what an agent becomes when strangers can message it

openclaw/openclawView the repository
LANGUAGE
TypeScript (+Swift/Kotlin)
SOURCE LOC
~1.83M core (+0.95M ext)
MODULES
78 src dirs · 22 pkgs · 151 ext
BUILT-IN TOOLS
~45 core, per-context
PROVIDERS
77 as extensions
OS SANDBOX
opt-in — host by default
All 36 blocks

Surfaces & entry

The turn

Tools

Context & memory

Model layer

Safety

Extensibility

State

Isometric plate: the 36 subsystems of OpenClawBlocks are grouped into districts by hatching and tint; block height is a rough proxy for code mass. Lines trace the data flow of a single turn. The block index beside this diagram carries the same information as text.ADBCEGFHIMJLONAJPKQXRSZYTAAUABVWACADAEAFAGAHAI

Hover to read · drag to pan · ⌘/ctrl + scroll to zoom

How to read this plate

Each block is one subsystem of OpenClaw. Its height is a rough proxy for code mass, calibrated the same way across every harness so the plates are comparable. Hatching and tint group blocks into districts — surfaces, the turn, tools, context, the model layer, safety, extensibility and state.

Lines trace the real data flow of a single turn plus the major supporting links. Pick any block for a plain description and the files it was read from, or trace the turn to walk the path a request actually takes.

What this is

OpenClaw is not a coding agent that grew a chat interface; it is a personal assistant whose first assumption is that other people can talk to it. That single assumption reshapes everything downstream. A stranger messaging you on WhatsApp has to be paired and approved before the assistant will answer, inbound text is handled as hostile input rather than instruction, and the tool set is resolved per conversation from who is asking and where.

It is by a wide margin the largest harness here: 1.83M lines of TypeScript in its core, another 0.95M across 151 bundled extensions, a 276k-line web dashboard, 375k lines of Swift and 106k of Kotlin for companion apps on macOS, iOS and Android — and roughly 4.6M lines of test code, two and a half times its own source. Almost every capability ships as a plugin: 77 model providers, 26 chat channels and 95 additional tools are declared in extension manifests rather than compiled into the core.

The architectural centre is the Gateway, a local control plane owning sessions, tools, events and channel connections. The CLI, the web UI, the terminal interface, the phone apps and two OpenAI-compatible HTTP surfaces are all merely clients of it. At 251,750 lines the Gateway is about two-thirds the size of the agent code it fronts — the price of serving that many front doors from one brain.

Asking how many tools it has is the wrong question, and the source says so. Tools are ToolDescriptor records that declare an owner — core, plugin, channel or mcp — and an availability expression, and the set is assembled fresh for each conversation from the sandbox policy, the trigger, the requesting agent, plugin grants and several allowlists. Around 45 core tool names exist; how many you actually get depends on who you are.

Implementation

Lineage. OpenClaw is the fourth harness in this atlas descended from pi, and it is explicit about it: THIRD_PARTY_NOTICES.md records that portions were adapted from Pi / pi-mono, and package.json declares @earendil-works/pi-tui at 0.82.1 for terminal rendering. Where prime-agent froze a fork of pi at 0.7.3 and never renamed it, OpenClaw consumes current upstream as a library and grew a gateway, 151 extensions and five native app targets around it. Its own history runs Warelay → Clawdbot → Moltbot → OpenClaw.

The boundary is the inbox, not the OS. A real container sandbox exists — src/agents/sandbox.ts, validate-sandbox-security.ts, Docker setup scripts — but src/config/types.sandbox.ts declares enabled?: boolean with no default, and agent-tools.ts:379 reads options?.sandbox?.enabled ? options.sandbox : undefined, so tools run on the host unless you switch it on. What is on by default is inbound-trust machinery: pairing for DM-capable channels, src/security/external-content.ts, a 1,512-line audit log, a 2,029-line operator-approval store that can route a risky command to a human over the chat itself, plus packages/net-policy and a proxy-capture module.

State is a database, not a log file. Where the other harnesses keep JSONL or an event log, OpenClaw keeps two SQLite databases defined in 3,278 lines of hand-written SQL — 134 tables and 130 indexes in openclaw-state-schema.sql, 35 more tables in openclaw-agent-schema.sql — with schema-repair, additive-migration and legacy-backfill modules to move them forward in place. Around that sit 33,218 lines of cron, plus tasks, boards and a fleet registry, because an assistant that acts unprompted needs durable queues rather than a transcript.

Extension is a marketplace with a security gate. src/plugins/ is 113,212 lines across 526 files — discovery, a hook bus, a manifest registry, ClawHub and an install-time security scan — and it is the only harness here that scans a plugin before letting it run. Two further seams are unusual: src/agents/harness/native-hook-relay*.ts carries lifecycle hooks across a process boundary into Swift clients, and extensions/ contains working bridges to three other harnesses in this atlas (codex, opencode, opencode-go) plus migrate-hermes, which imports Hermes's own state.db, memories, skills and secrets. The subjects of this survey are not independent of each other.