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/.
The original report (based on web research) had several inaccuracies. Here's what the source code actually shows:
| Claim in Original Report | Source 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) |
| Constant | Value | File | Purpose |
|---|---|---|---|
MAX_ENTRYPOINT_LINES | 200 | memdir.ts:35 | MEMORY.md line cap |
MAX_ENTRYPOINT_BYTES | 25,000 | memdir.ts:38 | MEMORY.md byte cap |
MAX_MEMORY_FILES | 200 | memoryScan.ts:21 | Files scanned in memory directory |
MAX_MEMORY_LINES (recall) | 200 | attachments.ts:269 | Per-file lines when surfaced |
MAX_MEMORY_BYTES (recall) | 4,096 | attachments.ts:277 | Per-file bytes when surfaced (~4KB) |
MAX_SESSION_BYTES | 61,440 | attachments.ts:288 | Total memory bytes per session (60KB) |
MAX_MEMORY_CHARACTER_COUNT | 40,000 | claudemd.ts:91 | CLAUDE.md "large file" warning flag (not enforced) |
MAX_INCLUDE_DEPTH | 5 | claudemd.ts:537 | @import recursion depth |
FRONTMATTER_MAX_LINES | 30 | memoryScan.ts:22 | Frontmatter scan depth |
HOLDER_STALE_MS | 3,600,000 | consolidationLock.ts:19 | Dream lock stale threshold (1 hour) |
AUTOCOMPACT_BUFFER_TOKENS | 13,000 | autoCompact.ts | Buffer before auto-compact triggers |
MAX_MCP_DESCRIPTION_LENGTH | 2,048 | mcp/client.ts | MCP tool description character cap |
| Memory selection max files | 5 | findRelevantMemories.ts:20 | Hard-coded max in Sonnet prompt |
| Dream min hours | 24 | autoDream.ts:64 | Default time gate |
| Dream min sessions | 5 | autoDream.ts:65 | Default session gate |
buildMemoryPrompt() reads MEMORY.md, applies dual truncation (200 lines / 25KB), appends warning if truncated. Injected into system prompt via getUserContext().
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.
executeExtractMemories() forks agent with restricted tools → pre-injects memory manifest ([type] filename (timestamp): description) → extraction agent updates topic files + MEMORY.md.
Time gate (24h) + session gate (5 sessions) + lock acquire → buildConsolidationPrompt() → forked dream agent reviews logs, merges into topic files, prunes MEMORY.md.
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.
Source: src/services/api/claude.ts:3213-3237
SYSTEM_PROMPT_DYNAMIC_BOUNDARY ← cache scope split pointscope: '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.
| Gate | Purpose | Default |
|---|---|---|
KAIROS | Daily log mode (perpetual sessions) | Feature flag |
TEAMMEM | Team memory (shared via VCS) | Feature flag |
tengu_passport_quail | Enable memory extraction | Feature flag |
tengu_bramble_lintel | Throttle extraction (every N turns) | 1 (every turn) |
tengu_moth_copse | Skip MEMORY.md index in extraction prompt | Feature flag |
tengu_onyx_plover | Dream scheduling thresholds | { enabled, minHours, minSessions } |
tengu_paper_halyard | Skip project-level CLAUDE.md | Feature flag |
MCP_SKILLS | Enable MCP skill loading | Feature flag |
From src/utils/settings/constants.ts:7-22:
userSettings: ~/.claude/settings.jsonprojectSettings: .claude/settings.json (shared)localSettings: .claude/settings.local.json (gitignored)flagSettings: --settings CLI flag + inline SDK settingspolicySettings: managed (remote API → MDM → managed-settings.json → drop-in fragments)Arrays are concatenated and deduplicated across scopes. Scalars: source overwrites target. Objects: deep merged.
| Variable | Available In | Value |
|---|---|---|
CLAUDE_PROJECT_DIR | All hooks | Real repo root (stable, never worktree-relative) |
CLAUDE_ENV_FILE | SessionStart, CwdChanged, FileChanged | Path to temp .sh file for persisting exports |
CLAUDE_PLUGIN_ROOT | Plugin/skill hooks | Plugin installation directory |
| Area | File | Lines |
|---|---|---|
| Memory loading & truncation | src/memdir/memdir.ts | 35-316 |
| Memory selection (Sonnet) | src/memdir/findRelevantMemories.ts | 18-141 |
| Memory frontmatter parsing | src/memdir/memoryScan.ts | 35-77 |
| Memory type taxonomy | src/memdir/memoryTypes.ts | 1-272 |
| Memory surfacing limits | src/utils/attachments.ts | 269-2321 |
| Memory extraction (forked agent) | src/services/extractMemories/extractMemories.ts | 296-616 |
| Dream consolidation | src/services/autoDream/autoDream.ts | 122-325 |
| Dream prompt | src/services/autoDream/consolidationPrompt.ts | 10-65 |
| Dream lock | src/services/autoDream/consolidationLock.ts | 21-84 |
| Session memory | src/services/SessionMemory/sessionMemory.ts | 1-496 |
| CLAUDE.md discovery & loading | src/utils/claudemd.ts | 0-1397 |
| Rules frontmatter parsing | src/utils/frontmatterParser.ts | 9-51 |
| Context injection | src/context.ts | 150-189 |
| System prompt construction | src/utils/systemPrompt.ts | 29-123 |
| Prompt cache detection | src/services/api/promptCacheBreakDetection.ts | 1-728 |
| Auto-compact | src/services/compact/autoCompact.ts | 33-150 |
| Hook execution (4700+ lines) | src/utils/hooks.ts | 747-4700+ |
| Hook events enum | src/entrypoints/sdk/coreTypes.ts | 25-53 |
| Hook output schemas | src/types/hooks.ts | 50-165 |
| Settings schema | src/utils/settings/types.ts | 255-949+ |
| Settings merging | src/utils/settings/settings.ts | 538-547 |
| MCP config loading | src/services/mcp/config.ts | 1258-1290 |
| Permission rule parsing | src/utils/permissions/permissionRuleParser.ts | 81-133 |