Skip to content

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

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.

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