Repository navigation
Conversation
The settings pin shuts the route by which the unpinned CLI attached a subdirectory's memory once the run read a file below it, so since the pin a nested CLAUDE.md, .claude/CLAUDE.md or unscoped rule never reached the model. Against Claude 2.1.263 an --add-dir naming that subdirectory loads all three in place before the first request, labelled as project instructions, with what its rules import, a scoped rule's imports included, and none of its settings. Each build now walks below the cwd, breadth first, never through a link and never into .git, node_modules or another dot-directory, and collects every directory that holds such memory, or whose only memory is scoped rules that import something. When all of them together fit 16 directories and 32 KiB, the files their memory imports counted too, each rides the one variadic --add-dir after the workspace and its repositories, shallowest first. Past that none does: a partial pick would load arbitrary packages up front while the one the run works in stays out, and the launch says so. The outside-link guard checks each directory as the walk holds it, which is how its imports are counted, so it reads at most 16 nested directories' memory per build beside those of scoped rules alone; each that reaches outside the workspace is left out by name. A directory whose path holds anything but letters, digits and . _ @ + - / is not added, since the name rides the argv. The walk stops at 32 levels and 20000 entries, and says so. Those bounds left their sum open, and a link target may repeat d/../ any number of times, so one lookup through a long chain walked tens of thousands of components: a thousand such links, or sixteen in-place directories importing them, held the synchronous build for minutes. One budget per build now covers the walk and every directory's check: 65536 distinct lookups, 1048576 path components walked and 64 MiB read, each path resolved once. The workspace and its repositories are checked first; past the budget the walk stops, every directory not yet checked is left out, and the launch says so once. Which rules count as unscoped mirrors how the pinned CLI reads paths: the fence, YAML with its quote-and-untab retry, core-schema scalar typing, the top-level comma split, brace expansion within the CLI's budget, a trailing /** dropped and ** alone meaning unconditional. A rule is classified from its first 4 KiB, read on to the fence's close when that opens one, up to 4 MiB; past that it is unclassified and said. A rules entry that links outside the cwd counts for nothing, as the CLI skips it. A tree with no nested memory builds the argv it built before. The existing repository-config arms now expect sub/CLAUDE.md in the first request. New arms pin against the real binary that nested memory loads in place, single- and multi-repo, with its import, its .claude/CLAUDE.md, its unscoped rule and a scoped rule's import; that a scoped rule, a ~ import, node_modules, a dot-directory, a linked-out CLAUDE.md, an outside import and hostile settings beside it do not; and that one directory over the budget loads none. With the guard limited to the roots, the CLI hands the linked-out file to the model.
ppXD
force-pushed
the
fix/load-nested-claude-memory-in-place
branch
from
October 6, 2026 18:48
a3230e4 to
a07d31e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Nested memory loads in place. Under the settings pin, Claude 2.1.263 no longer attaches a subdirectory's
CLAUDE.md,.claude/CLAUDE.mdor unscoped rule when the run reads below it. An--add-dirnaming that subdirectory does load all of it before the first request:Each build walks below the cwd: breadth first, never through a link, never into
.git,node_modulesor a dot-directory. It adds every such directory after the workspace and its repositories, shallowest first, when all of them fit 16 directories and 32 KiB, imported bytes included. Past that none is added and the launch says so. A directory whose only memory is a scoped rule that imports a file counts too.Containment and cost. Each directory the walk would add passes the same outside-link guard as a root (
ClaudeWorkspaceMemory.Guard), as it is found.ClaudeWorkspaceMemory.Budget.cs) covers the walk and every check: 65536 distinct lookups, 1048576 path components walked and 64 MiB read, with every path resolved once.PhysicalPath.Filespends components from anAllowance.d/../made one lookup cost about 15 ms, and a crafted tree held the synchronous build for minutes.Which rules count.
ClaudeRuleScope.Readmirrors the CLI's frontmatter parse.Test plan
RealHarnessWorkspaceMemoryTests6/6.RepositoryConfigE2ETests9/9.imp/on the--add-dir. Its only memory is a scoped rule that importsimp/guide.md.nested-in-place claude-code single-repo/multi-repo Confinedandnested-over-budget claude-code single-repo Confined[repo-config-e2e] ran non-root nested-in-place claude-code single-repo Standard uid=1654