# How Claude Code's agentic loop fills your context window

> Claude Code runs a gather→act→verify loop that fills context before you type. Compaction, /clear, and subagents are the official levers for what sticks.

URL: https://bartlomiejkrupa.dev/articles/claude-code-agentic-loop-context/
Published: 2026-06-30
Updated: 2026-07-29
Tags: claude-code, agentic-loop, context-window, compaction, claude-md, skills, subagents, mcp, hooks
Summary: Claude Code runs a gather→act→verify loop that fills context before you type. Compaction, /clear, and subagents are the official levers for what sticks.

Claude Code is an agentic harness: the model reasons through a **gather → act → verify** loop while tools read, edit, run, and search your project. Context starts filling before your first prompt - `CLAUDE.md`, auto memory, MCP tool names, and skill descriptions all load at startup. File reads dominate growth during the loop. Compaction, `/clear`, and subagents are the official levers for reclaiming space and controlling what survives.

## Definition

**Agentic harness** - the runtime around a language model that provides tools, context management, and an execution environment. The model plans; the harness acts.

**Agentic loop** - the three phases Claude Code cycles through on every task: gather context, take action, verify results. Phases blend together; a bug fix may loop through all three dozens of times. See [agentic loop](/notes/agentic-loop).

**Startup tax** - tokens loaded into the context window before you type your first message. You pay this on every new session. See [startup tax](/notes/startup-tax).

**MCP** - Model Context Protocol: the connector standard Claude Code uses to plug external tools and services into the loop.

## The loop and built-in tools

When you give Claude a task, it works through gather → act → verify. A question about your codebase might only need gathering. A refactor cycles through all three repeatedly. Each tool result feeds the next decision - that feedback is the loop.

Without tools, Claude can only reply with text. With them, it can act. Anthropic groups the built-in tools into five categories:

| Category | What Claude can do |
| --- | --- |
| File operations | Read files, edit code, create files, rename and reorganize |
| Search | Find files by pattern, search content with regex, explore codebases |
| Execution | Run shell commands, start servers, run tests, use git |
| Web | Search the web, fetch documentation, look up error messages |
| Code intelligence | See type errors after edits, jump to definitions, find references |

[Claude Code tools](/articles/claude-code-tools) has the full 42-tool inventory, the permission split, and per-tool behavior.

Extensions layer on top without replacing the loop: skills package workflows, MCP connects external services, hooks automate tool events, and subagents delegate work to separate windows.

## What loads before you type

A lot enters context before your first prompt. Your setup may vary, but Anthropic's documentation names these startup surfaces:

| Surface | When loaded | Notes |
| --- | --- | --- |
| System prompt | Session start | Core behavior, tool-use instructions, response formatting |
| Project-root `CLAUDE.md` | Session start | Re-injected from disk after compaction |
| Auto memory (`MEMORY.md`) | Session start | First **200 lines or 25KB**, whichever is smaller |
| MCP tool names | Session start | Full schemas deferred by default; only names load until a tool is used - see [Claude Code tools](/articles/claude-code-tools) for the token math behind that default |
| Skill descriptions | Session start | One-line index only; bodies load on invocation |
| Output style / `--append-system-prompt` | Session start | Both enter the system prompt |

The startup tax is real and continuous - `CLAUDE.md` competes with your task on every turn. Keep it lean and universal; see [keep CLAUDE.md to universal instructions](/notes/claude-md-universal-only) and [why agents ignore your CLAUDE.md](/articles/why-agents-ignore-your-claude-md).

For skills you invoke manually, set `disable-model-invocation: true` so descriptions stay out of the startup index until you run `/skill-name`. Disconnect unused MCP servers instead - only connected servers cost names in context.

## How context grows during the loop

Once the loop runs, file reads dominate. Each read stays in conversation history for every subsequent turn. A single large file keeps costing tokens for the rest of the session.

Other growth paths:

- **Path-scoped rules** - rules in `.claude/rules/` with a `paths:` frontmatter load automatically when Claude reads a matching file. You see a one-line "Loaded …" notice in the terminal; the rule content enters context silently.
- **Nested `CLAUDE.md`** - child-directory instructions load when Claude reads a file in that subtree.
- **PostToolUse hooks** - hooks can inject `additionalContext` via JSON output. That text enters Claude's context; plain stdout on exit 0 does not.

Be specific in prompts ("fix the bug in `auth.ts`") so Claude reads fewer files. For research-heavy work, delegate to a subagent instead of letting reads accumulate in the main window.

## When the loop drifts

Two complaints come up constantly in long sessions, and they are the same mechanic seen from opposite sides.

