---
title: "Context & System Prompts — Claude Code Internals — Vlad Arbatov"
description: "Prompt assembly, CLAUDE.md, auto-memory, git context, compression"
image: "https://arbatov.dev/share-claude.png"
---

# Context Assembly & System Prompts

## Overview

Claude Code's context assembly brings together project instructions (CLAUDE.md), automatic memory (memdir), system reminders, git context, environment information, and skill metadata into a cohesive system prompt. The system is designed to be cache-friendly while remaining responsive to dynamic changes.

---

## System Prompt Assembly (constants/prompts.ts:444-576)

### Assembly Order

**Static (Globally-Cacheable) Prefix** — shared across all users:

1. Static intro section
2. System section
3. Doing tasks section
4. Actions section
5. Using your tools section
6. Tone and style section
7. Output efficiency section

**`__SYSTEM_PROMPT_DYNAMIC_BOUNDARY__`** — cache break point

**Dynamic (Session-Specific) Content**:

8. Session-specific guidance
9. Memory section (CLAUDE.md + auto-memory)
10. Ant model override (if applicable)
11. Environment info (CWD, git status, platform)
12. Language section (if preference set)
13. Output style section (if configured)
14. MCP instructions (if servers connected)
15. Scratchpad instructions (if enabled)
16. Function result clearing section
17. Summarize tool results section
18. Token budget section (if enabled)
19. Brief section (if Kairos)

### Section Caching (constants/systemPromptSections.ts)

```typescript
systemPromptSection('name', async () => compute())  // cached
DANGEROUS_uncachedSystemPromptSection('name', () => compute(), 'reason')  // volatile
```

Cache invalidated on: `/clear`, `/compact`, memory file changes, settings changes, MCP server connect/disconnect.

---

## Context Sources

### getSystemContext() (context.ts:116-150)

Memoized context builder for system-level info:
- Git status information
- Cache-breaking content (if BREAK_CACHE_COMMAND feature enabled)
- Skipped in CCR (`CLAUDE_CODE_REMOTE`)

### getUserContext() (context.ts:155-189)

Prepares user-level context:
- CLAUDE.md file discovery and loading
- Memory file filtering for auto-injected files
- Current date
- Respects `CLAUDE_CODE_DISABLE_CLAUDE_MDS` and `--bare` mode

---

## CLAUDE.md Loading (utils/claudemd.ts)

### Discovery Order (highest priority last)

1. **Managed** (`/etc/claude-code/CLAUDE.md`) — global instructions for all users
2. **User** (`~/.claude/CLAUDE.md`) — private global instructions
3. **Project** — instructions in the codebase:
   - `CLAUDE.md` in project root
   - `.claude/CLAUDE.md` in project root
   - All `.md` files in `.claude/rules/`
4. **Local** (`CLAUDE.local.md`) — private project-specific (gitignored)

### @include Directive System (lines 336-400)

```
@path              — Relative path
@./relative/path   — Relative to including file
@~/home/path       — Home directory expansion
@/absolute/path    — Absolute path
```

- Circular references prevented via `processedPaths` set
- Non-existent files silently ignored
- Max 5 levels deep (`MAX_INCLUDE_DEPTH`)
- Ignored inside code blocks and HTML comments

### Frontmatter Paths

```yaml
---
paths:
  - src/utils/**
  - tests/integration/**
---
```

Patterns matched against file paths for conditional rule application.

### Worktree Handling (lines 859-884)

- Detects nested worktrees (when cwd is in `.claude/worktrees/`)
- Skips Project files from main repo to avoid duplication
- Still loads CLAUDE.local.md

---

## Auto-Memory System (memdir/)

### Enablement (memdir/paths.ts:30-55)

Priority chain:
1. `CLAUDE_CODE_DISABLE_AUTO_MEMORY` env var
2. `--bare` mode → disabled
3. CCR without persistent storage → disabled
4. `settings.json` `autoMemoryEnabled` → toggle
5. Default: **enabled**

### Memory Directory

Default: `~/.claude/projects/{sanitized-git-root}/memory/`

Override via:
- `CLAUDE_CODE_REMOTE_MEMORY_DIR` (CCR/Cowork)
- `autoMemoryDirectory` in settings.json

### MEMORY.md

Serves as index/entrypoint:
- Max **200 lines**
- Max **25,000 bytes**
- Can include `@path` references to topic files
- Truncated with warning if exceeded

### Memory Types (memdir/memoryTypes.ts)

