Source Code Findings

Corrections and new discoveries from reading the Claude Code source code directly. All file paths reference /home/visar/Documents/wip/archived/claude-code-source-code/.

Contents

Report Corrections

The original report (based on web research) had several inaccuracies. Here's what the source code actually shows:

Claim in Original ReportSource Code Reality
CLAUDE.md is injected as a "user message after the system prompt" Wrong CLAUDE.md is injected as a system prompt context section via getUserContext(), not a user message. (src/context.ts:150-189)
Memory selection agent is "a sub-agent" Imprecise It's specifically Claude Sonnet running with a dedicated system prompt. (src/memdir/findRelevantMemories.ts:18)
Truncated MEMORY.md is "silently dropped with no indication" Wrong A WARNING is appended explaining which cap fired (lines vs bytes). (src/memdir/memdir.ts:92-100)
The type field in frontmatter influences selection Misleading Type is used for display only in the manifest ([feedback] filename). It does NOT filter or influence the Sonnet selector's decision. (src/memdir/memoryScan.ts)
CLAUDE.md has a recommended 200-line limit Not enforced There is NO size enforcement in the source. A 40KB flag exists but only for /doctor command warnings. Files of any size are loaded in full. (src/utils/claudemd.ts:91)
Topic files are "never loaded at startup" Imprecise Topic files are surfaced per-query by the Sonnet selector, with per-file limits (200 lines / 4KB) and a session budget (60KB total). (src/utils/attachments.ts:269-288)
Memory extraction is triggered "at end of each query loop" Mostly correct It runs as a forked agent with restricted tools. Throttled by feature gate tengu_bramble_lintel (default: every 1 turn). Skipped if main agent already wrote to memory. (src/services/extractMemories/extractMemories.ts:296)
Session memory is the same as auto-memory Wrong Session memory is a separate system: periodic background extraction into .session/memory.md, triggered by token thresholds (~30K init, ~20K between updates). Distinct from auto-memory topic files. (src/services/SessionMemory/sessionMemory.ts)
Auto-compact triggers at some percentage Imprecise Auto-compact triggers when token usage ≥ (effective window - 13,000 tokens). Circuit breaker stops after 3 consecutive failures. (src/services/compact/autoCompact.ts:33-150)

Hard-Coded Constants & Limits

ConstantValueFilePurpose
MAX_ENTRYPOINT_LINES200memdir.ts:35MEMORY.md line cap
MAX_ENTRYPOINT_BYTES25,000memdir.ts:38MEMORY.md byte cap
MAX_MEMORY_FILES200memoryScan.ts:21Files scanned in memory directory
MAX_MEMORY_LINES (recall)200attachments.ts:269Per-file lines when surfaced
MAX_MEMORY_BYTES (recall)4,096attachments.ts:277Per-file bytes when surfaced (~4KB)
MAX_SESSION_BYTES61,440attachments.ts:288Total memory bytes per session (60KB)
MAX_MEMORY_CHARACTER_COUNT40,000claudemd.ts:91CLAUDE.md "large file" warning flag (not enforced)
MAX_INCLUDE_DEPTH5claudemd.ts:537@import recursion depth
FRONTMATTER_MAX_LINES30memoryScan.ts:22Frontmatter scan depth
HOLDER_STALE_MS3,600,000consolidationLock.ts:19Dream lock stale threshold (1 hour)
AUTOCOMPACT_BUFFER_TOKENS13,000autoCompact.tsBuffer before auto-compact triggers
MAX_MCP_DESCRIPTION_LENGTH2,048mcp/client.tsMCP tool description character cap
Memory selection max files5findRelevantMemories.ts:20Hard-coded max in Sonnet prompt
Dream min hours24autoDream.ts:64Default time gate
Dream min sessions5autoDream.ts:65Default session gate

Complete Memory Data Flow

1
System Prompt Load

buildMemoryPrompt() reads MEMORY.md, applies dual truncation (200 lines / 25KB), appends warning if truncated. Injected into system prompt via getUserContext().

2
Per-Query Recall

User input → findRelevantMemories() (Sonnet ranks up to 5 files from filename + description) → readMemoriesForSurfacing() (truncate to 200 lines / 4KB each, 60KB session budget) → injected as <system-reminder> attachments.

3
Memory Saving (end of turn)

executeExtractMemories() forks agent with restricted tools → pre-injects memory manifest ([type] filename (timestamp): description) → extraction agent updates topic files + MEMORY.md.