The first: somewhere around thirty exchanges in, the agent starts breaking constraints it was given at the top of the session - and patterns it established for itself. There is no warning and no error. The code just stops matching the rules, and you find out at review.

The second: right after an automatic compaction, the session behaves like a brand-new agent that has never seen the feature - usually while you are halfway through building it.

Neither is forgetting in any interesting sense:

| What it looks like | What is actually true |
| --- | --- |
| Rules held early, broken by turn 30 | The constraint is still in the transcript, but no longer near either edge of the window, competing with everything since |
| Mid-task, it acts like a new agent | The constraint is not in the transcript at all - the summary kept the plot and dropped the rules |

Both have the same fix, and it is not a bigger window. Anything that has to hold for a whole session belongs in a file that gets re-injected - project-root `CLAUDE.md`, or a `SessionStart` hook firing with `source: "compact"` - rather than in a message that gets buried or summarized.

The expensive version of this failure is a fabricated file. An agent deep in a drifted context can invent a path or a function, and once invented it becomes context for everything after it: later turns reason about the fiction as if it were the codebase, and produce a clean, plausible diff against code that does not exist. Nothing errors. The whole refactor makes sense on paper.

The tell is that it never quotes anything. Two habits catch it: require the agent to read before it writes ("quote the current implementation before you change it", or an `@` mention that puts the real file in context), and end the task with a command that fails loudly when the target is missing. A hallucinated file survives review comfortably. It does not survive the test suite.

## Compaction survival map

As context fills, Claude Code clears older tool outputs first, then summarizes the conversation if needed. Your requests and key code snippets are preserved; detailed instructions from early in the conversation may be lost. Put persistent rules in `CLAUDE.md`, not in chat history.

What survives depends on how each mechanism was loaded:

| Mechanism | After `/compact` |
| --- | --- |
| System prompt / output style | Unchanged - not part of message history |
| Project-root `CLAUDE.md`, auto memory | Re-injected from disk |
| Rules with `paths:` / nested `CLAUDE.md` | Lost until a matching file is read again |
| Skill descriptions (startup index) | Not re-injected |
| Invoked skill bodies | Re-injected - **5K tokens per skill**, **25K total**; oldest dropped first |

Path-scoped rules and nested `CLAUDE.md` files load into message history when triggered, so compaction summarizes them away. They reload the next time Claude reads a matching file. If a rule must persist across compaction, move it to project-root `CLAUDE.md` or drop the `paths:` frontmatter.

Steer what the summary keeps with a **Compact Instructions** section in `CLAUDE.md`:

```markdown
## Compact Instructions
When compacting, preserve: current task goal, files being edited, test commands, and open decisions.
Drop: exploratory reads, superseded plans, verbose tool output.
```

Or steer a single compaction from the prompt:

```bash
/compact focus on the auth flow and files under src/auth/
```

[Context engineering beats a bigger window](/articles/context-engineering-beats-a-bigger-window) covers tactics for when to compact proactively versus reset entirely.

## Subagents as context isolation

Subagents run in a **separate context window** - completely isolated from your main conversation. They load their own system prompt, `CLAUDE.md`, and MCP/skill setup, but not your conversation history or the main session's auto memory. When done, only a summary and a small metadata trailer return to the parent.

The heavy intermediate tokens - large file reads, MCP documentation, search output - never enter your window. Keeping them out entirely is what [subagent context isolation](/notes/subagent-context-isolation) means in practice.

Reach for a subagent when a task needs many files or a large doc read, but the main loop only needs the conclusion - delegation and tier-selection guidance live in the context-engineering series article linked above.

## Inspect and reset

Two commands show live state:

```bash
/context   # breakdown by category with optimization suggestions
/memory    # which CLAUDE.md and auto-memory files loaded at startup
```

Run `/clear` between unrelated tasks to reset to zero tokens instead of dragging old context along.

Flagship models in Claude Code - Fable 5.1, Fable 5, Sonnet 5 and later, Opus 4.6 and later, and Sonnet 4.6 - support a **1M-token** context window (Opus 4.6 and Sonnet 4.6 through their `[1m]` variants). Compaction works the same at the larger limit; a bigger ceiling does not remove the need to engineer what enters the window. See the sibling article for paid-plan limits and credit gates.

## Bottom line

Understand three things: the **loop** that drives every session, the **startup tax** you pay before typing, and the **survival map** that tells you what compaction keeps. Spend context deliberately - that is [context engineering](/notes/context-engineering), and it matters more than window size.

Sources:
- How Claude Code works: https://code.claude.com/docs/en/how-claude-code-works
- Explore the context window: https://code.claude.com/docs/en/context-window
- How Claude remembers your project: https://code.claude.com/docs/en/memory
- Model configuration: https://code.claude.com/docs/en/model-config