| Type | Purpose | When to Save |
|------|---------|-------------|
| `user` | User role, goals, knowledge | Learn details about user profile |
| `feedback` | Work approach guidance | User corrects or confirms approach |
| `project` | Ongoing work, goals, deadlines | Learn who/what/why/when |
| `reference` | Pointers to external systems | Learn about external resources |

### What NOT to Save

- Code patterns, architecture (derivable from code)
- Git history (use git log/blame)
- Debugging solutions (fix is in the code)
- Anything in CLAUDE.md files
- Ephemeral task details

---

## Git Context (context.ts:36-111)

### Information Collected

```javascript
const [branch, mainBranch, status, log, userName] = await Promise.all([
  getBranch(),
  getDefaultBranch(),
  execFileNoThrow(gitExe(), ['--no-optional-locks', 'status', '--short']),
  execFileNoThrow(gitExe(), ['--no-optional-locks', 'log', '--oneline', '-n', '5']),
  execFileNoThrow(gitExe(), ['config', 'user.name'])
])
```

### Output Format

```
This is the git status at the start of the conversation.
Note that this status is a snapshot in time, and will not update.

Current branch: {branch}
Main branch: {mainBranch}
Git user: {userName}

Status:
{truncated_status}

Recent commits:
{last_5_commits}
```

- **Snapshot**: Captured once at session start, not updated
- **Parallel execution**: All git commands run in Promise.all
- **Truncation**: Status truncated to 2000 chars

---

## Environment Info (constants/prompts.ts:606-791)

### computeSimpleEnvInfo()

Builds environment section with:
- Primary working directory (CWD)
- Worktree detection and warning
- Is git repository: Yes/No
- Platform, Shell, OS Version
- Model name and ID
- Knowledge cutoff date
- Claude Code availability info
- Fast mode explanation

### Knowledge Cutoffs

| Model | Cutoff |
|-------|--------|
| claude-sonnet-4-6 | August 2025 |
| claude-opus-4-6 | May 2025 |
| claude-opus-4-5 | May 2025 |
| claude-haiku-4-5 | February 2025 |
| claude-opus-4 | January 2025 |
| claude-sonnet-4 | January 2025 |

---

## System Reminders

System reminders injected as `<system-reminder>` tags into:
- Tool result outputs (truncation warnings, empty file warnings)
- User messages (system-generated side questions)
- File read results (malware analysis reminders)
- Memory system (staleness warnings)

---

## Conversation Compression (services/compact/)

### Strategy Layers

1. **Snip Compaction** — keep snippets of recent history
2. **Microcompaction** — prompt cache editing
3. **Context Collapse** — project view over collapse store
4. **Autocompaction** — full compaction at ~90% token limit
5. **Reactive Compaction** — proactive compaction to reduce latency

### Token Budgets

```typescript
POST_COMPACT_MAX_FILES_TO_RESTORE = 5
POST_COMPACT_TOKEN_BUDGET = 50_000
POST_COMPACT_MAX_TOKENS_PER_FILE = 5_000
POST_COMPACT_MAX_TOKENS_PER_SKILL = 5_000
POST_COMPACT_SKILLS_TOKEN_BUDGET = 25_000
```

### Image Handling

Before compaction:
- Strips all image blocks from user messages
- Replaces with `[image]` text marker
- Also strips documents from tool_result content

---

## Skills in Context (tools/SkillTool/prompt.ts)

### Budget Allocation

- Skills get **1% of context window** (in characters)
- Per-skill description cap: 250 chars
- Default fallback: 8,000 chars for 200k context window

### Listing Format

```
- skill-name: description (up to 250 chars)
```

Truncation strategy:
1. Try full descriptions
2. If budget exceeded, truncate non-bundled skill descriptions
3. Always preserve bundled skill descriptions
4. Ultimate fallback: names only

---

## Context Injection Mechanisms

### prependUserContext() (utils/api.ts)

Inserts context dict as first user message block (CLAUDE.md content, date).

### appendSystemContext() (utils/api.ts)

Appends context dict to system prompt text (git status, cache breaker).

---

## Key Environment Variables

| Variable | Purpose |
|----------|---------|
| `CLAUDE_CODE_DISABLE_CLAUDE_MDS` | Hard-disable all CLAUDE.md files |
| `CLAUDE_CODE_SIMPLE` | `--bare` mode (minimal prompt) |
| `CLAUDE_CODE_REMOTE` | CCR session flag |
| `CLAUDE_CODE_REMOTE_MEMORY_DIR` | Override auto-memory directory |
| `CLAUDE_CODE_DISABLE_AUTO_MEMORY` | Toggle auto-memory |
| `SHELL` | Current shell for platform hints |
