fix: normalize definition_file paths - #3242
Conversation
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
Relativizes definition_file alongside source_file everywhere a graph's paths are made portable — in build_from_json, in extract (absolute→canonical remap and backslash→posix normalization), and in watch's _relativize_source_files and _rebase_relative_source_files via a shared _PORTABLE_PATH_KEYS tuple — so the implementation site recorded when a C/C++/ObjC decl/def pair merges ships repo-relative instead of leaking the build machine's absolute path. The scope guard still leaves a definition_file outside the watched tree untouched.
No blocking issues surfaced. 3 lower-confidence candidates did not survive cross-model review.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 3273 functions depend on the 1399 functions this change touches.
Health — this change adds coupling hotspots:
- new:
extract()— 520 callers, 43 callees - new:
_rebuild_code()— 113 callers, 50 callees - new:
build_from_json()— 193 callers, 18 callees - new:
build_merge()— 62 callers, 13 callees - new:
to_obsidian()— 36 callers, 13 callees - new:
extract_files_direct()— 17 callers, 20 callees - new:
extract_js()— 85 callers, 4 callees - new:
extract_xaml()— 19 callers, 17 callees - …and 64 more — each is listed as a finding
Verification — 3273 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: 2876 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify build\_from\_json.
The verifier did not have enough to check build\_from\_json, 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: not verifiable: all 6 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly NameError — names the real obstacle, not a sampling gap)
Could not verify: Could not verify extract.
The verifier did not have enough to check extract, 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: parameter `cache_root` is annotated `Path | None` — outside the synthesizable primitive/collection set
Could not verify: Could not verify \_rebase\_relative\_source\_files.
The verifier did not have enough to check \_rebase\_relative\_source\_files, 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: parameter `source_root` is annotated `Path` — outside the synthesizable primitive/collection set
Could not verify: Could not verify \_relativize\_source\_files.
The verifier did not have enough to check \_relativize\_source\_files, 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: parameter `root` is annotated `Path` — outside the synthesizable primitive/collection set
· 72 more finding(s) on lines outside this diff (see the check run).
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
Relativizes definition_file — the implementation site recorded when a C/C++/ObjC declaration and definition merge into one node — everywhere source_file is already made portable: in build_from_json, in extract's absolute-path normalization and backslash-to-posix pass, and in watch's _relativize_source_files and _rebase_relative_source_files (now driven by a shared _PORTABLE_PATH_KEYS). Without this the graph shipped the build machine's absolute definition path, so a reader on another checkout pointed at a file that isn't there.
No blocking issues surfaced. 3 lower-confidence candidates did not survive cross-model review.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 3273 functions depend on the 1399 functions this change touches.
Health — this change adds coupling hotspots:
- new:
extract()— 520 callers, 43 callees - new:
_rebuild_code()— 113 callers, 50 callees - new:
build_from_json()— 193 callers, 18 callees - new:
build_merge()— 62 callers, 13 callees - new:
to_obsidian()— 36 callers, 13 callees - new:
extract_files_direct()— 17 callers, 20 callees - new:
extract_js()— 85 callers, 4 callees - new:
extract_xaml()— 19 callers, 17 callees - …and 64 more — each is listed as a finding
Verification — 3273 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: 2876 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify build\_from\_json.
The verifier did not have enough to check build\_from\_json, 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: not verifiable: all 6 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly NameError — names the real obstacle, not a sampling gap)
Could not verify: Could not verify extract.
The verifier did not have enough to check extract, 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: parameter `cache_root` is annotated `Path | None` — outside the synthesizable primitive/collection set
Could not verify: Could not verify \_rebase\_relative\_source\_files.
The verifier did not have enough to check \_rebase\_relative\_source\_files, 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: parameter `source_root` is annotated `Path` — outside the synthesizable primitive/collection set
Could not verify: Could not verify \_relativize\_source\_files.
The verifier did not have enough to check \_relativize\_source\_files, 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: parameter `root` is annotated `Path` — outside the synthesizable primitive/collection set
· 72 more finding(s) on lines outside this diff (see the check run).
Summary
Fixes #3223 by ensuring
definition_fileis stored as a portable repo-relative path, consistent withsource_file.Previously, C/C++ declaration/definition merging copied the implementation's absolute
source_filedirectly intodefinition_file. This caused build-machine paths to leak into extracted graphs and made the field unusable when a graph was consumed from another machine or checkout.Changes
definition_filein the finalextract()path normalization so the extraction API does not return absolute in-tree paths.definition_fileinbuild_from_json()as defense-in-depth for loaded JSON.source_fileanddefinition_fileconsistently during watch/incremental relativization and rebasing.definition_file.Validation
C++ paired declaration/definition tests: 5 passed
Full watch suite: 137 passed, 9 skipped, 2 pre-existing Windows-specific failures
Targeted regression suites: 822 passed, 20 skipped, 4 pre-existing Windows-specific failures
git diff --check: passedVerified direct
extract()andbuild_from_json()both produce:source_file:Foo.hdefinition_file:Foo.cppThe Windows-specific failures are unrelated to this change and involve existing
cp1252, path-length, and active-working-directoryrmdirlimitations.