Documentation/loader: `paths:` YAML frontmatter not honored at user-level `~/.claude/rules/` (works at project scope)
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
The Memory docs document two related primitives:
paths:YAML frontmatter on rule files in.claude/rules/— "Path-scoped rules trigger when Claude reads files matching the pattern, not on every tool use."- User-level rules at
~/.claude/rules/— "Personal rules in~/.claude/rules/apply to every project on your machine."
The docs example for paths: is shown at project scope. The docs do not explicitly state whether paths: is supported at user scope.
Empirical result on Claude Code 2.1.116:
- Project-level
<project>/.claude/rules/foo.mdwithpaths:frontmatter: works as documented. The scoped rule loads when Claude reads a matching file and is suppressed when it doesn't. - User-level
~/.claude/rules/foo.mdwithpaths:frontmatter: does not load. The same glob shape that works at project scope produces no rule injection at user scope, regardless of cwd or which file Claude reads. A control rule at the same user-level path with nopaths:field loads correctly, proving the user-level loader is otherwise active.
So either:
- (a) Loader bug — user-level
paths:should work but doesn't. - (b) Documentation gap —
paths:is project-only by design and the docs should state this explicitly in the user-level rules section.
Either way, the current behavior is silent: a rule file with paths: frontmatter at ~/.claude/rules/ neither loads nor emits any warning.
What Should Happen?
Pick one and document it:
- Honor
paths:at user scope too — load conditionally on file-read pattern, same semantics as project scope. OR - Keep
paths:project-only — emit a one-time stderr warning when a rule file withpaths:frontmatter is found under~/.claude/rules/, and add a sentence to the user-level rules section of the Memory docs ("paths:frontmatter is honored only on project-level rules").
Error Messages/Logs
No errors. The user-level rule with `paths:` frontmatter is silently dropped from context. No stderr warning, no log line. The only signal is that an instructed sentinel string never reaches the model — detectable only via `claude --print` probing with a known-good control rule alongside.
Steps to Reproduce
Minimal reproduction. Paste into a clean shell:
# 1. Set up a temp project tree
mkdir -p /tmp/cc-paths-repro/{.claude/rules,foo,bar}
cd /tmp/cc-paths-repro
echo "FOO_FILE" > foo/target.txt
echo "BAR_FILE" > bar/target.txt
# 2. Project-level rules (control case — these work)
cat > .claude/rules/_proj-paths.md <<'EOF'
---
paths:
- "foo/**"
---
You have been instructed about the sentinel: SENTINEL_PROJ_PATHS
If asked to list sentinels you have been instructed about, include this one.
EOF
cat > .claude/rules/_proj-control.md <<'EOF'
You have been instructed about the sentinel: SENTINEL_PROJ_CONTROL
If asked to list sentinels you have been instructed about, include this one.
EOF
# 3. User-level rules (the bug surface)
mkdir -p ~/.claude/rules
cat > ~/.claude/rules/_user-paths.md <<'EOF'
---
paths:
- "foo/**"
---
You have been instructed about the sentinel: SENTINEL_USER_PATHS
If asked to list sentinels you have been instructed about, include this one.
EOF
cat > ~/.claude/rules/_user-control.md <<'EOF'
You have been instructed about the sentinel: SENTINEL_USER_CONTROL
If asked to list sentinels you have been instructed about, include this one.
EOF
# 4. Probe — read a file matching foo/**
claude --print "Read the file foo/target.txt. Then list any sentinel strings starting with SENTINEL_ that you have been instructed about. Output one per line, nothing else."
# 5. Cleanup
# rm -rf /tmp/cc-paths-repro
# rm ~/.claude/rules/_user-paths.md ~/.claude/rules/_user-control.md
# (remove ~/.claude/rules/ entirely if it didn't exist before this test)
Expected output (all four sentinels):
SENTINEL_PROJ_CONTROL
SENTINEL_PROJ_PATHS
SENTINEL_USER_CONTROL
SENTINEL_USER_PATHS
Actual output (the user-level path-scoped sentinel is missing):
SENTINEL_PROJ_CONTROL
SENTINEL_PROJ_PATHS
SENTINEL_USER_CONTROL
The two project-level rules behave correctly. The user-level control rule loads. The user-level rule with paths: frontmatter is silently dropped, even though the cwd and the file-read target both match the glob.
Additional shapes tested at user scope (all FAIL)
To rule out a glob-shape problem, three glob variants were tested at user scope independently — project-relative foo/**, recursive prefix **/foo/**, and absolute /abs/path/foo/**. None loaded. The asymmetry is not glob-shape sensitive; it is scope sensitive (project vs user).
Workaround
Place rules with paths: frontmatter under <project>/.claude/rules/ instead of ~/.claude/rules/. Project-scope path-scoping works as documented.
Environment
- Claude Code: 2.1.116
- Install method: Homebrew cask
claude-code(/opt/homebrew/Caskroom/claude-code/2.1.116/claude) - OS: macOS (Apple Silicon)
- Shell: zsh
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