Reference: https://arxiv.org/pdf/2604.14228
| Principle | Values Served | Design Question | Sections |
|---|---|---|---|
| Deny-first with human escalation | Authority, Safety | Should unrecognized actions be allowed, blocked, or escalated to the human? | 5, 8, 9 |
| Graduated trust spectrum | Authority, Adaptability | Fixed permission level, or a spectrum users traverse over time? | 5 |
| Defense in depth with layered mechanisms | Safety, Authority, Reliability | Single safety boundary, or multiple overlapping ones using different techniques? | 3, 5 |
| Externalized programmable policy | Safety, Authority, Adaptability | Hardcoded policy, or externalized configs with lifecycle hooks? | 5, 6 |
| Context as scarce resource with progressive management | Reliability, Capability | What is the binding resource constraint, and how to manage it: single-pass truncation or graduated pipeline? | 4, 6, 7, 8 |
| Append-only durable state | Reliability, Authority | Mutable state, checkpoint snapshots, or append-only logs? | 4, 9 |
| Minimal scaffolding, maximal operational harness | Capability, Reliability | Invest in scaffolding-side reasoning, or operational infrastructure that lets the model reason freely? | 3, 4 |
| Values over rules | Capability, Authority | Rigid decision procedures, or contextual judgment backed by deterministic guardrails? | 3, 5, 7 |
| Composable multi-mechanism extensibility | Capability, Adaptability | One unified extension API, or layered mechanisms at different context costs? | 6 |
| Reversibility-weighted risk assessment | Capability, Safety | Same oversight for all actions, or lighter for reversible and read-only ones? | 4, 5, 8 |
| Transparent file-based configuration and memory | Adaptability, Authority | Opaque database, embedding-based retrieval, or user-visible version-controllable files? | 7 |
| Isolated subagent boundaries | Reliability, Safety, Capability | Subagents share the parent's context and permissions, or operate in isolation? | 8 |
| Graceful recovery and resilience | Reliability, Capability | Fail hard on errors, or silently recover and reserve human attention for unrecoverable situations? | 4, 5 |
- User: Submits prompts, approves permissions, reviews output.
- Interfaces: Interactive CLI, headless CLI (
claude -p), Agent SDK, and IDE/Desktop/Browser. - Agent loop:
queryLoop()async generator inquery.ts. - Permission system: Deny-first rule evaluation (
permissions.ts), auto-mode ML classifier, hook-based interception (types/hooks.ts). - Tools: Up to 54 built-in tools (19 unconditional, 35 conditional) assembled via
assembleToolPool()(tools.ts), merged with MCP-provided tools. - State & persistence: Append-only JSONL session transcripts (
sessionStorage.ts), global prompt history (history.ts), subagent sidechain files. - Execution environment: Shell execution with optional sandboxing (
shouldUseSandbox.ts), filesystem operations, web fetching, MCP server connections.
Surface layer: src/entrypoints/ (SDK entry, coreTypes.ts, controlSchemas.ts, coreSchemas.ts), src/screens/, src/components/ (ink framework).
Core layer: queryLoop() async generator (query.ts), five sequential compaction shapers (query.ts:365-453).
Safety/action layer:
- Permission system (
permissions.ts) with 7 permission modes (types/permissions.ts) - Auto-mode ML classifier (
yoloClassifier.ts) - Hook pipeline spanning 27 event types (
coreTypes.ts; output schemas intypes/hooks.ts) - Tool pool assembly via
assembleToolPool()(tools.ts) - Shell sandbox (
shouldUseSandbox.ts) - Subagent spawning via
AgentTool(AgentTool.tsx,runAgent.ts)
State layer:
getSystemContext()andgetUserContext()(context.ts) - memoizedsrc/state/- runtime application state- JSONL session transcripts at project-specific paths (
sessionStorage.ts) - Four-level instruction hierarchy (
claudemd.ts) - Sidechain transcripts (
sessionStorage.ts:247) - Resume/fork operations (
conversationRecovery.ts)
Backend layer: BashTool.tsx, PowerShellTool.tsx, src/remote/, MCP client (services/mcp/client.ts), 42 tool subdirectories in src/tools/
- Tool pre-filtering (
tools.ts): Blanket-denied tools removed from model's view before any call. - Deny-first rule evaluation (
permissions.ts): Deny rules always take precedence over allow rules. - Permission mode constraints (
types/permissions.ts): Active mode determines baseline handling. - Auto-mode classifier: ML-based classifier evaluates tool safety.
- Shell sandboxing (
shouldUseSandbox.ts): Restricts filesystem and network access. - Not restoring permissions on resume (
conversationRecovery.ts): Session-scoped permissions not restored. - Hook-based interception (
types/hooks.ts):PreToolUsehooks modify permission decisions;PermissionRequesthooks resolve decisions.
plan: Model must create plan; execution proceeds only after user approval.default: Standard interactive use. Most operations require user approval.acceptEdits: Edits within working directory and certain filesystem shell commands auto-approved.auto: ML-based classifier evaluates requests (gated byTRANSCRIPT_CLASSIFIER).dontAsk: No prompting, but deny rules still enforced.bypassPermissions: Skips most permission prompts, but safety-critical checks remain.bubble: Internal-only mode for subagent permission escalation to parent terminal.
- Budget reduction (
applyToolResultBudget()): Enforces per-message size limits on tool results, replaces oversized outputs with content references. - Snip (
snipCompactIfNeeded(), gated byHISTORY_SNIP): Lightweight trim removing older history segments. - Microcompact: Fine-grained compression, always runs time-based path, optionally cache-aware path (gated by
CACHED_MICROCOMPACT). - Context collapse (gated by
CONTEXT_COLLAPSE): Read-time projection over conversation history; summary messages live in collapse store, not REPL array. - Auto-compact: Full model-generated summary via
compactConversation()incompact.ts; fires only when context still exceeds pressure threshold after previous four shapers.
MCP servers: Primary external tool integration. Configured from project, user, local, enterprise scopes. Client supports stdio, SSE, HTTP, WebSocket, SDK, IDE-specific variants.
Plugins: Package and distribute bundles of MCP servers, skills, hooks, and commands.
Skills: Domain-specific instructions injected into context; only frontmatter descriptions stay in prompt.
Hooks: 27 hook events: tool authorization (PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest, PermissionDenied), session lifecycle (SessionStart, SessionEnd, Setup, Stop, StopFailure), user interaction (UserPromptSubmit, Elicitation, ElicitationResult), subagent coordination (SubagentStart, SubagentStop, Teammatedle, TaskCreated, TaskCompleted), context management (PreCompact, PostCompact, InstructionsLoaded, ConfigChange), workspace events (CwdChanged, FileChanged, WorktreeCreate, WorktreeRemove), notifications. Persisted hooks use four command types: command, prompt, http, agent.
- Managed memory (
/etc/claude-code/CLAUDE.md): OS-level policy for all users. - User memory (
~/claude/CLAUDE.md): Private global instructions. - Project memory (
CLAUDE.md,claude/CLAUDE.md,.claude/rules/*.mdin project roots): Instructions checked into codebase. - Local memory (
CLAUDE.local.mdin project roots): Git-ignored, private project-specific instructions.
Memory files support @include directive for modular instruction sets. Syntax variants: @path, @/relative, @~/home, @/absolute. Works in leaf text nodes only (not inside code blocks).
Built-in subagents:
- Explore: primarily read/search-oriented investigation, write/edit tools in deny-list
- Plan: creates structured plans; execution proceeds through standard permission model
- General-purpose: broadly capable, used when explicitly requested
- Claude Code Guide: onboarding and documentation assistance with own permissionMode override
- Verification: validation checks (test suites, linting)
- Statustime-setup: terminal status line configuration
Custom subagents: via .claude/agents/*.md files; YAML frontmatter specifies description, tools (allowlist), disallowedTools, model, effort, permissionMode, mcpServers, hooks, maxTurns, skills, memory scope, background flag, isolation mode.
- Worktree: Creates temporary git worktree, subagent gets its own copy of repository
- Remote (internal-only): Launches in remote Claude Code Remote environment, always background
- In-process (default): Shares filesystem with parent but operates in isolated conversation context
Permission override logic (runAgent.ts): When subagent defines permissionMode, override applied unless parent already in bypassPermissions, acceptEdits, or auto mode (those always take precedence). Async agents: cascade of canShowPermissionPrompts first, then bubble mode, then default (sync show prompts, async do not).
Transcript path: join(projectDir, ${getSessionId()}.jsonl). Three independent persistence channels:
- Session transcripts: Conversation records (user, assistant, attachment, system messages, compaction markers, filehistory snapshots, attribution snapshots, content-replacement records)
- Global prompt history:
history.jsonlat Claude configuration home directory (history.ts) - Subagent sidechains: Separate
.jsonl+.meta.jsonfiles per subagent
compact_boundary marker records headUuid, anchorUuid, tailUuid via annotateBoundaryWithPreservedSegment() (compact.ts). Resume/fork (conversationRecovery.ts, commands/branch/branch.ts) do NOT restore session-scoped permissions.
- Base tool enumeration:
getAllBaseTools()returns up to 54 tools (19 always included: BashTool, FileReadTool, AgentTool, SkillTool; 35 conditional) - Mode filtering:
getTools()applies mode-specific filtering;CLAUDE_CODE_SIMPLEmode only Bash, Read, Edit - Deny rule pre-filtering:
filterToolsByDenyRules()strips blanket-denied tools - MCP tool integration: MCP tools from
appState.mcp.toolsfiltered and merged - Deduplication: By name, built-in tools take precedence over MCP tools
- Sibling abort controller: Fires when any Bash tool errors, immediately terminating other in-flight subprocesses
- Progress-available signal: Wakes up
getRemainingResults()consumer when new output ready - Results buffered and emitted in order tools were received
- Concurrent-read, serial-write execution model
- No tool use (model produces only text content)
- Max turns (
maxTurnslimit reached) - Context overflow (API returns
prompt_too_long) - Hook intervention (
PostToolUsehook setshook_stopped_continuation) - Explicit abort (
abortControllersignal fires)
- Max output tokens escalation: Up to three recovery attempts per turn (
MAX_OUTPUT_TOKENS_RECOVERY_LIMIT = 3) - Reactive compaction (gated by
REACTIVE_COMPACT): Summarizes just enough to free space;hasAttemptedReactiveCompactflag ensures at most once per turn - Prompt-too-long handling: First attempts context collapse overflow recovery and reactive compaction
- Streaming fallback:
onStreamingFallbackcallback handles streaming API issues - Fallback model:
fallbackModelparameter enables switching to alternative model
Permission flow hooks (5):
PreToolUse: returnspermissionDecision(deny/ask),permissionDecisionReason,updatedInputPostToolUse: injectsadditionalContext, for MCP tools returnsupdatedMCPToolOutputPostToolUseFailure: injectsadditionalContextfor error-specific guidancePermissionDenied: provides retry guidance after auto-mode denialsPermissionRequest: returnsallowordenydecision
Other hook types: Session lifecycle, user interaction, subagent coordination, context management, workspace events, notifications.
Hook command types: command (shell), prompt (LLM), http, agent (agentic verifier), plus non-persistable callback.
stdio, SSE, HTTP, WebSocket, SDK, sse-ide, ws-ide
- Relevant-memory prefetch (
query.ts) - MCP instructions deltas (new or changed server instructions)
- Agent listing deltas
- Background agent task notifications
| File | Size | Responsibility |
|---|---|---|
main.tsx |
804KB | Entry point, mode dispatch, setup |
query.ts |
68KB | Core agent loop, 5 context shapers |
QueryEngine.ts |
47KB | SDK/headless conversation wrapper |
Tool.ts |
30KB | Tool interface, types, utilities |
history.ts |
14KB | Global prompt history |
mcp/client.ts |
Large | MCP client (8+ transport variants) |
compact.ts |
Large | Compaction engine |
AgentTool.tsx |
Large | Agent tool, subagent dispatch |
runAgent.ts |
Large | 21-parameter agent lifecycle |
- Always included: AgentTool, BashTool, FileReadTool, FileEditTool, FileWriteTool, SkillTool, WebFetchTool, WebSearchTool
- Environment: GlobTool/GrepTool (unless embedded), ConfigTool (internal-only), PowerShellTool (Windows)
- Feature flag: TaskCreate/Get/Update/List (todoV2), EnterWorktreeTool (worktree), TeamTools (swarms), ToolSearchTool
- Null-checked: SuggestBackgroundPRTool, WebBrowserTool, RemoteTriggerTool, MonitorTool, SleepTool
- System prompt (output style modifications,
--append-system-promptflag) - Environment info via
getSystemContext()(context.ts): git status, optional cache-breaking injection - CLAUDE.md hierarchy via
getUserContext()(context.ts) - Path-scoped rules (conditional and directory-matched rules, lazy load)
- Auto memory (contextually relevant memory entries prefetched asynchronously)
- Tool metadata (skill descriptions, MCP tool names, deferred tool definitions via ToolSearch)
- Conversation history (subject to compaction)
- Tool results (file reads, command outputs, subagent summaries)
- Compact summaries (replacing older history segments)
[boundaryMarker, ...summaryMessages, ...messagesToKeep, ...attachments, ...hookResults]
Boundary marker annotated with headUuid, anchorUuid, tailUuid via annotateBoundaryWithPreservedSegment().
Agent definition, prompts, permissions, tools, model settings, isolation, callbacks.
- SDK-level permissions from
allowedToolspreserved ("explicit permissions from the SDK consumer that should apply to all agents") - Session-level rules replaced with subagent's declared
allowedTools - When
allowedToolsnot provided (common AgentTool path), parent's session-level rules inherited without replacement
File locking rather than message broker or distributed coordination service. Tasks claimed from shared list via lock-file-based mutual exclusion. Lock files stored at predictable filesystem paths.
- Commands with >50 subcommands fall back to single generic approval prompt instead of per-subcommand deny-rule checks (Adversa.ai, 2026)
- Pre-trust initialization ordering: hooks, MCP server connections, settings file resolution run before interactive trust dialog (Donenfeld and Vanunu, 2026; CVE-2025-59536 CVSS 8.7, CVE-2026-21852 CVSS 5.3)
- Multiple CVEs exploit pre-trust initialization of hooks and MCP servers
- 1.6% of codebase constitutes AI decision logic; 98.4% operational infrastructure
- Users approve approximately 93% of permission prompts (Hughes, 2026)
- Auto-approve rates increase from ~20% at <50 sessions to >40% by 750 sessions (McCain et al., 2026)
- Sandboxing reduced permission prompt frequency by estimated 84% (Dworken and Weller-Davies, 2025)
- Agent teams consume approximately 7× tokens of standard session in plan mode (Anthropic, 2025b)
- 27% of Claude Code-assisted tasks were work not attempted without the tool (Huang et al., 2025)
- Developers in AI-assisted conditions scored 17% lower on comprehension tests (Shen and Tamkin, 2026)
- Causal analysis of Cursor adoption across 807 repositories: code complexity increased by 40.7% (He et al., 2025)
- AI tools made developers 19% slower despite perceived 20% improvement (Becker et al., 2025)
- 304,000 AI-authored commits across 6,275 repositories: ~25% of AI-introduced issues persist to latest revision (Liu et al., 2026)