Skip to content

Let graph commands consume inspect selectors instead of unioning same-name symbols #5187

Description

@Widthdom

Summary

inspect emits generation-bound selectors for ambiguous symbols, but direct graph commands cannot consume them. A bare-name query silently unions edges from unrelated same-name definitions, while a qualified name is not accepted as an equivalent narrowing mechanism.

This can attribute callers, callees, references, and impact to the wrong implementation.

Environment

  • origin/main: c642bc4c3dda4ef659df8e6b699e10f61da3c836
  • cdidx v1.44.3, locally built
  • fresh and complete repository index
  • full net8.0 and net9.0 suites pass

Reproduction

dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll inspect \
  GetCompletionScript --db .cdidx/codeindex.db --json --limit 10

This returns separate candidates for:

  • CodeIndex.Cli.ConsoleCompletionRenderer.GetCompletionScript;
  • CodeIndex.Cli.ConsoleUi.GetCompletionScript.

Each candidate exposes a selector such as id:<n>@g:<fingerprint>.

dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll callees \
  GetCompletionScript --db .cdidx/codeindex.db \
  --json --exact-name --limit 20

The result silently unions both definitions: the renderer's callees and ConsoleUi's forwarding call appear together.

Qualified free text returns no rows:

dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll callees \
  CodeIndex.Cli.ConsoleUi.GetCompletionScript \
  --db .cdidx/codeindex.db --json --exact-name

Trying the emitted selector is rejected because --selector is scoped to inspect.

Expected behavior

  • Selectors emitted by inspect are reusable by references, callers, and callees.
  • impact accepts the same selector where it shares the resolution path.
  • Selected results are scoped to exactly that symbol identity.
  • Ambiguous bare-name compatibility output explicitly reports that it is not identity-scoped and exposes the candidates/selectors being unioned.

Root cause and evidence

  • src/CodeIndex/Models/SymbolSelector.cs parses generation-bound selectors.
  • src/CodeIndex/Cli/CliFlagSchema.cs:534 scopes --selector exclusively to inspect.
  • QueryCommandRunner.Inspect.cs already validates selector generations and resolves the selected identity.
  • Direct graph runners still resolve only from free-text names and aggregate same-leaf definitions.
  • Qualified free text is not a working substitute.

Focused PR scope

One PR should:

  1. reuse the existing selector parser/resolver in references, callers, and callees;
  2. extend impact only where the same exact-identity plumbing applies;
  3. scope graph SQL and pagination to the selected symbol ID;
  4. include the selector in cursor/query fingerprints;
  5. expose support in CLI help, completions, structured field docs, and matching MCP tools;
  6. make ambiguous unselected output truthful through candidate metadata and an identity-scoped signal;
  7. add the required bilingual changelog fragment.

Non-goals

  • Do not implement compiler-grade overload resolution.
  • Do not redesign partial-family identity.
  • Do not change reference extraction heuristics.
  • Do not silently choose a candidate.
  • Do not treat symbol IDs as stable across index generations.

Implementation guidance and cautions

  • Keep one shared resolver; do not copy inspect parsing into each command.
  • Require and validate the generation fingerprint for newly emitted selectors.
  • Reject missing, stale, malformed, negative, and cross-database selectors with stable diagnostics.
  • A selected identity must never fall back to leaf-name aggregation when it has zero graph rows.
  • Apply path, language, test, and generated filters consistently after identity validation.
  • Preserve conservative ambiguity for optional parameters, params, generics, extension methods, and dynamic dispatch.
  • Keep CLI and MCP semantics aligned.

Required tests

  • Two same-name methods in unrelated containers with different callees.
  • Selector round-trip from inspect into references/callers/callees and applicable impact paths.
  • Selected rows contain only the chosen identity.
  • Bare-name ambiguity is explicit and backward compatible.
  • Missing, malformed, stale-generation, and cross-database selectors.
  • Cursor continuation cannot be reused with another selector.
  • Human/JSON CLI, MCP, help, and all shell completions.

Acceptance criteria

  • Every current selector emitted by inspect is actionable in documented graph commands.
  • Selecting ConsoleUi.GetCompletionScript returns only its forwarding call.
  • Selecting ConsoleCompletionRenderer.GetCompletionScript returns only its own callees.
  • No selected query silently falls back to a same-name union.
  • Ambiguous unselected queries state that they are not identity-scoped.
  • Cursor, filtering, and completeness metadata remain truthful.

Regression history

This is the remaining direct-graph application of that contract. No newer exact issue was found.

Metadata

Metadata

Assignees

No one assigned

    Labels

    .NETPull requests that update .NET codebugSomething isn't workingdocumentationImprovements or additions to documentationenhancementNew feature or requesttests

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions