One CLAUDE.md to Route Them All - How I Set Up Claude Code Across Repos

One CLAUDE.md to Route Them All: How I Set Up Claude Code Across Repos

~/.claude/CLAUDE.md            true in every repo: voice, safety, delegation tiers
        |
~/dev/                 no CLAUDE.md here, the folder names are the map
   |-- fleet/CLAUDE.md
   |-- personal-wiki/CLAUDE.md
   |-- meridiano/meridiano-nestjs/CLAUDE.md
        |
   skills                      loaded only when a task matches

Every Claude Code session I run starts in ~/dev, a folder with 79 entries in it: my blog, my personal wiki, three Meridiano repos, a daily planner app, my config repo, and a long tail of experiments. One file follows me into all of them: my global ~/.claude/CLAUDE.md.

Deciding what earns a line in that file got easier after I built a second routing file, ran it for a few weeks, and deleted it.

Every Line Costs, on Every Request

Claude Code’s CLAUDE.md is its name for the cross-harness AGENTS.md convention: a file the harness loads into the context window when the session starts. The model is stateless, so this file is how my preferences survive from one session to the next.

One prompt turns into many model provider requests, and each request re-sends the whole conversation, CLAUDE.md included. Matt Pocock opens the steering lesson of his AI Coding Crash Course:

Anything that you load into the agent up front, you pay for on every single model provider request.

That costs two things. The first is tokens, the cost everyone already sees. The prefix cache bills the repeated part at a tenth of the normal input price on Anthropic’s API. The second is attention: “Every extra instruction that you load makes every other instruction a little bit quieter and pushes the agent a little bit closer to the dumb zone.” Caching does nothing for that one. He calls the pair context load.

His fix is a choice between two strategies. Push puts the instruction in the context window every session. Point leaves the instruction in the environment and puts one line in the context window saying when to go get it. That line is a context pointer.

Pushed rules also misfire, because the agent cannot tell when they apply. His example is a claude.ai user whose standing instructions said “I work under PCI DSS card payment compliance. Anything security relevant should be flagged.” They asked for a chocolate cake recipe and got one, followed by a note on the security implications of the cake.

My own version of the cake would be the personal wiki’s first rule, “never edit raw/”, showing up while I fix a date picker in my Android planner.

The Router I Built and Deleted

On 2026-08-23 I was listening to Pocock on The Unhandled Exception podcast, episode 88, and around minute 46 he described a workspace-level file that points at each project. I built mine the same day at ~/dev/CLAUDE.md. It was pure pointers:

## Workspace Map

This file routes agents. Project-specific rules live inside each project.
Before editing a project, `cd` into its path and read that project's `CLAUDE.md`.

## Projects

- `~/dev/meridiano/meridiano-nestjs` - AI-powered intelligence briefings, tailored to my interests from curated news feeds; read `CLAUDE.md` first.
- `~/dev/personal-wiki` - A file-based personal knowledge base maintained by LLM agents and read through human-friendly surfaces like Notion; read `CLAUDE.md` first.
- `~/dev/fleet` - My personal coding setup and config files; read `CLAUDE.md` first.
  ...

It had ten project lines and copied no rules up from the repos, the point pattern with nothing added.

A few weeks later I deleted it. Claude was already finding my repos when I just said the name. “Open fleet” or “check meridiano-nestjs” worked with or without the map, because the folders are named fleet and meridiano-nestjs.

Pocock’s writing-for-agents skill has a line for this:

The environment is a source of truth too (package.json scripts, config files, the directory layout, --help output), and a document that restates it is a cache: a copy of a lookup, earning its load only when the lookup is expensive.

My map was a cache of ls. Finding fleet costs one command.

The “read CLAUDE.md first” line mostly duplicated the harness. Claude Code’s memory docs say a CLAUDE.md in a subdirectory loads “once Claude reads, writes, or edits another file in that subdirectory.” Open any file in personal-wiki/ and the harness loads the wiki’s rules.

The map did cover one gap. A git commit reads no file, so a session that starts in ~/dev and goes straight to git in fleet has not loaded fleet’s rule to commit and push directly to main. Finding a folder and loading its rules are separate steps. Most tasks have Claude open a file in the repo early on, but a git-only task may never open one, and nothing warns me.

