Ch.5: Claude Code: The Highest-Leverage File in Your Repo

Outline

Transcript

0:00 The weirdest Claude Code failure is not when it misses a complicated algorithm. It is when it forgets the obvious thing you told it yesterday. Use this test command. Do not touch generated files. Put new API handlers over there. Yeah. We have all shipped that loop more times than we'd admit. And honestly, my instinct here is blunt: if every session starts with the same orientation speech, you do not have a prompting problem. You have a project-memory problem. The repo's whole personality lives in your head instead of in the repo.

0:32 `CLAUDE.md` is your project's brain: persistent, reviewable context that makes the agent start closer to how the repo actually works. And the docs back that brain idea up. They describe `CLAUDE.md` as a markdown file Claude Code reads for persistent guidance, and that memory page is linked in the description. It can live at the project root, or inside the dot claude directory, and it loads when a session starts. Right, though that caveat matters. The file is not a law of physics. Claude still reads it and interprets it, so a vague rule earns you vague behavior.

1:07 True. But good instructions change the default path. Instead of guessing at the repo's setup, the agent opens with a small operating manual: the commands, the conventions, a few architecture notes, and the handful of mistakes expensive enough to ban up front. So it begins the task already pointed in the right direction. So the best entries feel almost obvious in hindsight. They're the things you would tell a new teammate on day one. How to install dependencies. How to run fast tests. Which command is safe before a commit.

1:35 Which generated files are off limits. And the conventions that are real but not obvious from the code. Take a case: maybe this repo leans on a specific fixture pattern, migrations are always hand-reviewed, and the API contract lives in another workspace. Miss that, and the agent ships a plausible diff in the wrong part of the system. Oof, yeah. Those are real coordination rules. And if Claude Code has to rediscover them by trial and error, you pay for that rediscovery in broken diffs, Before the real task even starts.

2:08 Now, a teammate is going to push on this. They'll say, why keep another markdown file when Claude can just read the repo? Shouldn't the agent infer the project by exploring? It should explore. But code does not reveal every team rule. A test file shows what exists. It won't tell you which test command is the cheap preflight, which integration suite needs Docker, or which flaky test nobody trusts. Hold on. I didn't realize that early on. I thought the file was a shortcut around exploration, but really it doesn't replace exploration.

2:41 It steers exploration. Sure. It tells the agent where the map is reliable, where the cliffs are, and which local habits matter before it starts editing. Yep. Exploration without orientation is how the agent takes the scenic route through your repo. So, okay, all of this has to actually live somewhere. The first layer is project-level. These are checked in with the repo, so everyone on the team gets the same baseline. And they should be, I mean, the unglamorous stuff. The build command. The test command.

3:10 The formatting command. Directory layout. Architecture guardrails. For example, if the backend package needs `uv run pytest tests/unit` before commits, write it down so every run reaches for the same cheap check. Sure. And try this gut check: if a teammate would gripe in review, you should have known this, then it probably belongs in the project file. If it's only your personal habit, it probably does not. And that personal-habit point is exactly where the user level comes in. Your own preferences live under your home dot claude directory, so that file travels with you across every project.

3:45 So this is where preferences go. Keep responses concise. Show risky commands first. And never create commits unless I ask. Now imagine dropping that commit rule into a team repo: suddenly your personal workflow kind of becomes everyone else's policy. Yeah. A project file should not encode one engineer's quirks, and a user file has no business pretending every repo works the same. Keep those layers apart, and you stop helpful context from becoming team-wide noise. Then there's a 3rd case: private, but project-specific. A local database path.

4:20 A personal dev-server port. A note that your machine needs a different setup command than everyone else's. That is where `CLAUDE.local.md` fits. It sits at the project root, it is meant to be gitignored, and it gives you private project context without leaking it into the shared repo. So the rule is basically this: if it is a fact about your laptop, it never gets committed? Pretty much. Team standards go in the committed file. Machine facts stay in the local one. Otherwise the repo slowly turns into a scrapbook of one person's laptop.

4:52 Right. Commit your laptop's database path once, and the next teammate inherits a bug they cannot even reproduce. So the file works, which is where it quietly goes wrong. People want to put everything in it. The style guide. The architecture doc. The migration history. That one incident from last quarter. Oh, wow. The markdown junk drawer. Yep. And a senior dev will defend it: just put it all in one place, then nothing gets lost. But the docs are clear on the tradeoff. Shorter files usually get better adherence, and huge instruction files eat the model's limited attention, its context, before the task begins.

