Repo/version: graphifyy v0.9.1 · extract.py cross-file call resolver (~L13455–13530)
What happens
The resolver indexes every definition of a symbol by normalized label (global_label_to_nids). A callee with exactly 1 definition resolves; a callee with 2+ definitions requires import evidence to disambiguate, else continue (skip). For languages with no per-symbol import statement — PowerShell (functions autoload via the .psm1), C globals, etc. — that evidence never exists, so every cross-file call to a 2+-definition symbol is silently dropped.
This collides with the standard mock-by-redefinition test pattern. Each Pester test file declares a local stub function Invoke-Thing { … }, adding a same-named definition node.
Minimal repro
# src/Invoke-Thing.ps1
function Invoke-Thing { 'real' }
# tests/Thing.Tests.ps1
function Invoke-Thing { 'stub' } # mock stub -> 2nd definition
# src/Use-Thing.ps1
function Use-Thing { Invoke-Thing } # expected: Use-Thing --calls--> Invoke-Thing
Expected: one calls edge. Actual: 0 — Invoke-Thing has 2 definitions and no import evidence, so the edge is skipped.
Real-world impact (measured)
In a PowerShell + Pester repo, the single DB-access primitive (called from 121 source files) is defined 76 times (1 source + 75 Pester stubs). Built graph: 0 inbound calls edges → absent from god-node ranking. Rebuilding with test files excluded restores 114 inbound edges and ranks it #1 god node. A control function defined only twice keeps its edges throughout.
Capture failure is proportional to importance — the more central a function, the more test files mock it, the more completely its call graph is erased. God-node detection goes blind to exactly the functions it exists to surface.
Why it generalizes
Not Pester-specific: the skip fires for any ambiguous callee lacking import evidence — PowerShell module autoload, C global functions, any import-less resolution with same-named definitions.
Suggested direction (a guard ordering, not a defect of omission)
The continue is the deliberate #543/#1219 precision guard against over-connecting common short names. The fix is to filter test-file definitions out of the candidate set before the ambiguity branch: when a callee has exactly one non-test definition, resolve to it. Genuine multi-source collisions (overloads, interface+impl) retain 2+ candidates and stay guarded. The hard part is a robust cross-language test-file classifier (*.Tests.ps1, *_test.py, *.spec.ts, tests/, …) — happy to send a PR if that direction works for you, but you own where the insertion point goes.
Repo/version:
graphifyyv0.9.1 ·extract.pycross-file call resolver (~L13455–13530)What happens
The resolver indexes every definition of a symbol by normalized label (
global_label_to_nids). A callee with exactly 1 definition resolves; a callee with 2+ definitions requires import evidence to disambiguate, elsecontinue(skip). For languages with no per-symbol import statement — PowerShell (functions autoload via the.psm1), C globals, etc. — that evidence never exists, so every cross-file call to a 2+-definition symbol is silently dropped.This collides with the standard mock-by-redefinition test pattern. Each Pester test file declares a local stub
function Invoke-Thing { … }, adding a same-named definition node.Minimal repro
Expected: one
callsedge. Actual: 0 —Invoke-Thinghas 2 definitions and no import evidence, so the edge is skipped.Real-world impact (measured)
In a PowerShell + Pester repo, the single DB-access primitive (called from 121 source files) is defined 76 times (1 source + 75 Pester stubs). Built graph: 0 inbound
callsedges → absent from god-node ranking. Rebuilding with test files excluded restores 114 inbound edges and ranks it #1 god node. A control function defined only twice keeps its edges throughout.Capture failure is proportional to importance — the more central a function, the more test files mock it, the more completely its call graph is erased. God-node detection goes blind to exactly the functions it exists to surface.
Why it generalizes
Not Pester-specific: the skip fires for any ambiguous callee lacking import evidence — PowerShell module autoload, C global functions, any import-less resolution with same-named definitions.
Suggested direction (a guard ordering, not a defect of omission)
The
continueis the deliberate #543/#1219 precision guard against over-connecting common short names. The fix is to filter test-file definitions out of the candidate set before the ambiguity branch: when a callee has exactly one non-test definition, resolve to it. Genuine multi-source collisions (overloads, interface+impl) retain 2+ candidates and stay guarded. The hard part is a robust cross-language test-file classifier (*.Tests.ps1,*_test.py,*.spec.ts,tests/, …) — happy to send a PR if that direction works for you, but you own where the insertion point goes.