Claude Code was not reading sibling repositories' CLAUDE.md — 18 measured sessions from a cross-repo workspace
Introduction
I work across several projects with a single AI assistant. Beyond the directory it was launched from, other projects’ directories are registered as “additional working directories”, so whichever one I start in, I can read and write in any registered project. That practice itself was settled in advance as policy, and it has not wavered.
The problem lay elsewhere. Each project has a rules file carrying the cautions specific to that project. That file, which is supposed to be “loaded automatically when needed”, was in fact never once loaded while I was working in a project other than the one I had launched from. This is a record of pinning down that blank, mechanically, from the observation logs.
The official conditional clause — how far does “subdirectories” reach?
For automatic loading of this rules file, the official documentation states the following condition explicitly.
“Files in subdirectories load on demand when Claude reads files in those directories”
“in subdirectories under your current working directory”
What gets “loaded automatically when needed” is limited to subdirectories under the current launch directory. A project registered as an additional working directory and located somewhere other than where you launched (a sibling project) does not meet that condition.
Measurement — mechanically aggregating all 18 log entries
Rather than judging by assumption, I aggregated the files actually loaded from the observation logs. The scope was 7 working sessions, 18 file-loading events in total.
Kinds of settings file actually loaded (observation logs: 18 events, 7 sessions)
Rules file common to every project … 18
Launch project's own rules file … 18 (subset)
Sibling project's own rules file … 0
Within those same sessions I edited six or more files on the sibling project’s side, and even moved the working directory over there temporarily. Even so, the sibling project’s own rules file came to 0. The logging mechanism itself was working normally, so this can be settled as “it was never loaded in the first place”, not “the record was missing”.
Cross-repo workspace (vertical = one session's progress, horizontal = which project is touched, nested = what gets loaded then)
Session starts (one AI assistant, several target projects)
│
├─▶ Launch directory = project A
│ ├─ Rules common to every project ──── loaded (measured 18/18)
│ └─ A's own rules ───────────────── loaded (measured 18/18)
│ └─ "cross-check the port number and an identifying query before touching" is in force
│ │
├─▶ Additional working directory = project B (sibling) │
│ │ The DB's logical name is the same as A's. Only the port differs
│ ├─ Rules common to every project ──── loaded │
│ └─ B's own rules ───────────────── not loaded (measured 0/18)
│ │ * after editing six or more of B's files in the same │
│ │ session, and moving the working directory to B too │
│ └─ the same cross-check procedure is not in force on B's side
│ │ │
▼ ▼ ▼
Whichever branch you come from, you arrive at "operating on a DB with the same logical name" ◀──┘
│ (the reassurance from A's side gets carried over to B's judgement)
│
└─▶ Mechanically aggregate the 18 log entries ── settle that it is not being read
│
└──(return edge)──▶ back to the start, re-read the scope of "when needed"
└─ the official conditional clause = limited to under the launch directory
What was written in the blank
There is a reason this did not stay a mere detail of the specification. Two independent systems’ databases both carried the same logical name, with a configuration in which only the port number differed. Both projects’ own rules files carried a procedure written precisely to prevent that mix-up: before operating on a database, cross-check the connection against the port number and an identifying query.
That procedure was added in the first place after an incident in which the two really were nearly mixed up, as a measure against recurrence. Following the records, both projects’ own rules files were newly created on the same day as the incident. In other words, those two files were “countermeasures put in place by someone who knew the danger”.
And yet the very file carrying that countermeasure does not get loaded while work is happening on the sibling project’s side. The countermeasure I had written was structured so as not to be read in the very situation where it was most needed — that is what the 18 observations revealed afterwards.
⚠️ To be precise about the order: the incident happened before the countermeasure was written, and the loading blank was observed about a month later. The causal claim “the rule was written but not read, and that is why the incident happened” does not hold. What can be said goes only as far as “a countermeasure put in place after the incident was in a shape that would not take effect in the same situation”. As a matter of fact I consider this the more awkward version — because whoever writes a countermeasure is reassured the moment they write it.
Ways to close it — three candidates
Reading further into the official documentation turned up three candidates for closing this blank.
| Candidate | Content |
|---|---|
| A dedicated environment variable | A setting that includes additional working directories’ rules files in what gets loaded. But every registered project’s file loads together, so the standing overhead rises |
| Path-scoped rules | A finer-grained rules mechanism that loads only “when you touch a file matching a particular pattern”. This too, however, works only under the launch directory |
| Align the launch directory to a common parent | Put every project under one common directory, so that the “subdirectory” condition itself is satisfied |
The third candidate looks like the front-runner, but whether to actually adopt it is an operational judgement, and as of this article it is not settled. What is settled here is only the fact that the sibling projects’ rules are not being read, and the structure that there are several candidates, each with its own trade-offs.
Confirm that a rule “that should work” actually works, separately from having written it
Writing a safety-check procedure into a rules file, and that rule actually being in force, turned out to be separate matters. The cross-repo workspace practice itself is reasonable, and needs no change. But only by checking the scope of “when needed” in that specification against observation logs rather than assumption did it become clear where the safety-check procedure I had written was in force and where it was not.
Why We Separated the Admin Panel and Customer App into Different Repositories — Gains and Tradeoffs
What is born the moment you write a rule is not a guarantee that it will be followed, but rather the reassurance of having written it. What the number 18 taught me was not a detail of the specification but that that reassurance needs peeling back once, against the logs rather than against my own assumption.