5:30 Here's where it gets interesting, though. A 40-line file that bans generated directories beats a 900-line manual nobody reads. Durable, repeated instructions belong there. Long procedures, reference material, one-off history, those sort of live somewhere else, and you link or import only when it actually earns the context. Yeah. Otherwise the project brain becomes a context nightmare with a friendly filename. Now imports. The docs frame them as organization. A `CLAUDE.md` file can point at another file with an at-path import, and Claude expands that content when it loads the instructions.

6:06 Wait, so does pulling a file in through an import actually save you any context? Not really, and this is the part that trips people. Imports keep the file readable for humans. They do not make the imported words free, you know. The organizing is for the people reading it. So the whole benefit is human, not computational. Exactly. Those words still cost context. For instance, import a 2,000-line architecture doc and you carry all 2,000 lines every session. Use imports for stable, important context, not the whole docs folder because it feels tidy.

6:40 And that same context pressure is why the docs added a rules directory. For example, you drop a markdown rule file in there, and some can be scoped to apply only on matching paths. So should the root file shrink while the rules directory grows? Often, yeah. Scope a rule to where it matters, instead of making every task haul around every rule. Right. Take migrations: frontend rules should not ride along for a database migration. The root file keeps only what is always true everywhere. Yeah. The scoped file carries the rule for just that slice of the tree, so a task only picks up the rules it is actually standing in.

7:18 Now, one naming detail trips up almost everybody. Claude Code reads `CLAUDE.md`. It does not directly read agents dot em dee as its main instruction file. Right, and that stings, because plenty of repos already ship an agents dot em dee for other coding agents. The fix is simple. Make `CLAUDE.md` import the existing agents dot em dee, or keep a shared source and bridge both tools to it. One source of truth beats two drifting files. Otherwise one agent learns the repo rule, the other misses it, and your docs have a split-brain problem.

7:52 Classic. Yeah, and nobody notices until the two files already disagree. The failure isn't the file name, it is letting two instruction sources drift apart. But there is one more distinction, and it is easy to blur. `CLAUDE.md` is instructions you write. Auto memory is notes Claude writes for itself, from corrections, preferences, and patterns it picks up. Hmm, wait. So if memory already carries things across sessions, why bother writing instructions at all? Because they have different jobs. Say Claude learned to rerun one flaky test before investigating.

8:26 Memory can hold that note. But if that is team policy, it belongs in instructions. Yeah. Memory has loading limits and upkeep, so you don't lean on it for deliberate project policy. Basically, memory remembers what happened. Instructions tell the agent how to behave next. And here is what nobody likes admitting: instructions age. The test runner changes. The repo moves. The team drops a helper. The file still says the old thing. Whoa, that is worse than a missing note. Now the agent follows stale confidence.

8:59 Sure. And someone always shrugs, it's just docs, who cares if it drifts a little. But treat `CLAUDE.md` like collaboration source code. Review it when workflows change. Delete rules that stopped mattering. Keep it small enough that someone actually notices when it is wrong. So stale instructions are behavior debt. They steer the next run toward yesterday's truth. Exactly. Stale context makes the agent confidently wrong, and that costs you more than any missing rule ever would. So keep the starter file surprisingly short.

9:30 One section for commands. One for architecture. One for code conventions. One for safety rules. One for the links or imports worth loading. And if you have nothing yet, let's say a repo with 0 docs, use slash init as a draft generator. Let Claude inspect the repo and propose a starting file, then edit it like any other generated artifact. Consider a brand-new service with no docs. Slash init can discover package files and directory names, but it cannot know which workflow the team trusts, which shortcut is dangerous, or which so-called obvious rule has burned you three times before. The human edit is the point.

10:07 Right. The draft gets you moving, but the human edit decides what is actually true. So, bottom line: stop re-teaching the repo every session. It is not glamorous. It is just persistent, reviewable context. But that is the whole reason it works. It nudges each session toward the way your project actually operates. Coming next, we open the hood on how Claude Code explores a codebase: search, read, narrow, and act, without a hidden index doing the work for it. Thanks for listening to Learning Podcasts.