There's a Dutch scouting tradition called "dropping." Kids get driven to an unfamiliar forest at night - sometimes blindfolded - and have to find their way back to camp. It builds independence, problem-solving, resilience.
> **That's what most people do to their AI agents.**
Drop them in a codebase. No orientation. Figure it out. (*Veel succes en heel gezellig*, as the Dutch would say.)
The difference is that, unlike people, the AI Agent memory goes as far as context allows.
```bash
find . -name "*.yml" -type f
grep -r "config" --include="*.md"
ls -la .claude/
```
The agent explores. Makes wrong assumptions. Gets corrected. Tries again. Eventually finds what it needs, or doesn't and quietly poison context.
I call this the **exploration tax** - the **tokens** and **time** spent orienting instead of working.
## Give the agent a map
The fix is simple: one file that maps your project.
```yaml
# backbone.yml
version: 1
structure:
config: config/
src: src/
tests: tests/
docs: docs/
conventions:
test_pattern: "*.test.ts"
config_format: yaml
boundaries:
never_modify:
- .env
- migrations/
- vendor/
```
That's enough to start. Claude reads this once and knows: config lives in `config/`, tests are `*.test.ts`, never touch `.env` or `migrations/`.
No more exploration loops. No more wrong guesses. No more "sorry, I thought the config was in the root directory."
## Scaling up
As your project grows, so can your backbone. Here's what mine looks like for [Reporails rules] (https://github.com/reporails/rules/blob/main/.reporails/backbone.yml):
```yaml
version: 3
agents:
claude:
main_instruction_file: CLAUDE.md
config: agents/claude/config.yml
skills: .claude/skills/
tasks: .claude/tasks/
codex:
config: agents/codex/config.yml
rules:
core: core/
agents: agents/
patterns:
rule_dir: "{category}/{slug}/"
definition: "rule.md"
test_pass: "tests/pass/"
test_fail: "tests/fail/"
categories:
structure: core/structure/
content: core/content/
efficiency: core/efficiency/
maintenance: core/maintenance/
schemas:
rule: schemas/rule.schema.yml
capability: schemas/capability.schema.yml
agent: schemas/agent.schema.yml
registry:
capabilities: registry/capabilities.yml
levels: registry/levels.yml
coordinate_map: registry/coordinate-map.yml
```
Multiple agents, rule patterns, schemas, registries - all mapped. Claude can construct paths directly instead of exploring.
## Wiring it up
The backbone file alone isn't enough - you need to tell Claude to use it. Add this to your CLAUDE.md:
```markdown
## Initialization
Read these files before searching or modifying anything:
1. Read `backbone.yml` for project structure and path resolution
2. Read any registries or schemas referenced there as needed
3. Read `.claude/rules/` for context-specific constraints
## Structure
Defined in `backbone.yml` - the single source of truth for project topology.
**BEFORE** running `find`, `grep`, `ls`, or glob to locate project files, read `backbone.yml` first. All paths are mapped there. Do not use exploratory commands to discover paths that the backbone already provides.
```
This is the key: explicit instruction to read the map before exploring. Without it, Claude might still wander.
## Why a separate file?
You could put all of this directly in your CLAUDE.md. But there's a tradeoff.
Everything in CLAUDE.md sits in the context window from the start - every session, every message, whether the agent needs it or not.
backbone.yml is read-on-demand. Claude doesn't load it at session start - it reads it when it would otherwise start exploring. The map replaces discovery, not adds to it.
There are also things a directory structure can't express:
- **Patterns.** `{category}/{slug}/rule.md` isn't a folder - it's a convention.
- **Relationships.** Which agent owns which config? What schema validates what file?
- **Boundaries.** What's off-limits? What's deprecated?
Directories show what exists. backbone.yml shows how it fits together.
## The cost of exploration
I tracked my Claude Code usage across 176 sessions. A significant chunk of friction came from wrong assumptions about project structure:
- Used the wrong YAML library (PyYAML instead of ruamel.yaml)
- Wrote changes to the wrong repo in a monorepo
- Assumed directories existed that didn't
- Missed config files that were right there
Each mistake costs tokens, time, and trust. The models are smart enough - the problem is orientation.
## Where this fits
In my [previous post](https://dev.to/cleverhoods/claudemd-best-practices-from-basic-to-adaptive-9lm), I introduced capability levels for instruction files:
- **L1-L2**: CLAUDE.md exists, has basic constraints
- **L3**: External references, multiple files
- **L4**: Path-scoped rules that load conditionally
- **L5**: backbone.yml - maintained structure, active upkeep
- **L6**: Dynamic context, skills, MCP integration
Most setups stop at L2-3. The jump to L5 isn't about adding more rules - it's about making your existing setup navigable. backbone.yml is how you get there.
## When to adopt this
Not every project needs it. Weekend hack? Basic CLAUDE.md is fine.
But if you notice:
- Claude repeatedly exploring the same directories
- Wrong assumptions about project structure
- Corrections like "no, the config is in X, not Y"
- Monorepo confusion about which repo to modify
...you're paying the exploration tax. A backbone file pays for itself in the first session.
## Keep it accurate
A backbone.yml only works if it's true. Paths that don't resolve, patterns that don't match reality - those are worse than no map at all.
Structure that rots is worse than no structure.
## Try it
1. Create `backbone.yml` in your project root
2. Map your directories, configs, conventions
3. Add the initialization section to your CLAUDE.md
4. Watch Claude stop guessing
I use this with Claude Code daily. The pattern should work for any agent that reads instruction files - Codex, Copilot, Cursor - though I haven't tested all of them. If you try it, let me know how it goes.
> **Don't drop your agent in the dark. Give it a map.**
---
*[Reporails](https://github.com/reporails/rules) is where I'm building instruction file governance. The [backbone.yml example](https://github.com/reporails/rules/blob/main/.reporails/backbone.yml) above is from there.*