Summary
A qualified C# graph query can resolve the requested definition correctly and then attach unrelated calls that share only the leaf name. Those rows are reported as confirmed, non-heuristic graph evidence and also inflate hotspot counts.
This is a correctness problem: qualified navigation currently produces confident false positives.
Reproduction
Verified against the complete graph built from origin/main at 8d537125aae747c1008ad31b3d59364cb43652f0 with cdidx 1.42.0:
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll callers \
ExclusiveFileLock.Open --exact-name --json --limit 10 \
--db .cdidx/codeindex.db
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll impact \
ExclusiveFileLock.Open --exact-name --json --limit 10 \
--db .cdidx/codeindex.db
The definition resolves to src/CodeIndex/Cli/ExclusiveFileLock.cs::Open, but callers include, for example:
PackageNormalizeCli.NormalizePackage, which calls ZipFile.Open;
- import/archive helpers whose
Open calls target other APIs;
DbContext paths that call SqliteConnection.Open.
impact reports these as confirmed_count: 10, hint_count: 0, and heuristic: false. inspect ExclusiveFileLock.Open exposes only the small set of actual references. The same unresolved leaf-name aggregation inflates symbol-specific hotspots counts for common names such as Open.
Expected behavior
- Resolved/confirmed graph rows must be tied to the requested symbol identity, not only
callee_name == "Open".
- Unresolved same-name edges may be exposed as bounded hints, but must be labeled heuristic/unresolved and must not contribute to confirmed counts.
- Symbol-specific hotspot counts must use resolved identity. Any unresolved-name bucket must be separate and visibly lower confidence.
- Unqualified discovery queries may retain useful broad matching without weakening the contract of a qualified query.
Implementation guidance
Treat this as one PR because callers, impact, and hotspots consume the same edge-resolution contract.
- Prefer persisted or query-time target symbol IDs/container identity for uniquely resolved edges.
- Keep an explicit unresolved state; do not convert a leaf-name match to confirmed merely because the query root resolved.
- Share resolution-aware aggregation across graph traversal and hotspot ranking to prevent future drift.
- Define deterministic behavior for overloads, partial types, multiple definitions, external APIs, aliases, and incomplete extraction.
- Preserve bounded execution and expose counts for confirmed vs unresolved/hint evidence.
- Avoid dropping unresolved data globally: it remains valuable for broad search when honestly classified.
Likely areas include DbReader.GraphQueries.cs, DbReader.ImpactTraversal.cs, graph edge persistence/resolution, and hotspot aggregation.
Required tests
Add a compact C# fixture containing:
- two unrelated classes with the same method name;
- a qualified query for one class;
- an overload;
- a uniquely resolvable edge;
- an intentionally unresolved external edge.
Assert parity across references, callers, impact, and hotspots: only identity-matching rows/counts are confirmed. Also test incomplete-graph/cap metadata and unqualified fallback behavior. Add English and Japanese changelog fragments and update graph JSON contract docs if fields/semantics change.
Regression history
This is a direct residual/regression of the identity-resolution work in #4569 and the same-name overmatch across references/callers/impact/hotspots tracked in #3894. Earlier related work includes qualified graph queries in #2819 and hotspot same-name inflation in #151. All are closed; no open exact duplicate was found.
Summary
A qualified C# graph query can resolve the requested definition correctly and then attach unrelated calls that share only the leaf name. Those rows are reported as confirmed, non-heuristic graph evidence and also inflate hotspot counts.
This is a correctness problem: qualified navigation currently produces confident false positives.
Reproduction
Verified against the complete graph built from
origin/mainat8d537125aae747c1008ad31b3d59364cb43652f0with cdidx 1.42.0:The definition resolves to
src/CodeIndex/Cli/ExclusiveFileLock.cs::Open, but callers include, for example:PackageNormalizeCli.NormalizePackage, which callsZipFile.Open;Opencalls target other APIs;DbContextpaths that callSqliteConnection.Open.impactreports these asconfirmed_count: 10,hint_count: 0, andheuristic: false.inspect ExclusiveFileLock.Openexposes only the small set of actual references. The same unresolved leaf-name aggregation inflates symbol-specifichotspotscounts for common names such asOpen.Expected behavior
callee_name == "Open".Implementation guidance
Treat this as one PR because callers, impact, and hotspots consume the same edge-resolution contract.
Likely areas include
DbReader.GraphQueries.cs,DbReader.ImpactTraversal.cs, graph edge persistence/resolution, and hotspot aggregation.Required tests
Add a compact C# fixture containing:
Assert parity across
references,callers,impact, andhotspots: only identity-matching rows/counts are confirmed. Also test incomplete-graph/cap metadata and unqualified fallback behavior. Add English and Japanese changelog fragments and update graph JSON contract docs if fields/semantics change.Regression history
This is a direct residual/regression of the identity-resolution work in #4569 and the same-name overmatch across references/callers/impact/hotspots tracked in #3894. Earlier related work includes qualified graph queries in #2819 and hotspot same-name inflation in #151. All are closed; no open exact duplicate was found.