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:
- reuse the existing selector parser/resolver in references, callers, and callees;
- extend impact only where the same exact-identity plumbing applies;
- scope graph SQL and pagination to the selected symbol ID;
- include the selector in cursor/query fingerprints;
- expose support in CLI help, completions, structured field docs, and matching MCP tools;
- make ambiguous unselected output truthful through candidate metadata and an identity-scoped signal;
- 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.
Summary
inspectemits 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:c642bc4c3dda4ef659df8e6b699e10f61da3c836cdidx v1.44.3, locally builtReproduction
This returns separate candidates for:
CodeIndex.Cli.ConsoleCompletionRenderer.GetCompletionScript;CodeIndex.Cli.ConsoleUi.GetCompletionScript.Each candidate exposes a selector such as
id:<n>@g:<fingerprint>.The result silently unions both definitions: the renderer's callees and
ConsoleUi's forwarding call appear together.Qualified free text returns no rows:
Trying the emitted selector is rejected because
--selectoris scoped toinspect.Expected behavior
inspectare reusable byreferences,callers, andcallees.impactaccepts the same selector where it shares the resolution path.Root cause and evidence
src/CodeIndex/Models/SymbolSelector.csparses generation-bound selectors.src/CodeIndex/Cli/CliFlagSchema.cs:534scopes--selectorexclusively toinspect.QueryCommandRunner.Inspect.csalready validates selector generations and resolves the selected identity.Focused PR scope
One PR should:
Non-goals
Implementation guidance and cautions
params, generics, extension methods, and dynamic dispatch.Required tests
Acceptance criteria
ConsoleUi.GetCompletionScriptreturns only its forwarding call.ConsoleCompletionRenderer.GetCompletionScriptreturns only its own callees.Regression history
inspecttargets in separate symbol bundles #4570 required ambiguous inspect targets to remain separate and called for stable selectors.This is the remaining direct-graph application of that contract. No newer exact issue was found.