Let explicit ignore rules exclude memory notes (issue 3637) - #3639
ayushcodes10 wants to merge 3 commits into
Conversation
detect() always scanned the memory directory inside the output directory and bypassed every ignore check there, leaving no way to keep a specific saved query note out of the graph. A deliberate dot graphifyignore or exclude flag rule is now honored inside that directory, while a plain dot gitignore entry (the documented convention for the whole output directory) still cannot drop notes by default, matching the protection already given to the converted sidecar directory. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Covers the default (a plain dot gitignore entry on the whole output directory still cannot drop a memory note), the new behavior (a deliberate dot graphifyignore rule can exclude one note or a whole subdirectory of notes), and a boundary check confirming a plain dot gitignore match alone is not treated as deliberate enough to exclude a note by itself. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Graphify reviewed this change.
Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).
Formal verification. No changes could be formally verified in this run.
Graphify review — findings
Makes detect() honor deliberate .graphifyignore/--exclude rules inside graphify-out/memory/ while keeping memory notes immune to plain .gitignore entries. Both the directory-level prune and the per-file check now run _explicitly_ignored_for_scan against only the explicit patterns, so users can drop a specific note or subpath from the graph without a generic VCS ignore silently removing saved query notes.
No blocking issues surfaced. 3 lower-confidence candidates did not survive cross-model review.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 2725 functions depend on the 747 functions this change touches.
Health — this change adds coupling hotspots:
- new:
extract()— 645 callers, 45 callees - new:
_rebuild_code()— 129 callers, 54 callees - new:
detect()— 116 callers, 16 callees - new:
_extract_generic()— 18 callers, 29 callees - new:
save_manifest()— 40 callers, 11 callees - new:
extract_files_direct()— 17 callers, 20 callees - new:
extract_js()— 85 callers, 4 callees - new:
extract_xaml()— 19 callers, 17 callees - …and 45 more — each is listed as a finding
Verification — 2725 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 1196 function(s) in the blast radius were not formally verified this run
Test selection
Test selection
286 of 286 test file(s) selected (100%) via static blast radius.
Escalated to a full run for safety — the selection is not trustworthy on its own (see below). CI should run the whole suite.
tests/test_affected_cli.py— full-run-safetytests/test_affected_member_seed.py— full-run-safetytests/test_agents_platform.py— full-run-safetytests/test_analyze.py— full-run-safetytests/test_anthropic_custom_endpoint.py— full-run-safetytests/test_antigravity_install.py— full-run-safetytests/test_apm_fallback_version.py— full-run-safetytests/test_architecture_doc.py— full-run-safetytests/test_astro_extraction.py— impact, full-run-safetytests/test_astro_import_ids.py— full-run-safetytests/test_atomic_canvas_export.py— full-run-safetytests/test_atomic_version_stamp.py— full-run-safetytests/test_atomic_writes.py— impact, full-run-safetytests/test_backend_env_isolation.py— full-run-safetytests/test_backend_extras.py— full-run-safetytests/test_benchmark.py— full-run-safetytests/test_benchmark_raw_graph.py— full-run-safetytests/test_build.py— impact, full-run-safetytests/test_build_merge_dedup_scope.py— full-run-safetytests/test_build_merge_hyperedges_and_prune.py— full-run-safetytests/test_build_merge_shrink_guard.py— full-run-safetytests/test_builtin_global_type_refs.py— full-run-safetytests/test_cache.py— full-run-safetytests/test_callflow_html.py— full-run-safetytests/test_cargo_introspect.py— full-run-safetytests/test_carried_hyperedge_remap.py— full-run-safetytests/test_case_sensitive_resolution.py— full-run-safetytests/test_charmap_encoding.py— impact, full-run-safetytests/test_chunking.py— impact, full-run-safetytests/test_cjs_module_extension.py— impact, full-run-safetytests/test_claude_cli_backend.py— impact, full-run-safetytests/test_claude_md.py— full-run-safetytests/test_cli_broken_pipe.py— full-run-safetytests/test_cli_export.py— full-run-safetytests/test_cli_help.py— full-run-safetytests/test_cluster.py— full-run-safetytests/test_codebuddy.py— full-run-safetytests/test_community_hub_labels.py— full-run-safetytests/test_community_labels_skill.py— full-run-safetytests/test_confidence.py— full-run-safetytests/test_corrupt_graph_json.py— full-run-safetytests/test_cpp_nested_and_cli.py— impact, full-run-safetytests/test_cpp_objc_cross_file_calls.py— full-run-safetytests/test_cpp_preprocess.py— full-run-safetytests/test_cross_extension_reexport_self_cycle.py— full-run-safetytests/test_cross_language_call_resolution.py— full-run-safetytests/test_cross_repo_external_call_guards.py— full-run-safetytests/test_cross_repo_member_calls.py— full-run-safetytests/test_cross_repo_shared_types.py— full-run-safetytests/test_csharp_call_site_generic_args.py— full-run-safety- … and 236 more
non-code file(s) changed (
CHANGELOG.md) → running the full suite for safety (a code graph can't see config/fixture/data deps)
changed code file(s) with no mapped test (
CHANGELOG.md) — a coverage gap or a missing link — running the full suite rather than only the selected tests
Selection is safe under the controlled-regression assumption; always-run tests + a periodic full run are the backstops. Advisory — it never changes the check verdict.
Formal verification
Could not verify: Could not verify detect.
The verifier did not have enough to check detect, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: no capturable inputs from the test suite; property tier: parameter `root` is annotated `Path` — outside the synthesizable primitive/collection set
· 53 more finding(s) on lines outside this diff (see the check run).
What
detect()unconditionally includedgraphify-out/memory/and exempted it from every ignore mechanism, so there was no supported way to keep a specific saved query note out of the graph, as described in issue #3637.Fix
Adds
_explicitly_ignored_for_scan(), which checks only the.graphifyignore/--excludepatterns (never a plain.gitignoreentry). Insidegraphify-out/memory/:.gitignoreentry (e.g. the documentedgraphify-out/convention) still cannot drop a memory note — the same protection already given to theconverted/sidecar directory for issue Office sidecars in graphify-out/converted/ are silently dropped when graphify-out is gitignored #3504..graphifyignore/--excluderule targeting a specific note or subdirectory is now honored, both at the directory pruning level and the file level.This follows option 1 from the issue ("honor
_ignored_for_scaninside the memory dir") while preserving the reason the hard include exists in the first place: without it, the documented "gitignore the whole output dir" convention would silently drop every memory note for anyone following the docs, not just the ones a user actually wants excluded.Tests
Four new regression tests in
tests/test_detect.py:.gitignoreentry on the whole output dir (baseline, matches the existing converted/ sidecar test).graphifyignorerule can exclude a specific memory note.graphifyignorerule can exclude a whole memory subdirectory.gitignorematch alone (not.graphifyignore/--exclude) is not treated as deliberate enough to exclude a noteFull suite: 5625 passed, 68 skipped, 0 failures.
Fixes #3637