| name | dive-into-claude-code-analysis |
| description | Analyze and apply architectural patterns from Claude Code's system design for building AI agent systems |
| triggers | ["how does Claude Code architecture work","show me Claude Code design patterns","apply Claude Code safety principles","implement agent loop like Claude Code","use Claude Code permission system design","analyze AI agent architecture patterns","design agent system with Claude Code principles","implement defense in depth for AI agents"] |
Dive into Claude Code Analysis
Skill by ara.so — Claude Code Skills collection.
This skill provides expertise in understanding and applying the architectural patterns, design principles, and implementation strategies documented in the VILA-Lab "Dive into Claude Code" analysis — a comprehensive study of Claude Code v2.1.88 (~512K lines of TypeScript across 1,884 files).
What This Project Provides
The Dive into Claude Code project is a systematic analysis that reveals:
- Architectural blueprint: How Claude Code structures its 98.4% deterministic infrastructure around 1.6% AI decision logic
- Design principles: 5 core values → 13 design principles → concrete implementation patterns
- Safety patterns: 7-layer defense-in-depth permission system with graduated trust spectrum
- Context management: 5-stage compaction pipeline for token budget management
- Agent loop implementation: ReAct-pattern while-loop with streaming execution and graceful recovery
- Extensibility mechanisms: 4 graduated extension points (hooks, skills, plugins, MCP)
Installation
git clone https://github.com/VILA-Lab/Dive-into-Claude-Code.git
cd Dive-into-Claude-Code
open paper/Dive_into_Claude_Code.pdf
Core Architecture Patterns
The 98/2 Split
Claude Code demonstrates that production AI agents are primarily infrastructure:
- 1.6%: AI decision logic (LLM reasoning, tool selection)
- 98.4%: Deterministic harness (permissions, context management, recovery, routing)
Key insight: The agent loop is a simple while-loop. The engineering complexity lives in the systems around it.
Five Architectural Layers
┌─────────────────────────────────────────┐
│ User & Interfaces (CLI, SDK, IDE) │
├─────────────────────────────────────────┤
│ Agent Loop (queryLoop) │
│ • Context Assembly │
│ • Model Invocation │
│ • Tool Dispatch │
├─────────────────────────────────────────┤
│ Permission System (7 modes, deny-first) │
├─────────────────────────────────────────┤
│ Tools & Extensions (54 base + MCP) │
├─────────────────────────────────────────┤
│ State & Execution Environment │
└─────────────────────────────────────────┘
Design Principles Framework
The 5 Core Values
enum CoreValue {
HumanDecisionAuthority = "human-control",
SafetySecurityPrivacy = "safe-by-default",
ReliableExecution = "does-what-meant",
CapabilityAmplification = "unix-utility-philosophy",
ContextualAdaptability = "evolves-with-trust"
}
The 13 Design Principles
Apply these when designing your AI agent:
- Deny-first with human escalation: Unrecognized actions → escalate to human
- Graduated trust spectrum: 7 permission modes users traverse over time
- Defense in depth: Multiple overlapping safety layers
- Externalized programmable policy: Configs with lifecycle hooks
- Context as scarce resource: 5-stage graduated compaction pipeline
- Append-only durable state: Immutable history logs
- Minimal scaffolding, maximal harness: Invest in operational infrastructure
- Values over rules: Contextual judgment + deterministic guardrails
- Composable multi-mechanism extensibility: 4 extension layers at different costs
- Reversibility-weighted risk assessment: Lighter oversight for reversible actions
- Transparent file-based config: User-visible files over opaque DBs
- Isolated subagent boundaries: Separate context/permissions per subagent
- Graceful recovery and resilience: Silent recovery over hard failures
Implementing the Agent Loop Pattern
Basic ReAct Loop Structure
async function* agentLoop(
initialPrompt: string,
context: AgentContext,
permissions: PermissionSystem
): AsyncGenerator<AgentEvent> {
let turnCount = 0;
const MAX_TURNS = 25;
const conversationHistory: Message[] = [];
while (turnCount < MAX_TURNS) {
const assembledContext = await assembleContext(
conversationHistory,
context.workspaceState,
context.availableTools
);
const compactedContext = await compactIfNeeded(
assembledContext,
context.tokenBudget
);
const modelResponse = await callModel({
messages: compactedContext.messages,
tools: compactedContext.availableTools,
streaming: true
});
const toolCalls = extractToolCalls(modelResponse);
if (toolCalls.length === 0) {
yield { type: 'complete', message: modelResponse.content };
break;
}
const authorizedCalls = await permissions.authorize(toolCalls);
for await (const toolResult of executeTools(authorizedCalls)) {
yield { type: 'tool_result', data: toolResult };
conversationHistory.push({
role: 'tool',
content: toolResult.output
});
}
turnCount++;
}
}
Five-Stage Compaction Pipeline
async function compactIfNeeded(
context: AssembledContext,
tokenBudget: number
): Promise<CompactedContext> {
let current = context;
const currentTokens = estimateTokens(current);
if (currentTokens <= tokenBudget) {
return current;
}
current = await budgetReduction(current, tokenBudget);
if (estimateTokens(current) <= tokenBudget) return current;
current = await snipLongMessages(current, tokenBudget);
if (estimateTokens(current) <= tokenBudget) return current;
current = await microcompact(current);
if (estimateTokens(current) <= tokenBudget) return current;
current = await contextCollapse(current);
if (estimateTokens(current) <= tokenBudget) return current;
current = await autoCompact(current, tokenBudget);
return current;
}
Permission System Implementation
Seven Permission Modes (Graduated Trust)
enum PermissionMode {
Plan = "plan",
Default = "default",
AcceptEdits = "acceptEdits",
Auto = "auto",
DontAsk = "dontAsk",
BypassPermissions = "bypassPermissions",
Bubble = "bubble"
}
Deny-First Authorization Pipeline
interface PermissionRule {
scope: 'global' | 'directory' | 'file';
pattern: string;
decision: 'allow' | 'deny' | 'ask';
priority: number;
}
class DenyFirstPermissionSystem {
async authorize(toolCalls: ToolCall[]): Promise<ToolCall[]> {
const authorized: ToolCall[] = [];
for (const call of toolCalls) {
if (this.isDeniedTool(call.tool)) {
continue;
}
const decision = this.evaluateRules(call);
if (decision === 'deny') {
continue;
}
if (decision === 'ask') {
const userApproved = await this.promptUser(call);
if (!userApproved) continue;
}
const hookResult = await this.runPreToolUseHooks(call);
if (hookResult.blocked) {
continue;
}
authorized.push(call);
}
return authorized;
}
private evaluateRules(call: ToolCall): 'allow' | 'deny' | 'ask' {
const matchingRules = this.rules
.filter(rule => this.matches(rule, call))
.sort((a, b) => b.priority - a.priority);
const denyRule = matchingRules.find(r => r.decision === 'deny');
if (denyRule) return 'deny';
const allowRule = matchingRules.find(r => r.decision === 'allow');
if (allowRule) return 'allow';
return 'ask';
}
}
Seven Independent Safety Layers
class DefenseInDepth {
async executeTool(call: ToolCall, context: ExecutionContext): Promise<ToolResult> {
await this.runHooks('PreToolUse', call);
const permissionDecision = await this.permissions.authorize([call]);
if (permissionDecision.length === 0) {
throw new Error('Permission denied');
}
if (context.mode === PermissionMode.Auto) {
const classifierResult = await this.classifier.evaluate(call);
if (!classifierResult.safe) {
const userOverride = await this.promptUser(call);
if (!userOverride) throw new Error('Classifier rejected');
}
}
const risk = this.assessReversibility(call);
if (risk === 'irreversible' && !call.userApproved) {
throw new Error('Irreversible action requires explicit approval');
}
const result = await this.executeWithLimits(call, {
timeout: 30000,
maxMemory: 512 * 1024 * 1024,
maxFileSize: 10 * 1024 * 1024
});
await this.runHooks('PostToolUse', call, result);
return result;
}
}
Extensibility Patterns
Four Graduated Extension Mechanisms
interface Hook {
event: HookEvent;
handler: string | Function;
blocking?: boolean;
}
const securityHook: Hook = {
event: 'PreToolUse',
handler: async (call: ToolCall) => {
if (call.tool === 'execute_command' && call.args.command.includes('rm -rf')) {
return { allow: false, reason: 'Dangerous command blocked' };
}
},
blocking: true
};
interface Skill {
name: string;
description: string;
triggers: string[];
content: string;
}
interface PluginManifest {
name: string;
components: {
commands?: CommandDefinition[];
agents?: AgentDefinition[];
skills?: Skill[];
hooks?: Hook[];
mcpServers?: MCPServerConfig[];
settings?: Setting[];
};
}
interface MCPServerConfig {
name: string;
command: string;
args?: string[];
env?: Record<string, string>;
}
Tool Pool Assembly
async function assembleToolPool(context: AgentContext): Promise<Tool[]> {
let tools = [...BASE_TOOLS];
tools = filterByMode(tools, context.mode);
tools = tools.filter(tool => !isDenied(tool, context.permissions));
const mcpTools = await loadMCPTools(context.mcpServers);
tools.push(...mcpTools);
tools = deduplicateTools(tools);
return tools;
}
Session Persistence Pattern
Append-Only State Management
interface SessionState {
id: string;
createdAt: number;
events: SessionEvent[];
metadata: {
workspaceRoot: string;
permissionMode: PermissionMode;
trustLevel: number;
};
}
class SessionPersistence {
async appendEvent(sessionId: string, event: SessionEvent): Promise<void> {
const session = await this.loadSession(sessionId);
session.events.push({
...event,
timestamp: Date.now(),
sequenceNumber: session.events.length
});
await this.saveSession(session);
}
async replaySession(sessionId: string): Promise<AgentContext> {
const session = await this.loadSession(sessionId);
let context = this.createInitialContext(session.metadata);
for (const event of session.events) {
context = await this.applyEvent(context, event);
}
return context;
}
}
Configuration Patterns
Transparent File-Based Config
interface ClaudeConfig {
permissionMode: PermissionMode;
customInstructions?: string;
deniedTools?: string[];
allowedDirectories?: string[];
hooks?: Hook[];
mcpServers?: MCPServerConfig[];
}
async function loadConfig(workspacePath: string): Promise<ClaudeConfig> {
const configs: ClaudeConfig[] = [];
const homeClaude = await loadIfExists('~/.claude/CLAUDE.md');
if (homeClaude) configs.push(homeClaude);
const workspaceClaude = await loadIfExists(path.join(workspacePath, 'CLAUDE.md'));
if (workspaceClaude) configs.push(workspaceClaude);
const configJson = await loadIfExists(path.join(workspacePath, '.claude/config.json'));
if (configJson) configs.push(configJson);
return mergeConfigs(configs);
}
Subagent Delegation Pattern
Isolated Context Boundaries
interface SubagentConfig {
isolatedContext: boolean;
inheritPermissions: boolean;
parentVisibility: 'none' | 'summary' | 'full';
}
async function delegateToSubagent(
task: string,
parentContext: AgentContext
): Promise<SubagentResult> {
const subagentContext: AgentContext = {
workspaceRoot: parentContext.workspaceRoot,
permissionMode: PermissionMode.Default,
conversationHistory: [],
availableTools: assembleToolPool({ }),
tokenBudget: parentContext.tokenBudget,
parentSessionId: null
};
const result = await runAgentLoop(task, subagentContext);
return {
summary: result.summary,
outcome: result.outcome,
};
}
Graceful Recovery Patterns
Five Recovery Strategies
class RecoverySystem {
async executeWithRecovery(call: ToolCall): Promise<ToolResult> {
try {
return await this.execute(call);
} catch (error) {
if (error.code === 'OUTPUT_TOO_LONG') {
return await this.retryWithIncreasedTokens(call, {
attempt: 1,
maxAttempts: 3,
tokenMultiplier: 2
});
}
if (error.code === 'CONTEXT_TOO_LONG') {
const compacted = await this.compactContext();
return await this.execute(call);
}
if (error.code === 'STREAMING_FAILED') {
return await this.executeNonStreaming(call);
}
if (error.code === 'MODEL_UNAVAILABLE') {
return await this.executeWithFallbackModel(call);
}
if (error.code === 'TOOL_UNAVAILABLE') {
return {
success: false,
message: `Tool ${call.tool} unavailable, continuing with reduced capabilities`
};
}
throw error;
}
}
}
Common Patterns from the Analysis
Pattern: Context Assembly with Hooks
async function assemble(context: AgentContext): Promise<AssembledContext> {
await runHooks('PreContextAssembly', context);
let assembled = {
messages: [...context.conversationHistory],
tools: await assembleToolPool(context),
systemPrompt: await loadSystemPrompt(context)
};
const customInstructions = await loadCustomInstructions(context.workspaceRoot);
if (customInstructions) {
assembled.systemPrompt += '\n\n' + customInstructions;
}
const triggeredSkills = await findTriggeredSkills(
context.lastUserMessage,
context.availableSkills
);
for (const skill of triggeredSkills) {
assembled.messages.push({
role: 'system',
content: skill.content
});
}
assembled = await runHooks('PostContextAssembly', assembled);
return assembled;
}
Pattern: Streaming Tool Execution
async function* streamingToolExecutor(
toolCalls: ToolCall[],
executor: ToolExecutor
): AsyncGenerator<ToolResult> {
const { concurrent, exclusive } = classifyTools(toolCalls);
const concurrentPromises = concurrent.map(call => executor.execute(call));
for await (const result of yieldAsCompleted(concurrentPromises)) {
yield result;
}
for (const call of exclusive) {
const result = await executor.execute(call);
yield result;
}
}
function classifyTools(calls: ToolCall[]): { concurrent: ToolCall[], exclusive: ToolCall[] } {
const concurrent: ToolCall[] = [];
const exclusive: ToolCall[] = [];
for (const call of calls) {
if (['write_file', 'execute_command', 'apply_diff'].includes(call.tool)) {
exclusive.push(call);
} else {
concurrent.push(call);
}
}
return { concurrent, exclusive };
}
Pattern: Auto-Mode Classifier
interface ClassifierResult {
safe: boolean;
reasoning: string;
confidence: number;
}
async function classifyToolCall(call: ToolCall): Promise<ClassifierResult> {
if (isTriviallyReversible(call)) {
return { safe: true, reasoning: 'Read-only operation', confidence: 1.0 };
}
if (isObviouslyDangerous(call)) {
return { safe: false, reasoning: 'Irreversible system modification', confidence: 1.0 };
}
const prompt = `
Analyze this tool call for safety:
Tool: ${call.tool}
Arguments: ${JSON.stringify(call.args, null, 2)}
Context: ${call.context}
Consider:
1. Is this operation reversible?
2. Does it modify system-critical files?
3. Could it leak sensitive data?
4. Is the scope appropriate for the task?
Think step-by-step, then answer: SAFE or UNSAFE
`;
const response = await callClassifierModel(prompt);
return {
safe: response.includes('SAFE') && !response.includes('UNSAFE'),
reasoning: response,
confidence: extractConfidence(response)
};
}
Security Considerations
Pre-Trust Execution Window (CVE Pattern)
async function initializeWorkspace() {
await loadMCPServers();
await runHooks('WorkspaceInit');
await promptForTrust();
}
async function initializeWorkspace() {
await promptForTrust();
if (trusted) {
await loadMCPServers();
await runHooks('WorkspaceInit');
}
}
Shared Failure Modes in Defense-in-Depth
async function analyzeCommand(command: string): Promise<SecurityAnalysis> {
const subcommands = parseSubcommands(command);
if (subcommands.length > 50) {
return {
analyzed: false,
reason: 'Command too complex for analysis',
fallbackToPermissionMode: true
};
}
return await fullSecurityAnalysis(command);
}
Troubleshooting
Context Overflow Despite Compaction
async function debugContextOverflow(context: AssembledContext) {
console.log('Token breakdown:');
console.log(' System prompt:', estimateTokens(context.systemPrompt));
console.log(' Conversation:', estimateTokens(context.messages));
console.log(' Tools:', estimateTokens(context.tools));
const largeMessages = context.messages.filter(m =>
estimateTokens(m.content) > 10000
);
if (largeMessages.length > 0) {
console.log('Large messages detected - consider manual snipping');
}
if (!context.compactionMetadata) {
console.log('WARNING: Compaction metadata missing - pipeline may not have run');
}
}
Permission Denied Despite Allow Rules
function debugPermissionDenial(call: ToolCall, rules: PermissionRule[]) {
const matchingRules = rules.filter(r => matches(r, call));
console.log(`Matching rules for ${call.tool}:`);
matchingRules.forEach(rule => {
console.log(` [${rule.decision}] ${rule.scope}:${rule.pattern} (priority: ${rule.priority})`);
});
const denyRule = matchingRules.find(r => r.decision === 'deny');
if (denyRule) {
console.log(`\n❌ DENIED by rule: ${denyRule.pattern}`);
console.log(' Deny-first policy means this overrides all allow rules');
}
}
Subagent Not Inheriting Expected Behavior
function debugSubagentIsolation() {
console.log('Subagent isolation checklist:');
console.log(' ❌ Does NOT inherit parent permissions');
console.log(' ❌ Does NOT see parent conversation history');
console.log(' ❌ Does NOT share parent context');
console.log(' ✅ DOES start at default permission mode');
console.log(' ✅ DOES get fresh tool pool');
console.log('\nIf you need shared context, use Skills instead of Subagents');
}
Further Reading
- Full Paper: arXiv:2604.14228
- Architecture Deep Dive:
docs/architecture.md in repo
- Design Guide:
docs/build-your-own-agent.md
- Cross-System Comparison: Claude Code vs OpenClaw vs Hermes-Agent analysis
- Community Projects: Curated list of related research and implementations
Key Takeaways for Agent Builders
- Invest in infrastructure, not scaffolding: The 98/2 split is intentional
- Context is your bottleneck: Plan your compaction strategy early
- Deny-first prevents surprises: Explicit allow lists scale better than deny lists
- Defense-in-depth shares failure modes: Test your safety layers under degraded conditions
- Isolated subagents prevent permission escalation: Never share context/permissions
- Append-only state enables time-travel debugging: Make history immutable
- Hooks inject at zero context cost: Use them for cross-cutting concerns
- Graduated trust beats binary trust: Users traverse a spectrum over time
License: CC-BY-NC-SA-4.0 (per upstream project)
Repository: https://github.com/VILA-Lab/Dive-into-Claude-Code