Fix case-only source path aliases on macOS - #2372
Conversation
There was a problem hiding this comment.
Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).
Graphify reviewed this change.
Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).
Graphify review — findings
This PR adds case-insensitive path alias handling to the graph reconciliation logic in graphify/watch.py. When a stored node's source path differs only by letter case from a currently scanned file, the code now attempts to confirm they point to the same on-disk file via os.path.samefile(), and if so treats the stored path as current rather than excluded—rebasing it to the scanner's canonical spelling. It also extends rebase_preserved to accept a mapping of canonical identities and builds a casefold lookup that discards ambiguous case-only collisions. On the test side, it adds test_reconcile_case_alias_uses_current_source_spelling, which monkeypatches samefile to simulate APFS case-insensitive behavior on case-sensitive CI and asserts the preserved node adopts the scanner's spelling without a fail-closed warning. The large set of renamed rationale_* test symbols appears to reflect surrounding test-file churn rather than substantive logic changes.
No blocking issues surfaced. 2 lower-confidence candidates did not survive cross-model review.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 363 functions depend on the 233 functions this change touches.
Health — this change adds coupling hotspots:
- worse:
_reconcile_existing_graph()— 3 callers, 10 callees
Verification — 363 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: 237 function(s) in the blast radius were not formally verified this run
· 1 more finding(s) on lines outside this diff (see the check run).
Summary: Recognize stored and scanned source paths that differ only by case when samefile proves they are the same disk object. Avoid false fail-closed retention warnings, rewrite preserved source_file values to the scanner's current spelling, and keep ambiguous casefold collisions fail-closed. Regression coverage: simulated APFS case-alias test; real macOS case-insensitive filesystem acceptance; full tests/test_watch.py passed with 85 passed and 2 skipped; ruff passed.