When a project grows beyond a certain scale, the biggest challenge for AI agents modifying code isn't "can't write it" — it's "don't know what rules to follow or which files to change." This article shares a layered, navigation-oriented documentation system validated in real large-scale projects, enabling AI agents to self-serve context, respect architecture constraints, and never miss a file when making cross-domain changes.
The Problem: AI Agents' Context Dilemma
When using AI coding agents (GitHub Copilot, Claude, Cursor, etc.) in large projects, common pain points include:
- Forgetting the rules: You tell it "you must use a specific async framework," and it writes forbidden patterns in another file
- Editing the wrong places: A task requires modifying 3 modules simultaneously, but it only changes 1
- Lacking domain knowledge: Unfamiliar with initialization order, event bus conventions, data field naming rules
- Repeating yourself: Every new conversation starts from scratch explaining the project architecture
The root cause is: AI agents lack a structured, self-service project knowledge base.
Our solution is a four-layer document system: Constitution → Root Router → Domain Routers → Cookbook, with the AI agent's own memory system as the fifth layer.
Layer 1: Constitution
File: .github/copilot-instructions.md
This is the foundation of the entire system. It defines global hard rules that must never be violated, no matter what.
GitHub Copilot automatically injects this file into every conversation context (a native GitHub feature). Other agents (like Claude Code) need to read it manually at startup.
The Constitution's content is organized by category. Here are some anonymized examples:
## Async
- The project-specified async framework is mandatory — do not use engine-native coroutines or Task.Run
- CancellationToken must be passed through all async call chains
## Data Integrity
- Numeric ranges must be 0-100 (not 0-1)
- DTO field name is `id`, not `entityId` (AI agents have guessed wrong multiple times)
## Architecture Boundaries
- UI scripts only observe events — never contain business logic
- Systems communicate via event bus, not direct coupling
Design principles:
- Only write "what not to do" — no navigation or implementation details
- Every rule originates from a real bug or rework — for example, "DTO field name is
id, notentityId" was added because AI agents repeatedly used the wrong field name - Concise formatting to ensure it loads completely within token limits
The Constitution is like the constitution in a legal system: it doesn't tell you what to do, but it makes clear what you must never do.
Layer 2: Root CLAUDE.md — Project Router
File: CLAUDE.md in the project root
If the Constitution is the "law," the Root CLAUDE.md is the "map." It provides the project overview and a task routing table:
## Task Routing — Where to Look
| If you're changing... | Read first |
|----------------------------------------------|--------------------------------|
| Core runtime flow (controllers, pipelines) | src/core/CLAUDE.md |
| AI/ML pipeline (prompts, guardrails) | src/core/ai/CLAUDE.md |
| UI framework, Views, Components | src/ui/CLAUDE.md |
| Entity behavior systems | src/core/entity/CLAUDE.md |
| Cross-domain operations | docs/cookbook/ |
When an AI agent receives a task, it first checks this table to know which domain document to read — no need to blindly search the entire codebase.
The Root CLAUDE.md also includes:
- Project overview and core business loop description
- Tech stack quick reference
- Directory structure diagram
- Key architectural patterns overview (event-driven, dependency injection, interface segregation, etc.)
Design principle: Navigate only, don't define rules. All rules belong in the Constitution; the Root only tells you "where to look."
Layer 3: Domain CLAUDE.md — Domain Routers
Distribution: One per major subdirectory, 18 in total across the project.
This is the core working layer of the system. Each domain router contains:
3.1 Parent Declaration
> Parent: core/CLAUDE.md | Constitution: .github/copilot-instructions.md
Every file explicitly declares its parent and ultimate authority source, forming a clear reference chain.
3.2 File Role Table
Lists what each file is and what it does in that directory:
## File Roles
| File | Role |
|-----------------------------|---------------------------------------------|
| MainController.cs | Turn orchestrator — Phase 1 → Phase 2 |
| InputGuardrail.cs | Validates AI output within allowed bounds |
| StreamFilter.cs | Real-time stream filtering during generation |
This lets the AI agent determine "which file should I modify" without opening and reading every file's code.
3.3 Initialization Order and Dependency Constraints
## Initialization Order
Phase 1: AppConfig → SaveSystem → EntityRegistry
Phase 2: DataStore → AssetManager → StateTracker
...
Services can only Resolve<T>() systems registered in earlier phases.
3.4 Subdomain Routing
Large domains (like Core) continue to layer downward:
core/CLAUDE.md
├── ai/CLAUDE.md (AI/ML pipeline)
├── narrative/CLAUDE.md (Narrative system)
├── world/CLAUDE.md (World simulation)
├── data/CLAUDE.md (Data management)
├── entity/CLAUDE.md (Entity behavior)
└── services/CLAUDE.md (External service layer)
Tree-structured Reference Network
All CLAUDE.md files form a reference tree:
Constitution (hard rules, auto-loaded)
↓
Root CLAUDE.md (master router)
├── core/CLAUDE.md → ai/ | narrative/ | world/ | data/ | entity/ | services/
├── ui/CLAUDE.md
├── models/CLAUDE.md
├── editor/CLAUDE.md → modules/ | data/ | tabs/
└── data/CLAUDE.md
Reference directions:
- Upward: Each file declares its parent + the Constitution
- Downward: Parents list their subdomains
- Peer: Task routing table points to sibling domains
- Cross-domain: Points to Cookbook
Design principle: Every CLAUDE.md is a self-contained context package. After reading it, you know what you can and cannot do in that directory, and where to go if you need to change something elsewhere.
Layer 4: Cookbook — Cross-domain Operation Manual
Directory: Docs/Cookbook/
The first three layers solve "how to change things within a single domain." But in practice, many tasks require modifying multiple domains simultaneously. For example:
- Adding a new runtime service → needs changes to DI registration, startup sequence, save system, and possibly UI
- Adding a new data model type → needs changes to model definition, interfaces, data manager, UGC mode support
The Cookbook provides step-by-step checklists for these common operations:
# Add New Service
## Steps
1. Create `MyService.cs` in `src/core/services/`
2. Implement `IInitializable`, `ISaveable` interfaces
3. Register in `AppBootstrap.InitPhase3()` — after TimeManager
4. Add save fields to `AppSaveData.cs`
5. Expose via `ServiceLocator.Register<IMyService>(instance)`
6. Add log tag `[MyService]` to Constitution
Each Cookbook entry annotates:
- Which files need modification (across multiple domains)
- The order of changes
- Constraints to follow (from the Constitution)
- Common pitfalls
Design principle: Cookbook is procedural knowledge, not structural knowledge. Domain CLAUDE.md tells you "what's here"; Cookbook tells you "what steps to follow for this task."
Layer 5: AI Memory System — Temporary and Persistent
The documentation system solves the project knowledge problem, but AI agents also need working memory. We leverage the agent's built-in memory mechanisms across three scopes:
| Scope | Path | Lifespan | Purpose |
|---|---|---|---|
| Session Memory | /memories/session/ | Current conversation | Task progress, intermediate findings, temporary notes |
| User Memory | /memories/ | Across all conversations | User preferences, common commands, lessons learned |
| Repo Memory | /memories/repo/ | Cross-conversation, repo-bound | Codebase conventions, verified build commands |
Session Memory is especially important: when a task requires multiple steps, the AI agent can record "how far I've gotten, what I discovered, and what's left" in Session Memory, allowing it to recover context even if interrupted.
Real Workflow
When an AI agent receives a task like "add a new attribute dimension to an entity," the full workflow is:
1. Constitution auto-loads
→ Knows: attribute values must be 0-100, delta must be -30 to +30
2. Check Root CLAUDE.md routing table
→ Changing entity system → read src/core/entity/CLAUDE.md
→ Changing data model → read src/models/CLAUDE.md
→ Cross-domain operation → check docs/cookbook/
3. Read entity/CLAUDE.md
→ Knows the state machine is a stateless parser
→ Knows behavior patterns cannot be directly written
4. Read cookbook/Add-New-Model-Type.md
→ Gets step checklist: define interface → create model → register → dual-track support
5. Session Memory records progress
→ "Step 1 done: interface defined"
→ "Step 2 in progress: creating model"
6. After completion, check the Constitution
→ Confirm no hard rules were violated
Throughout this process, the AI agent doesn't need step-by-step human guidance and doesn't need to search the entire codebase blindly.
Design Insights
Why Markdown instead of code comments?
Code comments are local — you only see them when you open that file. But AI agents need to know which file to open before opening it. CLAUDE.md provides meta-information that transcends any single source file.
Why layers instead of one giant document?
A 10,000-line document would blow through an AI's context window. Layered design ensures only the context relevant to the current task is loaded — Constitution (~100 lines) + Root (~150 lines) + 1-2 Domains (~100 lines each) = roughly 500 lines total, well within token budget.
Why is the Constitution in .github/?
Because GitHub Copilot natively supports auto-loading .github/copilot-instructions.md. This means the most important rules are injected into every conversation without any extra steps. Other agents can also auto-load corresponding files through similar mechanisms (e.g., Claude Code's CLAUDE.md, Cursor's .cursorrules).
Every Constitution rule has a story
We don't add rules "preventively." Every hard rule originates from a real bug, a rework, or an incorrect AI agent output. For example:
- "DTO field name is
id, notentityId" — because an AI agent guessed the field name wrong three times - "Deep-copy reference-type lists in save data" — because a shallow copy caused a subtle save corruption
- "Animation tweens must be bound to a lifecycle" — because tweens weren't cleaned up during scene transitions, causing null references
About the CLAUDE.md naming convention
CLAUDE.md comes from Anthropic's Claude Code convention — Claude Code automatically reads the CLAUDE.md file in its working directory. But in our system, its role has grown beyond any specific AI tool: any AI agent (or even human developer) can follow this navigation system to find the context they need. You can also rename it to AGENTS.md, CONTEXT.md, or whatever you prefer — the key is the layered navigation structure, not the filename itself.
Summary
| Layer | File | Responsibility | Loading Method |
|---|---|---|---|
| Constitution | .github/copilot-instructions.md | Inviolable global hard rules | Copilot auto / other agents manual |
| Root Router | CLAUDE.md (project root) | Project overview + task routing table | Agent reads automatically by convention |
| Domain Router | CLAUDE.md per subdirectory (×18) | Domain knowledge + file roles + subdomain routing | On-demand reading |
| Cookbook | Docs/Cookbook/*.md | Cross-domain operation step checklists | On-demand reading |
| Memory | /memories/session/ etc. | Working memory + persistent experience | Agent-managed |
The core philosophy of this system is: Treat your AI agent like a new colleague who needs onboarding. The Constitution is the company policy manual, Root CLAUDE.md is the org chart, Domain CLAUDE.md is the department guide, Cookbook is the standard operating procedures (SOP), and Memory is the personal notebook.
When these layers work together, AI agents can safely and accurately complete complex cross-domain code modifications with little to no human intervention.