Tools
Tools: CLAUDE.md Best Practices: The backbone.yml Pattern
2026-02-10
0 views
admin
Give the agent a map ## Scaling up ## Wiring it up ## Why a separate file? ## The cost of exploration ## Where this fits ## When to adopt this ## Keep it accurate ## Try it 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. 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. The fix is simple: one file that maps your project. 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." As your project grows, so can your backbone. Here's what mine looks like for Reporails rules: Multiple agents, rule patterns, schemas, registries - all mapped. Claude can construct paths directly instead of exploring. The backbone file alone isn't enough - you need to tell Claude to use it. Add this to your CLAUDE.md: This is the key: explicit instruction to read the map before exploring. Without it, Claude might still wander. 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: Directories show what exists. backbone.yml shows how it fits together. I tracked my Claude Code usage across 176 sessions. A significant chunk of friction came from wrong assumptions about project structure: Each mistake costs tokens, time, and trust. The models are smart enough - the problem is orientation. In my previous post, I introduced capability levels for instruction files: 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. Not every project needs it. Weekend hack? Basic CLAUDE.md is fine. ...you're paying the exploration tax. A backbone file pays for itself in the first session. 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. 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 is where I'm building instruction file governance. The backbone.yml example above is from there. Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse CODE_BLOCK:
find . -name "*.yml" -type f
grep -r "config" --include="*.md"
ls -la .claude/ Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
find . -name "*.yml" -type f
grep -r "config" --include="*.md"
ls -la .claude/ CODE_BLOCK:
find . -name "*.yml" -type f
grep -r "config" --include="*.md"
ls -la .claude/ COMMAND_BLOCK:
# 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/ Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
# 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/ COMMAND_BLOCK:
# 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/ CODE_BLOCK:
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 Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
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 CODE_BLOCK:
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 COMMAND_BLOCK:
## 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. Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
## 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. COMMAND_BLOCK:
## 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. - 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? - 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 - 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 - 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 - Create backbone.yml in your project root
- Map your directories, configs, conventions
- Add the initialization section to your CLAUDE.md
- Watch Claude stop guessing
how-totutorialguidedev.toaiml