fix(build): prefer higher-info relation on same-pair edge collapse - #2397
fix(build): prefer higher-info relation on same-pair edge collapse#2397arimu1 wants to merge 1 commit into
Conversation
Simple Graph/DiGraph last-write-wins after a deterministic sort by (source, target, relation) made alphabetical order delete calls when a references edge shared the same node pair (Graphify-Labs#2391). Prefer higher- information relations (calls > references, etc.); equal priority keeps the first-seen edge so Graphify-Labs#1061 direction preservation stays intact.
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 introduces a relation-priority scheme in build_from_json to control which edge survives when a simple Graph/DiGraph collapses parallel edges on the same node pair. It adds a _RELATION_PRIORITY table and _relation_priority helper, and modifies the edge-adding logic so that when two edges share a pair but have different relations, the higher-priority relation is kept instead of relying on alphabetical last-write-wins (covering both undirected and directed cases). New tests in test_build.py exercise these collapse scenarios (e.g., calls vs references, indirect_call vs contains, sole-relation retention, and the directed variant).
Worth a look
- Undirected reverse-pair branch never applies relation priority —
graphify/build.py:1075· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 804 functions depend on the 202 functions this change touches.
Health — this change adds coupling hotspots:
- worse:
build_from_json()— 146 callers, 15 callees
Verification — 804 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: 603 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
Fixes #2391.
build_from_jsonsorts edges by(source, target, relation)then inserts them into a simplenx.Graph/nx.DiGraphwith last-write-winsadd_edge. That made alphabetical order the survivor whenever two different relations landed on the same node pair — soreferencesalways overwrotecalls("calls" < "references"), silently deleting the higher-information call edge.This adds a small
_RELATION_PRIORITYtable so the higher-information relation wins the collapse instead. Unlisted relations score 0 (first-wins), so obscure types do not pick up a new alphabetical bias. Equal priority keeps the first-seen edge, same spirit as the #1061 reverse-direction guard (left intact).Out of scope (can follow up if wanted):
--multigraphwiring (related open PR [build] Add multigraph option to preserve parallel edges #709)also_relationsattributeTest plan
uv run pytest tests/test_build.py -q— 72 passedcalls+referencesboth input orders → survivor iscallswithsource_location=L271indirect_callbeatscontainsreferencesstill keptdirected=Truecallsdirection test still greenNotes