feat: follow inclusion graph from memory files to expand /reflect target scope#35
Open
alonl wants to merge 1 commit into
Open
feat: follow inclusion graph from memory files to expand /reflect target scope#35alonl wants to merge 1 commit into
alonl wants to merge 1 commit into
Conversation
…gets
Memory files (CLAUDE.md, AGENTS.md, rule files) often delegate guidance
to other docs via Claude Code's @-include syntax or standard markdown
links. Those docs were previously outside /reflect's scope, so a
learning that belonged in standards.md drifted into CLAUDE.md.
find_claude_files() now does a bounded BFS over @-includes and inline
markdown links from the discovered memory files and surfaces the reached
.md docs as type='referenced' entries with referenced_from + depth
provenance. Routing UI offers them like CLAUDE.md targets.
- Bounded depth (default 3 hops), node fanout (default 200), per-file
read (1 MiB)
- BFS dequeue order guarantees shortest-path provenance
- Cycle-safe via visited set
- Skips fenced code blocks, external URLs, same-file anchors
- Resolved paths confined to {root_dir, get_claude_dir()} so pasted-in
[x](/etc/passwd.md) can't surface arbitrary filesystem paths
- .md suffix re-checked on the resolved path (rejects evil.md → /etc/passwd
symlinks)
Closes BayramAnnakov#34
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
a45c298 to
87c604e
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.
Closes #34.
Summary
@filenameincludes or markdown links. Today those docs are outside/reflect's scope, so a learning that belonged instandards.mddrifts into CLAUDE.md.find_claude_files()now performs a bounded BFS over@-includes and inline markdown links from the discovered memory files and surfaces the reached.mddocs astype='referenced'entries withreferenced_from+depthprovenance.Concrete example
After this change, all four files are reachable as
/reflecttargets.Constraints honored
DEFAULT_INCLUSION_DEPTH = 3DEFAULT_INCLUSION_MAX_NODES = 200MAX_INCLUSION_FILE_BYTES = 1 MiBtest_bfs_shortest_path_provenance```and~~~https:,mailto:, …)[text](#section); in-page anchors stripped from path links.md-only targets — checked on both the raw target and the resolved path, so a symlinkedevil.md → /etc/passwdis rejected{root_dir, get_claude_dir()}; pasted-in[x](/etc/passwd.md)can't surface arbitrary filesystem paths(?<![\w.])@…lookbehind prevents matchingfoo@bar.md[text][ref]is intentionally not handledAPI
find_claude_files(root_dir, follow_includes=True, max_depth=3, max_nodes=200)— defaults on; passfollow_includes=Falseormax_depth=0to opt out.'referenced'entries carryreferenced_fromanddepth.Files changed (~783 LOC: 282 impl + 495 tests + 11 docs)
scripts/lib/reflect_utils.py—_parse_inclusions,_resolve_inclusion,_format_relative_path,_follow_inclusion_graph, plus thefind_claude_files()integrationtests/test_memory_hierarchy.py— 34 new tests across 4 classes covering parsing, resolution, traversal, security clamps, and theread_all_memory_entriesintegrationcommands/reflect.md— addsReferenced Docsrow to target table, updates type list, extends--targetsdisplay, adds routing hintREADME.md— one bullet under Multi-Target SyncTest plan
RELEASING.md(real[RELEASING.md](RELEASING.md)link inCLAUDE.md)capture_learning.pyandcheck_learnings.pyhooks still run/tmp→/private/tmpsymlink handledBackward compatibility
referenced_from,depth) only on'referenced'entriesassertIn("root", types)continue to pass🤖 Generated with Claude Code