Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions DEVELOPER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1104,6 +1104,18 @@ language across reference/caller/callee evidence. `graph_language_source`,
`graph_language_confidence`, `graph_language_candidates`, and `graph_language_conflict`
distinguish authoritative filter/definition decisions from consistent inference and keep
mixed-language evidence unresolved.
Path/line resolution must select `symbols.id` and enter the same candidate-bundle builder as
name resolution; do not hand graph loaders only the display name. Each bounded references,
callers, and callees section computes its own stable-order page and authoritative total.
`graph_sections` reports `total`, `returned`, `offset`, and `truncated`, while CLI `inspect`
and MCP `analyze_symbol` attach query-, effective-page-size-, and index-generation-bound
cursors independently to truncated sections. Caller/callee ordering ends with every grouped
identity field so offset pages cannot skip tied rows. Candidate selectors are part of cursor
scope so paging one overload or partial-family representative cannot borrow graph rows from
another candidate. Treat a path/line locator separately from graph path filters: the locator
selects the persisted symbol, but its inbound references and callers may come from any indexed
file permitted by explicit graph filters. Shared cursor parsing may retain inspect cursors, but
every non-inspect command must reject that cursor family before execution.

### Reference taxonomy

Expand Down Expand Up @@ -4268,6 +4280,19 @@ reference/caller/callee query は `symbol_reference_candidates` または
言語を推論します。`graph_language_source`、`graph_language_confidence`、
`graph_language_candidates`、`graph_language_conflict` により、filter/definition による
authoritative な判定と一貫した推論を区別し、複数言語の evidence は未確定のままにします。
path/line resolution は `symbols.id` を select し、name resolution と同じ
candidate-bundle builder に入れてください。graph loader に display name だけを渡しては
なりません。上限付きの references、callers、callees section は、それぞれ安定順序の page と
authoritative な総数を計算します。`graph_sections` は `total`、`returned`、`offset`、
`truncated` を報告し、CLI `inspect` と MCP `analyze_symbol` は truncated な section ごとに
query、effective page size、index generation に束縛した cursor を付けます。
caller/callee の順序は grouped identity field のすべてを末尾の tie-breaker に使い、offset page が
同順位 row を飛ばさないようにします。candidate selector も cursor scope に含め、1つの overload
または partial-family representative の pagination が別 candidate の graph row を借用しないように
してください。path/line locator と graph path filter は分離してください。locator は persisted
symbol を選択しますが、その inbound references と callers は、明示された graph filter が許可する
任意の indexed file から取得できます。共有 cursor parser が inspect cursor を保持しても、
inspect 以外の各 command は実行前にその cursor family を拒否しなければなりません。

### 参照 taxonomy

