Summary
tests/unit/call-resolver.test.ts — describe block resolveByMethodOrGlobal — cross-language global fallback rejection (#1783) — has a failing test on fix/issue-1836-update-graph-sh-hook-fallback-build-path (confirmed at commit e0ab9dc8, no local modifications to src/):
FAIL tests/unit/call-resolver.test.ts > resolveByMethodOrGlobal — cross-language global fallback rejection (#1783) > does not resolve a typed-method lookup to a same-named type in a different language
AssertionError: expected [ { id: 3, file: 'lib/widget.js', kind: 'method' } ] to deeply equal []
Repro
const jsMethod = { id: 3, file: 'lib/widget.js', kind: 'method' };
const lookup = makeLookup({ 'Widget.render': [jsMethod] });
const result = resolveByMethodOrGlobal(
lookup,
{ name: 'render', receiver: 'w' },
'lib/widget.py',
new Map([['w', 'Widget']]),
);
expect(result).toEqual([]); // actually returns [jsMethod]
A Python caller's w.render() (with w typed to Widget via the typeMap) incorrectly resolves to a same-directory JavaScript Widget.render method purely because the typeMap key matches — there is no static relationship between the two files/languages.
Root cause
resolveByGlobal's bare-call path guards against this exact cross-language false-positive class via isModuleScopedLanguage(relPath) (see src/domain/graph/resolver/strategy.ts:314 — if (!callerName || (isBareCall && isModuleScopedLanguage(relPath))) return [];), added for issue #1783.
resolveByReceiver's typeMap-based lookup (resolveReceiverTypeName and its callers in the same file) has no equivalent language-scoping guard — a typeMap-resolved type name (Widget) is looked up globally via lookup.byNameAndFile('Widget.render', ...)/lookup.byName(...) fallbacks without checking that the candidate's file extension is compatible with the caller's language.
Suggested fix
Apply the same (or an equivalent) cross-language guard used in resolveByGlobal to the receiver/typeMap resolution path in resolveByReceiver, so a typeMap hit in one language's file never satisfies a call site in a different language, mirroring the #1783 fix.
Found while
Validating the fix for issue #1838 (.claude/hooks/track-edits.sh) on this branch — confirmed unrelated to that change (no src/ modifications were made; failure reproduces on a clean worktree of fix/issue-1836-update-graph-sh-hook-fallback-build-path).
Summary
tests/unit/call-resolver.test.ts— describe blockresolveByMethodOrGlobal — cross-language global fallback rejection (#1783)— has a failing test onfix/issue-1836-update-graph-sh-hook-fallback-build-path(confirmed at commite0ab9dc8, no local modifications tosrc/):Repro
A Python caller's
w.render()(withwtyped toWidgetvia the typeMap) incorrectly resolves to a same-directory JavaScriptWidget.rendermethod purely because the typeMap key matches — there is no static relationship between the two files/languages.Root cause
resolveByGlobal's bare-call path guards against this exact cross-language false-positive class viaisModuleScopedLanguage(relPath)(seesrc/domain/graph/resolver/strategy.ts:314—if (!callerName || (isBareCall && isModuleScopedLanguage(relPath))) return [];), added for issue #1783.resolveByReceiver's typeMap-based lookup (resolveReceiverTypeNameand its callers in the same file) has no equivalent language-scoping guard — a typeMap-resolved type name (Widget) is looked up globally vialookup.byNameAndFile('Widget.render', ...)/lookup.byName(...)fallbacks without checking that the candidate's file extension is compatible with the caller's language.Suggested fix
Apply the same (or an equivalent) cross-language guard used in
resolveByGlobalto the receiver/typeMap resolution path inresolveByReceiver, so a typeMap hit in one language's file never satisfies a call site in a different language, mirroring the #1783 fix.Found while
Validating the fix for issue #1838 (
.claude/hooks/track-edits.sh) on this branch — confirmed unrelated to that change (nosrc/modifications were made; failure reproduces on a clean worktree offix/issue-1836-update-graph-sh-hook-fallback-build-path).