Skip to content

Title: Go interface calls with multiple implementations do not produce candidate concrete CALLS edges #1114

Open

Description

@Aklil

Version

codebase-memory-mcp 0.8.1

Platform

macOS (Apple Silicon)

Install channel

GitHub release archive / install.sh / install.ps1

Binary variant

ui

What happened, and what did you expect?

Summary

Go interface calls are recognized by the hybrid LSP, but when an interface has more than one known implementation, the graph records only a generic interface-dispatch edge—for example, Store.Get—rather than candidate concrete call edges such as RedisStore.Get and DynamoStore.Get.

This makes downstream graph queries, impact analysis, dead-code detection, and agent reasoning report that Go interface dispatch is not resolved, even though the interface call itself was detected.

Example

type Store interface {
    Get(string) error
}

type RedisStore struct{}

func (RedisStore) Get(string) error {
    return nil
}

type DynamoStore struct{}

func (DynamoStore) Get(string) error {
    return nil
}

func Process(s Store) error {
    return s.Get("key")
}

Current behavior

The call from Process is represented as an lsp_interface_dispatch target:

Process -> Store.Get

When there is exactly one indexed implementer, the existing lsp_interface_resolve path can resolve to the concrete method. With two or more implementers, no concrete candidate edges are emitted.

Expected or proposed behavior

Keep the generic interface-dispatch edge, but optionally emit conservative candidate edges to every indexed type that satisfies the interface method set:

Process -> Store.Get          [interface dispatch]
Process -> RedisStore.Get     [possible interface target]
Process -> DynamoStore.Get    [possible interface target]

These candidate edges should be distinguishable from definite calls, for example through:

  • A separate edge type such as POSSIBLE_CALLS or INTERFACE_CALLS.
  • CALLS edges with a strategy such as lsp_interface_candidate and lower confidence.

This would avoid falsely presenting a candidate target as definite while making polymorphic call paths visible to graph traversal and impact analysis.

Pipeline consideration

The recent sole-implementer confidence fix ensures that an unambiguous concrete implementation can win over the generic interface-method result.

This issue concerns the remaining multi-implementer case, where conservative call-graph fan-out may be preferable to stopping at the interface node.

A configuration option could control this behavior for users who prefer a smaller, stricter graph.

Acceptance criteria

  • A Go interface call with one implementation continues to resolve to that implementation.
  • A Go interface call with multiple indexed implementations retains its generic interface-dispatch edge.
  • Candidate concrete implementations are available to graph queries without being marked as definite runtime dispatch.
  • Tests cover single-file and cross-file interfaces with two or more implementations.

Confirmations

  • I searched existing issues and this is not a duplicate.
  • My reproduction uses shareable code (a dummy snippet or a public OSS repository), not proprietary code.

Activity

  1. added
    language-requestRequest for new language support
    parsing/qualityGraph extraction bugs, false positives, missing edges
    ux/behaviorDisplay bugs, docs, adoption UX
    windowsWindows-specific issues
    on Jul 16, 2026
  2. added
    enhancementNew feature or request
    priority/normalStandard review queue; useful PR with ordinary maintainer urgency.
    and removed
    bugSomething isn't working
    language-requestRequest for new language support
    ux/behaviorDisplay bugs, docs, adoption UX
    windowsWindows-specific issues
    on Jul 16, 2026
  3. added this to the 0.9.2-rc milestone on Jul 16, 2026
  4. DeusData commented on Jul 16, 2026

    @DeusData
    Owner

    Thanks for the compact Go example and for distinguishing definite dispatch from possible targets. This is an enhancement rather than a regression: the current graph deliberately stops at the interface node when runtime dispatch is ambiguous.

    The design decision is whether possible targets belong in the graph at all, and if so whether they use a separate relationship type or confidence-bearing CALLS edges. That choice affects trace_path, impact analysis, dead-code claims, schema compatibility, and graph fan-out on large interface-heavy codebases. I have placed it in 0.9.2-rc for that design review; please do not add a configuration switch or new edge type before the representation is agreed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestparsing/qualityGraph extraction bugs, false positives, missing edgespriority/normalStandard review queue; useful PR with ordinary maintainer urgency.

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions