The Agent Harness.
Two programs that turn a language model into an agent. We know how Claude Code works because people reverse-engineered it. We know how OpenClaw works because its code is open.
Claude Code runs one loop per task. OpenClaw runs one loop that never stops.
Every agent needs a loop: the model asks for a tool, the harness runs it, and the result goes back to the model.
Claude Code starts a fresh loop for each task and ends it when the model replies with end_turn.
OpenClaw runs a single daemon that stays up for days and wakes whenever a message arrives. Step through
the same five steps for both harnesses and see where they differ.
# Claude Code: one ephemeral loop per task def run_task(prompt): messages = [user(prompt)] while True: reply = model(messages) # think messages.append(reply) if not reply.tool_calls: # text only -> done return reply # stop_reason: "end_turn" for call in reply.tool_calls: # act messages.append(run_tool(call)) # observe, then repeat
# OpenClaw: one daemon, never sleeps while True: # the Gateway event = inbox.get() # a message, cron tick, or webhook agent = route(event) # pick the per-channel agent agent.handle(event) # runs its own loop, then waits
nO, an async generator, and it stops when the model replies with end_turn. OpenClaw is a
persistent Gateway daemon. This one background process takes in many chats at once, sends each chat to a session run by the right agent, and keeps running until you stop it.
Claude Code shrinks its history to fit. OpenClaw writes its memory to disk.
Claude Code works inside a fixed window: the model can only see so many tokens at once. Before each model call it tries five compaction steps, called shapers, cheapest first, and stops as soon as the history fits. There is no single fill level that sets this off, and writing a summary is the last resort. OpenClaw mostly avoids the problem, because its memory lives on disk as plain Markdown and YAML files that last longer than any one session.
# Claude Code: shrink history cheapest-first, stop once it fits SHAPERS = [budget_reduction, snip, microcompact, context_collapse, auto_compact] def fit(messages, limit): for shape in SHAPERS: if tokens(messages) <= limit: break # fits now, stop early messages = shape(messages) return messages
~/.openclaw/workspace, and it lasts across days and channels.
The same folder holds prompt files like AGENTS.md and SOUL.md.
Both use one skill format. Claude Code's tools work on code. OpenClaw's work on your life.
Both harnesses package skills the same way: a SKILL.md file with a YAML header (frontmatter), loaded by progressive disclosure.
Both use MCP to plug in any other tool. The difference is what the tools act on. Claude Code's tools work on a codebase.
OpenClaw's tools work on the rest of your life: your browser, your schedule, your chat apps. OpenClaw can also install skills from a public marketplace.
SKILL.md files and MCP. Claude Code's tools work on a codebase (Read, Edit, Bash, Grep), and its
skills can be set at four scopes: enterprise, personal, project, or plugin. OpenClaw's tools work on your life (browser, canvas, cron,
Discord, Slack), and it installs skills from the ClawHub registry at clawhub.ai. Be careful there: an audit
found that roughly 26% of 31,000+ community skills had at least one vulnerability.
Claude Code's subagents are short-lived helpers. OpenClaw's agents run side by side for days.
Claude Code starts a subagent in a fresh, separate context window, lets it do the work that uses up lots of tokens, and keeps only its summary. That way the main conversation does not fill up. OpenClaw runs many agents at once, one per channel or per peer (the person or group on the other end). Each one is long-lived and sandboxed. Press spawn to watch Claude Code's version.
h2A).Claude Code's hooks react to events inside a session. OpenClaw's triggers come from outside.
Claude Code's hooks are shell commands you attach to named events in a single session, such as the moment before a tool runs. They run every time their event happens, whatever the model wants. OpenClaw's triggers come from the outside world and wake the agent up: a cron schedule, a webhook, or a new message.
Fire inside one session.
- where
- the
hookskey insettings.json, reloaded as soon as the file changes - events
- SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, PreCompact, Stop, plus SubagentStart/Stop, SessionEnd, PermissionRequest, and more
- can block
- a
PreToolUsehook can return allow, deny, or ask. Or it can exit with code 2, which blocks the call and sends the hook's stderr back to the model - trigger
- the session's own lifecycle
Wake the agent from outside.
- cron
- scheduled jobs (
maxConcurrentRunsdefault 8,sessionRetentiondefault '24h') - webhooks
- authenticated, set under
hooks, default path/hooks; Gmail Pub/Sub works too - heartbeat
- each agent wakes itself, by default every '30m' (0m turns it off)
- channels
- are where messages come in and replies go out. A new message wakes the agent, and the reply goes back the same way
Claude Code checks every tool call. OpenClaw checks who is allowed to talk to it.
Before a tool call runs, Claude Code checks it against your rules. In auto mode, a separate classifier model checks it too. OpenClaw starts one step earlier. It first decides who is allowed to talk to it at all, then puts everyone who is not you in a sandbox.
Check the tool call.
- rules
ToolorTool(specifier), e.g.Bash(npm run test *),Read(./.env)- order
- deny → ask → allow; the first matching rule wins, and rules from all scopes are merged
- modes
- default, acceptEdits, plan, auto, dontAsk, bypassPermissions
- classifier
- in auto mode, a separate model blocks risky actions (curl|bash, prod deploys, force-push, push to main)
- floors
- protected paths (.git, .claude, shell rc) are never approved automatically. Even bypass mode blocks
rm -rf /and refuses to run as root unless sandboxed
Check who is talking.
- DM policy
pairing | allowlist | open | disabled, default pairing- pairing
- a one-time code:
openclaw pairing approve <channel> <code> - main session
- belongs to the single owner and runs tools on the host with full access
- everyone else
- all other sessions are sandboxed (Docker by default) with per-tool allowlists
Claude Code keeps its config in your repo. OpenClaw keeps it on the machine that runs it.
Both are configured with plain files. Neither uses a database. Claude Code's config lives in .claude/ inside the repo,
where it is committed and shared with your team. OpenClaw's lives in ~/.openclaw on whichever machine runs
the always-on daemon.
Committed to git, shared with the team.
- memory
CLAUDE.mdat~/.claude/,./,./.claude/, plusCLAUDE.local.md- settings
settings.json+settings.local.json; when settings conflict, the priority order is managed > CLI > local > project > user (permission rules are merged instead)- agents
.claude/agents/- mcp
.mcp.json/~/.claude.json- skills
SKILL.mdfiles
Lives in ~/.openclaw.
- config
- one
~/.openclaw/openclaw.json(JSON5: comments + trailing commas; override viaOPENCLAW_CONFIG_PATH) - workspace
~/.openclaw/workspacewith.agents/,extensions/,skills/- channels
- under
channels.<provider>.* - models
- per agent via
agents.defaults.models(catalog + allowlist)
~/.openclaw on whichever machine runs it.
Claude Code runs where you write code. OpenClaw runs in your chat apps.
Claude Code is one harness that runs in three places in your dev environment: your terminal, your editor, and a cloud container on the web. OpenClaw is one Gateway that you host yourself, and it connects to the messaging apps you already use every day.
Your shell
- runs in
- your terminal, in your current directory
- speed
- fastest, no cold start
- persistence
- sessions under
~/.claude/
Inside the editor
- runs in
- VS Code / JetBrains
- extras
- sees your selected text and open files
- diffs
- shown in the editor's own diff view
Cloud container
- runs in
- a temporary VM, deleted when the session ends
- setup
- install deps in
SessionStart - persistence
- commit & push or it's gone
Self-hosted bridge
- runs on
- a VPS or your own machine
- nodes
- a macOS menu bar, plus iOS and Android nodes
- shape
- one daemon, many channels at once
The apps you already use
- messaging
- WhatsApp, Telegram, Slack, Discord, Signal, iMessage, Matrix, Teams
- more
- Google Chat, Feishu, LINE, WeChat, QQ, IRC, Nostr, Twitch, WebChat
- idea
- the agent shows up where you already are
Claude Code had to be decompiled. OpenClaw publishes its source almost every day.
We know how these two harnesses work for very different reasons. We know Claude Code's internals only because its source leaked. We know OpenClaw's because its code has been open from day one.
Known by decompilation.
- shape
- one ~12MB minified, obfuscated
cli.js(vars like X6, K8, b6) - the leak
- the
.js.mapsource maps in the npm package included a sourcesContent field holding the original TypeScript, which made deobfuscation possible - coverage
- reported as a "source leak" by InfoQ and The Register (Apr 2026)
- analysis
- VILA-Lab studied v2.1.88: ~1,884 TS files, ~512K lines of code. Only ~1.6% is AI decision logic; the other ~98.4% is ordinary deterministic infrastructure
Known by reading it.
- license
- MIT, public from day one
- releases
- CalVer
vYYYY.M.D, almost every day; latest stable v2026.5.27 - lineage
- Clawdbot → Moltbot → OpenClaw, by Peter Steinberger (@steipete)
- scale
- hundreds of thousands of GitHub stars (~375K); its mascot is Molty, a space lobster
- steward
- its creator was hired by OpenAI (Feb 2026), and a stewardship foundation now runs it
git clone.
The harness is what turns a model into an agent.
A language model on its own is a function: text goes in, text comes out. The code around it is what makes it an agent. That code runs the loop, keeps the context small enough to fit, provides the tools, checks permissions, and connects to the places where you use it. Claude Code and OpenClaw make almost opposite choices at every one of these layers, and both work.
Claude Code is a closed, single-task loop that you run in your terminal, and we know its insides from a leaked source map. OpenClaw is an open, always-on daemon that talks to you through your chat apps, and you can read all of its code on GitHub. Both can run the same model. What differs is the harness.
- github.com/VILA-Lab/Dive-into-Claude-Code
- kirshatrov.com/posts/claude-code-internals
- blog.brightcoding.dev · inside claude code
- dev.to/kolkov · we reverse-engineered 12 versions
- github.com/ghuntley/claude-code-source-code-deobfuscation
- infoq.com · claude code source leak
- code.claude.com/docs · hooks
- code.claude.com/docs · settings
- code.claude.com/docs · skills
- code.claude.com/docs · permission modes
Claude Code facts come from official docs plus reverse-engineering of the leaked source maps. OpenClaw facts come from its open repo and docs.