Expand Down
2 changes: 2 additions & 0 deletions TESTING_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ Use `docs/test-doc-maintenance-plan.md` before moving oversized suites or adding
`goto --all` coverage shares one 63-definition fixture across the default bare LSP array and the plain `--json` argument path; it must assert complete deterministic output without a limit and retain a separate explicit-limit assertion in the same setup.
Cursor-pagination coverage for `outline` and `unused` must replay the emitted opaque token successfully, then prove that changed filters/order and a changed index-generation stamp fail with restart-required diagnostics.
Discovery-pagination coverage must page compact search/symbol/file output and the opt-in search-array/languages envelopes, assert authoritative total/omitted/stable-at metadata, reject query or generation cursor mismatches, and prove that a partial `find --all` scan resumes after the last scanned line.
Inspect graph-section coverage must compare name and path/line resolution through the same persisted candidate ID, keep ambiguous overload and partial-family bundles isolated, assert independent total/returned/truncated metadata for references, callers, and callees (including empty sections), and replay a query-, page-size-, and generation-bound cursor across the smallest two-row page boundary. Put inbound callers in another file to prove the location path is only a locator, seed equal-rank same-line callees to pin the complete identity tie-breakers, reject page-size changes before candidate lookup, reject inspect cursors in another command, and verify the same envelopes in MCP `analyze_symbol`.
Quiet-flag coverage in `ProgramCliTests.cs` reuses one seeded symbols database across text, NDJSON, and JSON-array modes and compares stdout with and without a trailing quiet alias, proving that quiet mode changes only informational stderr.
Doctor full-inventory coverage keeps composed filter selection, filtered summary counts, exact UTF-8 byte-budget boundaries, and structured overflow errors together in `ProgramRunnerTests`; license JSON remains a subprocess contract in `ProgramCliTests` so immediate-command dispatch and the published field names are both exercised.
Ctags export JSON coverage reuses one seeded database for default and `--include-generated` variants, asserts the fixed skip-reason keys sum to `skipped_count`, and keeps the missing-`files.generated` degradation in a separate legacy-schema fixture.
Expand Down Expand Up @@ -1084,6 +1085,7 @@ dotnet test --filter "FullyQualifiedName~GitHelperTests"
`goto --all` の coverage は、既定の bare LSP array と plain `--json` 引数経路で 1 つの 63 定義 fixture を共有し、limit 未指定時の完全かつ決定的な出力と、同じ setup 内での明示 limit の維持を検証してください。
`outline` と `unused` の cursor pagination coverage では、出力された opaque token の再利用成功に加え、filter/order の変更と index-generation stamp の変更が restart-required 診断で失敗することを検証してください。
discovery pagination の coverage では compact search / symbol / file と opt-in の search array / languages envelope をページングし、authoritative な total / omitted / stable-at metadata、query / generation 不一致 cursor の拒否、partial な `find --all` scan が最後に scan した line の次から再開することを検証してください。
inspect graph-section coverage では、name と path/line resolution が同じ persisted candidate ID を通ること、曖昧な overload と partial-family bundle が分離されること、references / callers / callees の独立した total / returned / truncated metadata(空 section を含む)を検証してください。inbound caller は別ファイルに置いて location path が locator にすぎないことを証明し、最小の2行 page 境界で query / page size / generation に束縛された cursor を再利用します。同順位かつ同じ行の callee で完全な identity tie-breaker を固定し、candidate lookup より前に page-size 変更を拒否し、別 command では inspect cursor を拒否してください。MCP `analyze_symbol` でも同じ envelope を確認します。
`ProgramCliTests.cs` の quiet flag coverage は1つの seeded symbols database を text、NDJSON、JSON array の各 mode で再利用し、末尾に quiet alias を付けた場合と付けない場合の stdout を比較して、quiet mode が informational stderr だけを変えることを固定します。
doctor full-inventory coverage では、合成 filter の選択、filtered summary 件数、UTF-8 byte budget の exact boundary、structured overflow error を `ProgramRunnerTests` にまとめます。license JSON は `ProgramCliTests` の subprocess contract として、immediate-command dispatch と公開 field 名を同時に検証します。
ctags export JSON coverage は1つの seeded database を既定と `--include-generated` variant で再利用し、固定された skip-reason key の合計が `skipped_count` と一致することを検証します。`files.generated` がない場合の縮退は別の legacy-schema fixture に保ってください。
Expand Down
29 changes: 29 additions & 0 deletions USER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,20 @@ For AI-oriented bounded payloads, `map`, `inspect`, and `outline` accept
`--compact`. It implies JSON output, caps list sections to 5 items by default
(or the explicit `--limit` / `--top` value), and adds `compact`,
`compact_limit`, and `truncation.sections.*` metadata.
Every `inspect` graph bundle also publishes independent
`graph_sections.references`, `graph_sections.callers`, and
`graph_sections.callees` envelopes with `total`, `returned`, `offset`, and
`truncated`. A truncated section includes an opaque `next_cursor`; pass it back
with `--cursor` and unchanged query filters to continue only that section.
The cursor is bound to the query, effective page size, and index generation, so
keep the same `--limit` / `--top` value when continuing. Name and path/line
inspection both preserve the selected persisted symbol ID, so location lookup
returns the same candidate-scoped graph evidence as the corresponding name
bundle instead of re-resolving a display name. MCP `analyze_symbol` exposes the
same section envelopes and accepts their cursors. In path/line mode, `--path`
locates the definition but does not restrict inbound references or callers to
that file. Inspect graph cursors are accepted only by `inspect`; passing one to
another command is a usage error.
For narrower `inspect` evidence, `--fields <csv>` implies JSON and selects
top-level groups such as `definitions`, `file`, `graph`, `references`,
`callers`, and `callees`; `--outline-only` is shorthand for
Expand Down Expand Up @@ -419,6 +433,7 @@ cdidx inspect Compute --outline-only # file/definition/nearby symbol summar
cdidx inspect Compute --body-only # definitions with body_content only
cdidx inspect Compute --body --body-start 40 --body-lines 40
cdidx inspect Compute --line 42 --context 2 --json
cdidx inspect Compute --json --limit 1 --cursor '<next_cursor>'
```

## Editor and index portability
Expand Down Expand Up @@ -3513,6 +3528,19 @@ AI 向けに上限付き payload が必要な場合、`map`、`inspect`、`outli
`--compact` に対応しています。これは JSON 出力を暗黙に有効化し、list section を
既定 5 件(明示した `--limit` / `--top` があればその値)に cap し、
`compact`、`compact_limit`、`truncation.sections.*` metadata を追加します。
すべての `inspect` graph bundle は、独立した
`graph_sections.references`、`graph_sections.callers`、
`graph_sections.callees` envelope も公開し、`total`、`returned`、`offset`、
`truncated` を示します。truncated な section には opaque な `next_cursor` が付き、
query filter を変えず `--cursor` で渡すと、その section だけを継続できます。
cursor は query、effective page size、index generation に束縛されるため、継続時は
同じ `--limit` / `--top` 値を維持してください。名前指定と path/line 指定の
どちらも選択された永続 symbol ID を維持するため、location lookup は display name を
再解決せず、対応する name bundle と同じ candidate-scoped graph evidence を返します。
path/line mode の `--path` は定義の位置を特定しますが、inbound references や callers を
そのファイルだけに制限しません。MCP `analyze_symbol` も同じ section envelope を公開し、
その cursor を受け付けます。inspect graph cursor は `inspect` だけが受理し、別 command に
渡すと usage error になります。
`inspect` の証跡をさらに絞りたい場合、`--fields <csv>` は JSON 出力を暗黙に有効化し、
`definitions`、`file`、`graph`、`references`、`callers`、`callees` などの
top-level group を選択します。`--outline-only` は
Expand Down Expand Up @@ -3545,6 +3573,7 @@ cdidx inspect Compute --outline-only # ファイル・定義・近傍シン
cdidx inspect Compute --body-only # body_content 付き definitions のみ
cdidx inspect Compute --body --body-start 40 --body-lines 40
cdidx inspect Compute --line 42 --context 2 --json
cdidx inspect Compute --json --limit 1 --cursor '<next_cursor>'
```

## Editor / index portability
Expand Down
22 changes: 22 additions & 0 deletions changelog.d/unreleased/4839.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
category: fixed
issues:
- 4839
affected:
- src/CodeIndex/Database/DbSymbolReader.Analysis.cs
- src/CodeIndex/Database/DbReader.GraphQueries.cs
- src/CodeIndex/Cli/QueryCommandRunner.Inspect.cs
- src/CodeIndex/Cli/QueryCommandRunner.OptionValidation.cs
- src/CodeIndex/Mcp/McpToolHandlers.Graph.cs
- USER_GUIDE.md
- DEVELOPER_GUIDE.md
- TESTING_GUIDE.md
---

## English

- **Location-based inspect now preserves graph identity and section completeness (#4839)** — path/line and name resolution share the persisted candidate ID, so ambiguous overloads do not borrow one another's references or callers, while a location path no longer hides cross-file inbound evidence. CLI `inspect` and MCP `analyze_symbol` now report independent totals, returned counts, truncation state, stable tie ordering, and query/page-size/index-bound continuation cursors for references, callers, and callees; other CLI commands reject inspect cursors.

## 日本語

- **location-based inspect が graph identity と section completeness を維持するようになりました (#4839)** — path/line と name resolution が persisted candidate ID を共有し、曖昧な overload 間で references や callers を借用せず、location path が別ファイルからの inbound evidence を隠さなくなりました。CLI `inspect` と MCP `analyze_symbol` は references、callers、callees ごとに独立した総数、返却件数、truncation 状態、安定した同順位順序、query/page size/index に束縛された continuation cursor を報告し、他の CLI command は inspect cursor を拒否します。
2 changes: 1 addition & 1 deletion src/CodeIndex/Cli/CliFlagSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public static bool HasAuthoritativeHelpOptions(string command) =>
private static readonly string[] UnusedFilterCommands = ["unused"];
private static readonly string[] BoundedProjectionCommands =
ProjectionFieldRegistry.SupportedCommands.ToArray();
private static readonly string[] CursorCommands = ["search", "outline", "unused", "deps", .. BoundedProjectionCommands];
private static readonly string[] CursorCommands = ["search", "outline", "unused", "deps", "inspect", .. BoundedProjectionCommands];
private static readonly string[] AllResultCommands = ["goto", "find", "unused"];

private static readonly string[] SinceCommands = ["search", "definition", "symbols", "files", "suggestions"];
Expand Down
4 changes: 2 additions & 2 deletions src/CodeIndex/Cli/ConsoleUi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ private static readonly (string Command, string Usage)[] CommandUsageLines =
("find", "cdidx find <query> (--path <glob>|--all) [--db <path>] [--json] [--format <text|json|count|compact|csv|tsv|lsp|qf|sarif>] [--fields <csv>] [--cursor <next_cursor>] [--max-json-bytes <n>] [--verbose] [--limit <n>|--top <n>] [--lang <lang>] [--exclude-path <glob>] [--exclude-tests] [--context <n>] [--before <n>] [--after <n>] [--snippet-lines <n>] [--focus-line <line>] [--focus-column <n>] [--max-line-width <n>] [--line-scan-limit <n>] [--allow-partial] [--exact] [--regex] [--count]"),
("excerpt", "cdidx excerpt <path[:line|:start-end]> [--line <line>|--start <line>|--start-line <line>] [--end <line>|--end-line <line>] [--context <n>|--before <n>|--after <n>] [--max-line-width <n>] [--focus-line <line>] [--focus-column <n>] [--focus-length <n>] [--db <path>] [--json] [--no-semantic-tokens] [--max-json-bytes <n>] [--verbose]"),
("map", "cdidx map [--db <path>] [--json] [--format <text|json|compact|issue-drafts>] [--pretty] [--compact] [--fields <csv>] [--cursor <next_cursor>] [--summary-only] [--verbose] [--limit <n>|--top <n>] [--lang <lang>] [--path <glob>] [--exclude-path <glob>] [--exclude-tests] [--bytes] [--sections <summary,tree,languages,hotspots,metrics|list>] [--depth <n>] [--min-entrypoint-confidence <0.0..1.0>] [--max-json-bytes <n>]"),
("inspect", "cdidx inspect <query>|--query <query>|-- <query> [--db <path>] [--json] [--format <text|json|compact>] [--pretty] [--compact] [--fields <csv>] [--outline-only] [--body-only] [--max-json-bytes <n>] [--verbose] [--limit <n>|--top <n>] [--lang <lang>] [--kind <kind>] [--path <glob>] [--exclude-path <glob>] [--exclude-tests] [--body] [--body-start <line>] [--body-lines <n>|--body-line-count <n>] [--context <n>|--before <n>|--after <n>] [--max-line-width <n>] [--exact|--exact-name] [--group-partials]"),
("inspect", "cdidx inspect --path <file> --line <line> [--end-line <line>] [--db <path>] [--json] [--format <text|json|compact>] [--pretty] [--compact] [--fields <csv>] [--outline-only] [--body-only] [--max-json-bytes <n>] [--body] [--body-start <line>] [--body-lines <n>|--body-line-count <n>] [--context <n>|--before <n>|--after <n>] [--max-line-width <n>]"),
("inspect", "cdidx inspect <query>|--query <query>|-- <query> [--db <path>] [--json] [--format <text|json|compact>] [--pretty] [--compact] [--fields <csv>] [--outline-only] [--body-only] [--cursor <next_cursor>] [--max-json-bytes <n>] [--verbose] [--limit <n>|--top <n>] [--lang <lang>] [--kind <kind>] [--path <glob>] [--exclude-path <glob>] [--exclude-tests] [--body] [--body-start <line>] [--body-lines <n>|--body-line-count <n>] [--context <n>|--before <n>|--after <n>] [--max-line-width <n>] [--exact|--exact-name] [--group-partials]"),
("inspect", "cdidx inspect --path <file> --line <line> [--end-line <line>] [--db <path>] [--json] [--format <text|json|compact>] [--pretty] [--compact] [--fields <csv>] [--outline-only] [--body-only] [--cursor <next_cursor>] [--max-json-bytes <n>] [--body] [--body-start <line>] [--body-lines <n>|--body-line-count <n>] [--context <n>|--before <n>|--after <n>] [--max-line-width <n>]"),
("outline", "cdidx outline <path> [--db <path>] [--json] [--pretty] [--compact] [--verbose] [--limit <n>|--top <n>] [--cursor <next_cursor>] [--sort <source|kind|references|size|complexity|path|name>] [--kind <kind[,kind]>] [--outline-fields <csv>]"),
("status", "cdidx status [--db <path>] [--json] [--format <text|json|compact>] [--compact] [--fields <csv>] [--cursor <next_cursor>] [--max-json-bytes <n>] [--verbose] [--check[=workspace,fold,graph,issues,hotspot,csharp,sql,newer]] [--stale-after <duration>] [--explain <field>] [--log-path] [--config] [--check-updates]"),
("workspace", "cdidx workspace <list|status|use|current|clear|deactivate> [name-or-relative-path] [--json]"),
Expand Down
Loading
Loading