Progressive Context Building
The layered documentation problem
Module 2 introduced the CLAUDE.md hierarchy: enterprise, project, rules directory, user. Legacy codebases break this neat model.
A monorepo with fifteen services cannot have one CLAUDE.md that covers everything. A project that evolved through multiple teams has different conventions in different areas. A system assembled from acquisitions contains code written under conflicting standards.
The answer is progressive context building: start minimal at the root, add detail in subdirectories, and let the agent load only what it needs for the current task. You stay within the instruction budget while giving targeted guidance where work actually happens.
The root-to-leaf architecture
Claude Code discovers CLAUDE.md files by traversing upward from the current working directory at startup, then loads subdirectory files on-demand when accessing files in those paths. You can exploit this behavior.
project/
├── CLAUDE.md # Global: 30-50 lines
├── packages/
│ ├── api/
│ │ └── CLAUDE.md # API-specific: 20-40 lines
│ ├── web/
│ │ └── CLAUDE.md # Web-specific: 20-40 lines
│ └── shared/
│ └── CLAUDE.md # Shared library rules: 15-30 linesRoot CLAUDE.md contains what every task needs:
- Project purpose (one sentence)
- Primary tech stack
- Essential commands (build, test, lint)
- Global prohibitions
- Pointers to subdirectory documentation
Subdirectory CLAUDE.md files contain context specific to that subtree:
- Local conventions that differ from root
- Service-specific commands
- Domain-specific gotchas
- Integration points with other services
Do not repeat root-level content in subdirectory files.
When the agent works in packages/api/, it has already loaded the root CLAUDE.md.
Duplicating content wastes instruction budget and creates maintenance headaches when root content changes.
Content distribution strategy
Each layer has a distinct job. Putting the wrong content at the wrong layer either bloats files or leaves agents without information they need.
| Layer | Content type | Token budget | Example |
|---|---|---|---|
| Root | Universal guidance | 500-800 tokens | Build commands, global prohibitions |
| Service | Domain-specific rules | 300-500 tokens | API conventions, testing patterns |
| Feature | Narrow scope gotchas | 100-300 tokens | Specific module quirks |
The placement test: "Does every task in this subtree need this information?"
- "Run
npm testbefore committing" → Root (applies everywhere) - "API endpoints must validate input with zod" →
packages/api/CLAUDE.md(API-specific) - "The legacy auth module uses callbacks, not promises" →
packages/api/auth/CLAUDE.md(feature-specific)
Building layers incrementally
You do not create all layers upfront. Start minimal and add layers where friction appears.
Phase 1: Root only. Create a single root CLAUDE.md with essential commands and critical prohibitions. Let the agent work for a few sessions. Watch where it struggles.
Phase 2: First subdirectory files. When repeated corrections cluster in a specific area, add a CLAUDE.md there. A service where the agent keeps misusing the ORM gets ORM guidance in its local file. A legacy module where conventions differ from the rest of the project gets its own documentation.
Phase 3: Refinement. As the team accumulates experience, guidance sharpens. Vague instructions become specific. Instructions that do not help get cut. Subdirectory files that grow too large split into rules directories.
This incremental approach avoids pre-optimizing for problems that may never appear. Documentation grows to match actual friction, not imagined friction.
The self-correcting documentation pattern
The most effective CLAUDE.md maintenance pattern comes from the tool's own creators. Boris Cherny describes the Claude Code team's approach: "Anytime we see Claude do something incorrectly, we add it to the CLAUDE.md, so Claude knows not to do it next time."
Every mistake becomes a future prevention.
The workflow:
- Agent makes a mistake during development
- Developer corrects the agent and completes the task
- Developer adds the correction to the appropriate CLAUDE.md
- Future sessions avoid the same mistake
# Gotchas (added through correction)
- Do not use `moment.js` for date handling; use `date-fns` instead
- API error responses must include `requestId` for tracing
- Test fixtures must not share state; create fresh instances per testEach line is a past mistake converted into prevention.
Some teams use a @.claude tag on code review comments.
When a PR correction would apply to future AI interactions, the comment gets this tag.
Weekly, someone collates tagged comments into CLAUDE.md additions.
Detecting when layers need adjustment
Context loading affects agent behavior in observable ways. Watch for these signals:
Too much context at root:
- Agent responses slow down noticeably
- Agent mentions irrelevant details from unrelated services
- Context compaction happens early in sessions
Too little context in subdirectory:
- Repeated corrections for the same issue
- Agent fails to follow local conventions it cannot see
- Agent generates code inconsistent with surrounding files
Conflicting context between layers:
- Agent behavior varies unpredictably
- Agent explicitly mentions conflicting instructions
- Agent asks for clarification on topics already documented
Use /context to check token consumption.
If memory files consume more than 2% of the context window, consider trimming or reorganizing.
Monorepo-specific patterns
Large codebases benefit from explicit routing in the root CLAUDE.md. Rather than letting agents discover subdirectory files through exploration, point them directly:
# Service documentation
- Email templates: see @emails/CLAUDE.md
- Go services: see @go/services/CLAUDE.md
- Shared utilities: see @packages/shared/CLAUDE.md
- Frontend components: see @web/components/CLAUDE.mdThis serves two purposes. Agents know where to look before they start exploring. Humans maintaining the documentation understand the structure.
The @path import syntax loads content into context at startup.
For subdirectory CLAUDE.md files, this is usually not what you want.
List paths as plain text for reference, not import syntax for eager loading.
The three-tier authority structure
For legacy codebases with uncertain ownership, subdirectory CLAUDE.md files can establish clear authority levels:
# Authority levels
## Always do
- Run tests before committing
- Use the established error handling pattern
- Follow existing naming conventions in this directory
## Ask first
- Add new dependencies
- Modify shared interfaces
- Change database schemas
## Never do
- Modify files outside this service without explicit instruction
- Delete tests even if they appear obsolete
- Refactor working code without clear benefitThis structure helps agents navigate the ambiguity inherent in legacy systems. Not everything needs explicit permission, but some changes require human judgment.
Handling inherited technical debt
Legacy codebases contain patterns the team knows are wrong but cannot fix immediately. Document these explicitly in the relevant subdirectory:
# Known technical debt (do not replicate)
This service contains several anti-patterns from earlier development:
- Callback-based async (newer code uses promises)
- Manual SQL queries (newer code uses the ORM)
- Mixed naming conventions (newer code follows style guide)
When modifying this code:
- Match the local style within a file
- Do not extend deprecated patterns into new code
- When rewriting a file entirely, modernize the patternsWithout this guidance, agents mimic what they see. Mixed patterns in the codebase produce mixed patterns in output. Explicit documentation about which patterns are intentional versus inherited prevents propagation of legacy decisions.
Verifying layer effectiveness
After establishing a layered structure, verify it works:
Test root coverage. Navigate to the repository root and start a fresh session. Give the agent a task that touches multiple services. Does it have the universal guidance it needs? Is it overloaded with service-specific detail it does not need?
Test subdirectory loading.
Navigate into a specific service directory.
Give the agent a task local to that service.
Does it follow service-specific conventions?
Check /context to confirm subdirectory CLAUDE.md loaded.
Test isolation. Work in one service, then switch to another without resetting. Does guidance from the first service bleed into the second? Subdirectory CLAUDE.md files should load on-demand, not accumulate.
The /memory command shows all loaded memory files.
Use it to verify which layers are active for the current context.
Migration path for existing projects
Projects with existing CLAUDE.md files can migrate to a layered structure incrementally:
-
Audit the current file. Identify content that applies universally versus content specific to certain areas.
-
Extract service-specific content. Move domain-specific guidance to subdirectory files. The root file should shrink.
-
Add routing. Update root CLAUDE.md to reference subdirectory locations.
-
Verify token consumption. Use
/contextbefore and after migration. Total tokens should be similar; distribution should improve. -
Monitor agent behavior. Watch for regressions in areas where guidance moved. Adjust layer placement based on observed issues.
The goal is effective agent guidance, not architectural purity. If a three-layer structure serves a project well, do not add a fourth layer because it seems more organized. If a single root file handles everything a small project needs, subdirectory files are maintenance burden without benefit.
Progressive context in practice
A team inheriting a legacy e-commerce platform might evolve their CLAUDE.md structure like this:
Week 1: Root CLAUDE.md with build commands and the one critical gotcha everyone hits (the unusual database connection pattern).
Week 3: After multiple corrections in the payments service, a services/payments/CLAUDE.md appears with PCI compliance requirements and transaction handling patterns.
Week 6: The catalog service gets its own file documenting the legacy product schema and its known inconsistencies.
Month 2: The root file gets a routing section pointing to service documentation, and teams start adding service files proactively when they create new services.
Month 4: A rules directory appears for cross-cutting concerns (testing standards, logging conventions) that apply to multiple services but not all code.
This progression reflects actual project needs discovered through work, not theoretical organization designed upfront. The documentation grows to match the complexity the team actually encounters.