The structural source-graph diff is role-blind: a param → return change on the same edge reads as no change¶
Index: Known gaps — closed and moot
Status (2026-10-12): CLOSED. diff_source_graph now matches edges on relation_key() and reports a kept dependency's role change as a changed_edges entry (ADR-077 D4), or as role_unknown_edges when one side carries no role data. Public entries' role changes surface as public_dependency_role_changed. See the archive entry for the fix and its tests. Original write-up (recorded 2026-10-11 at 2a1ccb0c8, status OPEN) follows.
false-clean — When a public declaration keeps its dependency on a type but changes how it uses it (param → return, field → base), the structural added/removed edge diff is empty. A two-sided experiment (external review, 2026-10-11) confirmed a zero diff for param → return.
Scope of the gap¶
- Affects only consumers of the structural diff. ADR-046 D3's role coverage (
source_graph_findings._disagreeing_roles) is a separate path and is not claimed to be missing here. - Two role-distinct edges sharing one
(src, dst, kind)collapse onto one representative, so adding a second role is also invisible.
Why it is not a one-line switch to relation_key()¶
Callers of diff_source_graph were promised the coarse key (ADR-046 D1, "existing callers ... are unaffected"). A role-keyed diff turns one role change into a removed+added pair, which every consumer would read as two dependency changes. The fix needs a changed-role result shape, and that shape belongs with the exposure-mode model in ADR-077 D4.