A high-level architecture report based on public research, the accidental npm source map leak (March 2026), and community analysis. 512,685 lines of TypeScript across 1,902 files -- only ~1.6% is AI decision logic; the rest is deterministic harness infrastructure.
Contents
The harness is the infrastructure layer between the Claude language model and the real world. It wires together five vertical layers: surface interfaces, the core agent loop, a safety and action layer, a state persistence layer, and a backend execution environment.
The model is not the orchestrator. It emits structured tool-use requests; the harness decides whether to execute them, then feeds results back. The model only ever sees a conversation.
flowchart TD
U["User"] -->|"prompt"| S["Surface Layer"]
S -->|"assembled context"| AL["Agent Loop"]
AL -->|"tool request"| SA["Safety and Action Layer"]
SA -->|"approved action"| BE["Backend Execution"]
BE -->|"tool result"| SL["State Layer"]
SL -->|"updated context"| AL
AL -->|"final reply"| S
S -->|"response"| U
subgraph SurfaceLayer["Surface Layer"]
S
end
subgraph Core["Core Layer"]
AL
end
subgraph Safety["Safety and Action Layer"]
SA
end
subgraph State["State Layer"]
SL
end
subgraph Backend["Backend Execution"]
BE
end
Interactive CLI, headless CLI, Agent SDK, IDE extensions, Desktop app, Browser -- all converge on the same queryLoop().
The async queryLoop() generator drives every iteration. It is the only place the model is invoked.
Permission system, hooks, tool pool assembly, shell sandbox, subagent spawning. Any layer can block a request.
Context assembly, session persistence (JSONL), CLAUDE.md hierarchy, sidechain subagent transcripts.
Shell execution, filesystem operations, MCP server connections, 42+ tool subdirectories implementing concrete tool logic.
Only ~1.6% of the codebase is AI decision logic. The other 98.4% is deterministic infrastructure: permissions, context management, tool routing, and recovery logic.
The core loop is a ReAct-inspired async generator (queryLoop()). It runs until the model returns a response with no tool calls, or until a stop condition fires. The loop has seven distinct continuation sites with separate recovery paths for token exhaustion, compaction failure, and API overload.
The orchestration code does not decide which file to read or which command to run. It faithfully executes what the model emits -- nothing more.
flowchart TD
START(["Session Start"]) --> INIT["Init State"]
INIT --> CTXASSEMBLE["Assemble Context"]
CTXASSEMBLE --> COMPACT["Compaction Pass"]
COMPACT --> INVOKE["Invoke Model API"]
INVOKE -->|"streaming chunks"| STREAM["Stream Parser"]
STREAM -->|"text only"| REPLY["Emit Reply"]
REPLY --> DONE(["Loop End"])
STREAM -->|"tool-use block"| PREHOOK["PreToolUse Hooks"]
PREHOOK -->|"blocked"| INJECT["Inject Block Feedback"]
INJECT --> CTXASSEMBLE
PREHOOK -->|"allowed"| PERMCHECK["Permission Check"]
PERMCHECK -->|"denied"| ASK{"Ask User?"}
ASK -->|"no"| INJECT
ASK -->|"yes"| EXEC["Execute Tool"]
PERMCHECK -->|"approved"| EXEC
EXEC --> POSTHOOK["PostToolUse Hooks"]
POSTHOOK --> RESULT["Append Tool Result"]
RESULT --> STOPCHECK{"Stop Condition?"}
STOPCHECK -->|"no"| CTXASSEMBLE
STOPCHECK -->|"yes - max turns"| DONE
STOPCHECK -->|"yes - context full"| AUTOCOMPACT["Auto-Compact"]
AUTOCOMPACT --> CTXASSEMBLE
| # | Step | What happens |
|---|---|---|
| 1 | Settings resolution | Merge managed, user, project, CLI, and session permission rules into a single policy |
| 2 | State init | Restore or create session JSONL, load CLAUDE.md hierarchy, inject git status and date |
| 3 | Context assembly | Layer system prompt, tool definitions, memory files, message history, and prior tool results |
| 4 | Compaction pass | Apply five-stage pipeline to keep token count under budget before calling the model |
| 5 | Model invocation | POST to Claude API with assembled context; response arrives as an event stream |
| 6 | Tool dispatch | Completed tool-use blocks route through PreToolUse hooks, then permission check, then execution |
| 7 | Result integration | Tool outputs wrap as tool-result blocks and re-enter context for next iteration |
| 8 | Stop check | End if model returns text-only, max iterations hit, or manual stop signal received |
Claude Code registers approximately 66 built-in tools at session start. Tools are split into concurrent (read-only, up to 10 parallel) and serialized (write/mutating, one at a time). External tools arrive via MCP servers, plugins, and skills.
Tools must explicitly declare themselves safe for concurrency. The default is fail-closed: unless a tool opts in, it serializes.
flowchart LR
MODEL["Claude Model"] -->|"tool-use block"| ROUTER["Tool Router"]
ROUTER --> BUILTIN["Built-in Tools"]
ROUTER --> MCP["MCP Server Tools"]
ROUTER --> AGENT["Subagent Tool"]
BUILTIN --> FIO["File I/O"]
BUILTIN --> SHELL["Shell Exec"]
BUILTIN --> GIT["Git Ops"]
BUILTIN --> SEARCH["Search and Web"]
BUILTIN --> NB["Notebook Edit"]
BUILTIN --> TASK["Task and Memory"]
MCP -->|"stdio or HTTP"| MSERVER["External MCP Server"]
AGENT -->|"fork or worktree"| SUB["Subagent Loop"]
FIO --> PERM["Permission Gate"]
SHELL --> PERM
GIT --> PERM
SEARCH --> PERM
NB --> PERM
TASK --> PERM
MSERVER --> PERM
PERM -->|"approved"| EXEC["Execute"]
PERM -->|"denied"| BLOCK["Block"]
Input validation (Zod schema) → PreToolUse hooks → Permission resolution → Execution → PostToolUse hooks → Error handling
Read-only tools: up to 10 concurrent. Mutating tools: strictly serialized. The StreamingToolExecutor dispatches tool blocks as they finish streaming -- before the model stops generating.
Recommended cap: 5-6 active servers (subprocess overhead). Tool schemas load on-demand. Output capped at 25,000 tokens per call; large results spill to disk with a reference in context.
Permissions enforce deny-first authorization across seven independent layers. Any single layer can block a request regardless of what other layers allow. The design ensures a compromised or jailbroken model cannot bypass safety checks by being persuasive -- enforcement is structural, not conversational.
flowchart TD
REQ["Tool Request"] --> PREFILTER["Layer 1: Pre-filter"]
PREFILTER -->|"tool not denied"| DENY1["Layer 2: Deny Rules"]
PREFILTER -->|"globally denied"| BLOCKED(["Blocked"])
DENY1 -->|"no deny match"| MODE["Layer 3: Permission Mode"]
DENY1 -->|"deny matches"| BLOCKED
MODE --> TIER{"Tier?"}
TIER -->|"Tier 1 - safe"| AUTOAPPROVE(["Auto-approved"])
TIER -->|"Tier 2 - modify"| CLASSIFIER["Layer 4: ML Classifier"]
TIER -->|"Tier 3 - risky"| BLOCKED
CLASSIFIER -->|"predicted safe"| SANDBOX["Layer 5: Shell Sandbox"]
CLASSIFIER -->|"predicted risky"| ASK["Ask User"]
ASK -->|"approved"| SANDBOX
ASK -->|"denied"| BLOCKED
SANDBOX -->|"passes"| HOOKCHECK["Layer 6: Hook Intercept"]
SANDBOX -->|"fails"| BLOCKED
HOOKCHECK -->|"allowed"| EXEC(["Execute"])
HOOKCHECK -->|"blocked by hook"| BLOCKED
Rules merge from five sources in priority order. Higher-priority sources override lower ones.
| Priority | Source | Scope |
|---|---|---|
| 1 (highest) | Managed / Policy settings | Admin-locked, non-overridable |
| 2 | User settings (~/.claude/settings.json) | Cross-project user preferences |
| 3 | Project settings (.claude/settings.json) | Per-repo rules, checked into git |
| 4 | CLI arguments (--allow / --deny) | Single session, invocation-time |
| 5 (lowest) | Session rules (transient) | Granted interactively, not persisted |
Read-only. No file edits, no shell. Designed for exploration and planning.
Standard mode. Reads auto-approved; writes and shell prompt the user.
File edits auto-approved; shell still prompts.
ML classifier decides autonomously. User is not prompted.
All checks skipped. Intended for sandboxed CI environments only.
The context window (200K-1M tokens) is the binding resource constraint. Every agent iteration must fit within it. The system uses a five-stage compaction pipeline to shed information before calling the model, and a file-based memory system to persist knowledge across sessions.
Five stages run in sequence from cheapest to most expensive. Earlier stages execute before later ones to minimize cost.
flowchart LR
CONV["Conversation History"] --> B1["Stage 1: Budget Reduction"]
B1 -->|"trim large tool outputs"| B2["Stage 2: Snip"]
B2 -->|"drop old history blocks"| B3["Stage 3: Microcompact"]
B3 -->|"fine-grained compress"| B4["Stage 4: Context Collapse"]
B4 -->|"read-time projection"| B5["Stage 5: Auto-Compact"]
B5 -->|"model-generated summary"| FIT{"Fits in window?"}
FIT -->|"yes"| CALL["Model Call"]
FIT -->|"no"| ERR["Error - stop loop"]
B1 -.->|"enforce per-message size cap"| B1
B3 -.->|"cache-aware compression"| B3
Persistent knowledge lives in files on disk, not in the model. The model reads these files as part of context assembly at session start and during the loop.
flowchart TD
DISK["Disk-Based Memory"] --> L1["Managed Settings"]
DISK --> L2["CLAUDE.md Files"]
DISK --> L3["MEMORY.md Index"]
DISK --> L4["Session JSONL"]
DISK --> L5["Sidechain Transcripts"]
L2 --> L2A["Repo root CLAUDE.md"]
L2 --> L2B["Subdirectory CLAUDE.md"]
L2 --> L2C["Auto-memory entries"]
L2 --> L2D["Lazy nested rules"]
L3 --> L3A["Topic files on-demand"]
L3A -->|"loaded when relevant"| CTX["Context Assembly"]
L4 --> L4A["Append-only turns"]
L4A -->|"resume or fork"| CTX
L1 --> CTX
L2 --> CTX
L3 --> CTX
The system tracks 14 cache-break vectors and uses sticky latches to prevent mode toggles from invalidating the prompt cache -- a significant cost optimization given Claude API's cache pricing.
Hooks are deterministic callbacks the harness fires at fixed lifecycle points. They convert probabilistic model behavior into enforceable rules -- e.g., run the formatter after every file edit, block any shell command touching production, log every tool call for audit. The model cannot override a hook decision.
Hooks make enforcement deterministic where prompts make it probabilistic. A PreToolUse hook that exits 2 blocks the action regardless of what the model was told.
flowchart LR
SESSION_START(["SessionStart"]) --> PROMPT_SUBMIT["UserPromptSubmit"]
PROMPT_SUBMIT --> PROMPT_EXPAND["UserPromptExpansion"]
PROMPT_EXPAND --> INSTR_LOAD["InstructionsLoaded"]
INSTR_LOAD --> PRE["PreToolUse"]
PRE -->|"exit 0 - allow"| PERM["PermissionRequest"]
PRE -->|"exit 2 - block"| FEEDBACK["Inject Feedback"]
PERM -->|"granted"| EXEC_TOOL["Tool Execution"]
PERM -->|"denied"| PERM_DENIED["PermissionDenied"]
EXEC_TOOL -->|"success"| POST["PostToolUse"]
EXEC_TOOL -->|"fail"| POST_FAIL["PostToolUseFailure"]
POST --> BATCH["PostToolBatch"]
POST_FAIL --> BATCH
BATCH --> NOTIFY["Notification"]
NOTIFY --> STOP_CHECK{"Stop?"}
STOP_CHECK -->|"continue"| PRE
STOP_CHECK -->|"done"| STOP_EV["Stop"]
STOP_EV --> SESSION_END(["SessionEnd"])
STOP_CHECK -->|"error"| STOP_FAIL["StopFailure"]
| Type | Mechanism | Use case |
|---|---|---|
command | Shell subprocess, JSON via stdin/stdout | Formatters, linters, audit loggers |
prompt | LLM evaluation with injected $ARGUMENTS | Semantic rule checks, content policies |
http | HTTP POST to external URL | Remote policy servers, webhooks |
agent | Full nested agent loop | Deep verification, complex pre-flight checks |
Claude Code supports delegating work to subagents via the AgentTool. Subagents re-enter queryLoop() with an isolated context window, preventing parent context inflation. Only a text summary returns to the parent; the full subagent conversation goes to a sidechain JSONL file.
flowchart TD
PARENT["Parent Agent Loop"] -->|"AgentTool call"| SPAWN{"Spawn Mode"}
SPAWN -->|"Fork"| FORK["Fork Subagent"]
SPAWN -->|"Worktree"| WT["Worktree Subagent"]
SPAWN -->|"Teammate"| TM["Teammate Subagent"]
FORK --> FLOOP["Isolated queryLoop"]
WT --> WLOOP["Isolated queryLoop"]
TM --> TLOOP["Isolated queryLoop"]
FLOOP -->|"inherits parent system prompt"| CACHE["Shared Prompt Cache"]
WLOOP -->|"overlay filesystem"| OVERLAY["Isolated File Overlay"]
TLOOP -->|"collaborative channel"| SHARED["Shared Scratchpad"]
FLOOP -->|"summary text only"| PARENT
WLOOP -->|"summary + overlay diff"| PARENT
TLOOP -->|"summary + escalations"| PARENT
FLOOP --> SCHAIN1["Sidechain JSONL"]
WLOOP --> SCHAIN2["Sidechain JSONL"]
TLOOP --> SCHAIN3["Sidechain JSONL"]
PARENT -->|"permission bubble"| USER["User Terminal"]
Lightweight child agent. Inherits the parent's exact system prompt bytes for prompt cache reuse. Receives a restricted tool set. Changes commit before summary returns.
Isolated filesystem overlay. Write tools modify file copies; reads hit the real filesystem. Max 20 turns, 100 messages. Overlay merges to disk on acceptance. Used for speculative execution.
Collaborative channel with shared scratchpad directory. Multiple workers can coordinate. Permission requests escalate upstream to the parent terminal.
| Agent Type | Purpose | Tools |
|---|---|---|
| Explore | Codebase search and file location | Read-only subset |
| Plan | Strategy design and task decomposition | Read-only + planning tools |
| General | Multi-step implementation tasks | Full tool set |
| Guide | Feature assistance and code review | Read + comment tools |
Coordination logic in multi-agent setups lives entirely in prompts, not code. The coordinator instructs workers via natural language directives. There is no message-passing protocol; agents communicate through the shared scratchpad directory or by returning summaries.
This report synthesizes public research, community analysis, and findings from the accidental npm source map exposure (March 2026). No proprietary or confidential material was used.
| Source | Type |
|---|---|
| Dive into Claude Code - arXiv 2604.14228 | Academic paper (VILA-Lab) |
| VILA-Lab/Dive-into-Claude-Code - GitHub | Open research repo |
| 512K Lines Reveal About Claude Code - Superframeworks | Technical analysis |
| The Claude Code Source Leak - Layer5 | Engineering blog |
| Claude Code Source Leak Findings - Alex Kim | Technical blog |
| Claude Code Source Leak (Mechanics) - ClaudeFast | Technical analysis |
| Inside Claude Code's Architecture - CallSphere | Architecture deep dive |
| Claude Code Agent Harness Architecture - WaveSpeed | Architecture analysis |
| Claude Code Architecture Deep Dive - Barney | Community analysis |
| Claude Code Source Leak - VentureBeat | News coverage |
| Claude Code Hooks Complete Guide - Konishi | Hooks reference |
| Harness Engineering Guide - DEV Community | Engineering guide |
| Anthropic Accidentally Exposes Claude Code Source - InfoQ | News analysis |
| A Look Inside Claude's Leaked AI Coding Agent - Varonis | Security analysis |
Report generated 2026-07-03. Architecture described reflects findings from the March 2026 leak and community analysis. Anthropic may have changed internal implementation since then.