When I went back to the file for this post, I also found a leftover line: meridiano-cli - one-line purpose, a template placeholder sitting under the real meridiano-cli entry. It loaded into every session for weeks and I never saw it, which tells you how often I read my own map. The writing-for-agents page names the problem: “Duplication is the most reliable sign a document was never tested.”

I also had one skill in ~/dev/.claude/skills/ that I never invoked. It went too.

What Earns a Pushed Line

The global file loads in every session, wherever I start it. A line belongs there only if it is true in every repo and likely to matter on most turns. Anthropic’s docs suggest keeping a CLAUDE.md under 200 lines; mine is 108. Here is what made the cut:

  • How I talk. A “Voice” section with rules like “No em dashes, en dashes, or hyphen-as-dash. End the sentence or use a comma.” It applies to commit messages, PR bodies and chat in every repo.
  • What a question means. “A question is a request for an answer, not for changes.” It fires constantly, because I ask a lot of questions.
  • Blast radius. “Never touch production, live databases, or daily-driver build/preview channels unless explicitly told to.”
  • My machine. “I develop on macOS, so assume a macOS/BSD userland.” The agent cannot see this from inside a repo, and getting it wrong means a broken sed -i in every project.
  • Who does the work. This is the routing that survived the deletion. Instead of routing to repos, the global file routes work to models:
- `haiku` - mechanical bulk work: renames, boilerplate, format conversion, log triage
- `sonnet` - rarely use it, only use it on tasks a bit more difficult than the ones handed to haiku
- `opus` - well-specified implementation with clear acceptance criteria AND genuinely tricky work

followed by my favorite line in the file: “When unsure between tiers, pick the cheaper and escalate on failure.”

Repo rules stay in each repo. The wiki’s ownership rules, the dashboard’s farming loop and Meridiano’s API conventions all live in their own CLAUDE.md files, and the harness loads each one when the agent opens a file in that repo. Procedures go one level further down, into skills, which only load when a task matches their description. That is progressive disclosure across three levels, and only the global file at the top pays on every request.

Writing It With writing-for-agents

Pocock’s writing-for-agents skill is what I reach for whenever I write a skill or a coding-standards doc. It is a reference for any document an agent reads. The skill page says: “Its default fix is to delete, not to explain.”

The parts I use most:

  • Context pointers. A skill description and an AGENTS.md line naming a doc are the same object, and “the pointer’s wording, not its target, decides how reliably the agent follows it.”
  • The two loads. Context load is the agent’s cost. Cognitive load is mine: remembering which documents exist and when to reach for each. The skill does not try to minimize the second one, because “it is the price of human agency.”
  • The no-op test. Does this line change behavior compared to what the model already does by default? If not, delete the whole sentence.
  • Sediment. Stale layers “that settle because adding feels safe and removing feels risky.” The meridiano-cli placeholder was sediment in a ten-line file.

What I’d Still Fix

Running the skill over my own global file finds four problems, which is less flattering.

The Voice section is 32 of the 108 lines, close to a third of the file, and it only matters when the agent writes prose. I already use the unslop skill from pstack, which enforces the same rules. The Voice section could shrink to a pointer at that skill, with only the rules that fire on every reply left behind.

The delegation tiers matter only when the agent spawns a subagent. That is often, but not most turns.

Starting every session in ~/dev has a memory cost too. Claude Code keeps a separate auto memory folder for each folder a session starts in. ~/dev is not a git repo, so sessions there get their own memory. The 12 notes in daily-dashboard’s memory folder never load from there. One of them, “Ana uses Chrome on macOS, not Safari”, is also out of date because I use Arc now, so it is sediment as well. A rule a repo needs every time belongs in its committed CLAUDE.md, which reaches the agent from any starting folder.

The file also says no a lot. 15 lines open with “No”, “Never”, “Do not”, “Don’t”, “Skip” or “Avoid”. The skill warns that “steering by prohibition drags the forbidden behaviour into context and makes it more available, not less,” and asks for the positive target instead. Some of mine are real guardrails. The strongest one, against recursive deletes, is a hook instead of a line, because the docs say CLAUDE.md is context, not enforced configuration. The rest are candidates for a rewrite.

None of this is urgent at 108 lines. But I deleted a ten-line file for not earning its keep, so the hundred-line one gets the same test.

The cheapest routing file is a well-named folder.

Down the Rabbit Hole