Skip to content

fix(code-index): disclose ambiguous calls as caller gaps - #3067

Open
devin-ai-integration[bot] wants to merge 2 commits into
masterfrom
devin/1791127746-ambiguous-candidate-gaps
Open

devin-ai-integration[bot] wants to merge 2 commits into
masterfrom
devin/1791127746-ambiguous-candidate-gaps

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Ambiguous call references (more than one candidate the resolver cannot choose between) now become disclosed unresolved-call gaps instead of disappearing, so callers/callees/impact answers report themselves as partial.

Motivation

Fixes #3012. resolve_cross_file_reference returned None when more than one inherent candidate remained, and same-file resolution in resolve_file_references dropped ambiguous references (_ => {}). Neither path left a gap row, so an incomplete radius looked complete.

Changes

  • production/helpers.rs: resolve_cross_file_reference returns ReferenceResolutionV1::{Bound, Ambiguous}; per-file resolution collects ambiguous Calls references as gaps. CrossFileResolutionV1.implementor_gaps is renamed to gaps and carries these rows too; resolve_selected_cross_file_references returns the full resolution.
  • production/sparse_resolution.rs: the sparse (incremental) path adds those gaps to the owning file's unresolved_calls, so incremental and full seals agree.
  • chunks.rs / chunks/artifacts.rs: deleted the same-file ambiguity special case. Ambiguous references are now retained with a new CodeIndexUnresolvedReferenceV1.ambiguous_local flag (serde-skipped when false, so existing artifacts are unchanged). Sealing treats a flagged reference as Ambiguous before any import lookup, so it is always a gap and can never bind a shadowed import. Java overloads keep their existing path.
  • Unit test qualified_reference_selects_its_namespace_and_bare_name_stays_ambiguous now asserts the ambiguous bare name is retained, not dropped.

Choice made: ambiguous candidates are disclosed as gaps, not emitted as low-confidence edges. The issue proposed either option; gaps add no false edges to graph answers.

Test plan

  • relation_coverage::a_type_path_call_with_two_inherent_candidates_makes_both_callers_partial (cross-file Clock::tick() with cfg-gated impls in two files): fails on master, passes with the fix.
  • relation_coverage::a_same_file_call_with_two_candidates_makes_both_callers_partial (Ruby) and a_same_file_python_call_with_two_candidates_makes_its_callees_partial (Python): fail without the same-file change, pass with it.
  • relation_coverage::locally_ambiguous_definitions_shadow_an_imported_name: no false caller on the imported pkg.lib.scale. Fails on the first commit, passes now.
  • cargo test -p tracedecay-code-index: all pass (285 + 209 + 4 + 3)
  • cargo clippy -p tracedecay-code-index --all-targets -- -D warnings: clean
  • cargo fmt --all -- --check: clean
  • Full workspace cargo nextest run left to CI.

Checklist

  • CHANGELOG.md updated (release-please manages it)
  • No secrets, credentials, or .env files included
  • Breaking changes documented (if any): none

Link to Devin session: https://app.devin.ai/sessions/fd546572dcdb49cbbf8f10b6dec5ec80
Open in Devin Desktop: https://app.devin.ai/desktop/session/fd546572dcdb49cbbf8f10b6dec5ec80?variant=devin
Requested by: @ScriptedAlchemy


Devin Review

Cross-file resolution returned no binding when more than one inherent
candidate remained, and same-file resolution dropped ambiguous references
before they reached cross-file resolution. Neither left a gap row, so
callers, callees and impact answers looked complete.

Ambiguous same-file references are now retained like unbound ones, and
cross-file resolution reports ambiguous calls as unresolved-call gaps in
both whole-set and sparse resolution.

Fixes #3012

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@changeset-bot

changeset-bot Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: dddb828

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

devin-ai-integration[bot]

This comment was marked as resolved.

A retained same-file ambiguous call could bind a shadowed import, or get
no gap row in Python and TypeScript. Mark it ambiguous_local so sealing
reports it as a gap and never binds it cross-file.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

code-index: cross-file resolution silently drops references with >1 inherent candidate

1 participant