Background
PR #1395 added a static receiver fallback to resolveByMethodOrGlobal in src/domain/graph/builder/call-resolver.ts to handle C# calls like Validators.IsValidEmail(...) where the receiver is a class name with no typeMap entry:
```typescript
if (!typeName) {
const staticCandidates = lookup
.byName(`${effectiveReceiver}.${call.name}`)
.filter((n) => n.kind === 'method');
if (staticCandidates.length > 0) return staticCandidates;
}
```
Problem
Unlike every other resolution path in this function, the static fallback does not apply computeConfidence(relPath, t.file, null) >= 0.5 before returning candidates. This means in a large polyglot project where two unrelated classes in different directories both define a method with the same name, the fallback could return false-positive edges from a distant file.
All other paths that call lookup.byName() apply the confidence filter — see lines 108, 124, 157, 165, 178, 190.
Suggested fix
Apply the confidence filter to the static fallback as well:
```typescript
if (!typeName) {
const staticCandidates = lookup
.byName(`${effectiveReceiver}.${call.name}`)
.filter((n) => n.kind === 'method' && computeConfidence(relPath, n.file, null) >= 0.5);
if (staticCandidates.length > 0) return staticCandidates;
}
```
Note: this may need evaluation for cross-file static dispatch (e.g. calling a static class in a different directory), as a confidence floor of 0.5 might be too restrictive. The fix should ensure the C# benchmark fixture still produces the expected 3 static receiver edges after the filter is applied.
Priority
Low — the kind='method' guard combined with the fully-qualified Receiver.Method key makes accidental matches unlikely in practice. This is a robustness improvement, not an urgent bug.
Background
PR #1395 added a static receiver fallback to
resolveByMethodOrGlobalinsrc/domain/graph/builder/call-resolver.tsto handle C# calls likeValidators.IsValidEmail(...)where the receiver is a class name with no typeMap entry:```typescript
if (!typeName) {
const staticCandidates = lookup
.byName(`${effectiveReceiver}.${call.name}`)
.filter((n) => n.kind === 'method');
if (staticCandidates.length > 0) return staticCandidates;
}
```
Problem
Unlike every other resolution path in this function, the static fallback does not apply
computeConfidence(relPath, t.file, null) >= 0.5before returning candidates. This means in a large polyglot project where two unrelated classes in different directories both define a method with the same name, the fallback could return false-positive edges from a distant file.All other paths that call
lookup.byName()apply the confidence filter — see lines 108, 124, 157, 165, 178, 190.Suggested fix
Apply the confidence filter to the static fallback as well:
```typescript
if (!typeName) {
const staticCandidates = lookup
.byName(`${effectiveReceiver}.${call.name}`)
.filter((n) => n.kind === 'method' && computeConfidence(relPath, n.file, null) >= 0.5);
if (staticCandidates.length > 0) return staticCandidates;
}
```
Note: this may need evaluation for cross-file static dispatch (e.g. calling a static class in a different directory), as a confidence floor of 0.5 might be too restrictive. The fix should ensure the C# benchmark fixture still produces the expected 3 static receiver edges after the filter is applied.
Priority
Low — the
kind='method'guard combined with the fully-qualifiedReceiver.Methodkey makes accidental matches unlikely in practice. This is a robustness improvement, not an urgent bug.