4
Dream Consolidation (background)

Time gate (24h) + session gate (5 sessions) + lock acquire → buildConsolidationPrompt() → forked dream agent reviews logs, merges into topic files, prunes MEMORY.md.

5
Session Memory (background, separate)

Periodic forked sub-agent extracts key session info into .session/memory.md. Triggered at ~30K token init, ~20K between updates. Does not interrupt main conversation.

System Prompt Assembly Order

Source: src/services/api/claude.ts:3213-3237

  1. Attribution header (billing)
  2. CLI system prompt prefix
  3. Introduction section
  4. System section (tools, compression, hooks)
  5. Doing tasks section
  6. Tools section (per-tool instructions)
  7. SYSTEM_PROMPT_DYNAMIC_BOUNDARY ← cache scope split point
  8. User/project context (working directory, CLAUDE.md, memory)
  9. Output style (if configured)
  10. Language preference (if set)
  11. MCP instructions (if connected)
  12. Append system prompt (if set)
Cache scope split Content before the boundary: scope: 'global' (shared across all users, 1P Anthropic only). Content after: scope: 'org' or null (dynamic, session-specific). This means your CLAUDE.md and memory content are in the non-cacheable zone — they're re-processed every API call.

Feature Gates & Settings

GatePurposeDefault
KAIROSDaily log mode (perpetual sessions)Feature flag
TEAMMEMTeam memory (shared via VCS)Feature flag
tengu_passport_quailEnable memory extractionFeature flag
tengu_bramble_lintelThrottle extraction (every N turns)1 (every turn)
tengu_moth_copseSkip MEMORY.md index in extraction promptFeature flag
tengu_onyx_ploverDream scheduling thresholds{ enabled, minHours, minSessions }
tengu_paper_halyardSkip project-level CLAUDE.mdFeature flag
MCP_SKILLSEnable MCP skill loadingFeature flag

Settings Precedence (source-verified)

From src/utils/settings/constants.ts:7-22:

  1. userSettings: ~/.claude/settings.json
  2. projectSettings: .claude/settings.json (shared)
  3. localSettings: .claude/settings.local.json (gitignored)
  4. flagSettings: --settings CLI flag + inline SDK settings
  5. policySettings: managed (remote API → MDM → managed-settings.json → drop-in fragments)

Arrays are concatenated and deduplicated across scopes. Scalars: source overwrites target. Objects: deep merged.

Environment Variables for Hooks

VariableAvailable InValue
CLAUDE_PROJECT_DIRAll hooksReal repo root (stable, never worktree-relative)
CLAUDE_ENV_FILESessionStart, CwdChanged, FileChangedPath to temp .sh file for persisting exports
CLAUDE_PLUGIN_ROOTPlugin/skill hooksPlugin installation directory

Key Source Files

AreaFileLines
Memory loading & truncationsrc/memdir/memdir.ts35-316
Memory selection (Sonnet)src/memdir/findRelevantMemories.ts18-141
Memory frontmatter parsingsrc/memdir/memoryScan.ts35-77
Memory type taxonomysrc/memdir/memoryTypes.ts1-272
Memory surfacing limitssrc/utils/attachments.ts269-2321
Memory extraction (forked agent)src/services/extractMemories/extractMemories.ts296-616
Dream consolidationsrc/services/autoDream/autoDream.ts122-325
Dream promptsrc/services/autoDream/consolidationPrompt.ts10-65
Dream locksrc/services/autoDream/consolidationLock.ts21-84
Session memorysrc/services/SessionMemory/sessionMemory.ts1-496
CLAUDE.md discovery & loadingsrc/utils/claudemd.ts0-1397
Rules frontmatter parsingsrc/utils/frontmatterParser.ts9-51
Context injectionsrc/context.ts150-189
System prompt constructionsrc/utils/systemPrompt.ts29-123
Prompt cache detectionsrc/services/api/promptCacheBreakDetection.ts1-728
Auto-compactsrc/services/compact/autoCompact.ts33-150
Hook execution (4700+ lines)src/utils/hooks.ts747-4700+
Hook events enumsrc/entrypoints/sdk/coreTypes.ts25-53
Hook output schemassrc/types/hooks.ts50-165
Settings schemasrc/utils/settings/types.ts255-949+
Settings mergingsrc/utils/settings/settings.ts538-547
MCP config loadingsrc/services/mcp/config.ts1258-1290
Permission rule parsingsrc/utils/permissions/permissionRuleParser.ts81-133