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
19 changes: 19 additions & 0 deletions TESTING_GUIDE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Testing Guide

Dependency summary regressions in `QueryCommandRunnerGraphTests` (#5346) separate
page counts, SQL/C# candidate boundaries, extraction completeness, and response
budgets. Keep the three-edge limits 1/2/3/4, empty/filter/missing-graph controls,
batch child metadata, and the 201-symbol single-edge source-budget fixture.
Include mixed C#/SQL scope readiness and a filtered Markdown lookahead so
whole-query authority and page-window omissions cannot inherit page-only evidence.
Cycle summary variants share the existing ranked-SCC fixture in
`QueryCommandRunnerTests`; run these and dependency query regressions on net8/net9.

`Extract_CSharpStaticLambdaGate_BoundsRepeatedSameLineDeclarations` checks 64
same-line static methods with a warmed 2 MiB allocation ceiling on both runtimes,
including C#, Razor, Blazor and CSHTML. Preserve all identities, raw start columns,
Expand Down Expand Up @@ -1409,6 +1418,16 @@ Issue #5300 のテストは隣接・入れ子の C# callable、対象行の除

# テストガイド

`QueryCommandRunnerGraphTests` の依存関係 summary 回帰テスト(#5346)は、ページ件数、
SQL/C# の候補上限、抽出の完全性、応答サイズ上限を区別します。3 edge に対する
limit 1/2/3/4、空結果・フィルター・グラフ欠落、batch の子メタデータ、201 symbol
から1 edgeを作る候補上限 fixture を維持してください。
混在する C#/SQL の範囲全体の readiness と、フィルターで除去される Markdown の
先読みも検証し、総件数の authority とページ範囲の省略を返却行だけから判断しないでください。
循環 summary は
`QueryCommandRunnerTests` の既存の SCC 順位 fixture を共有し、依存クエリの回帰と
併せて net8/net9 で実行します。

#5339 は #5332 の fixture に正常な `files --format count --json` の batch を追加し、
3件・12件ともスナップショット3個分のコピー量を上限として、件数・鮮度・確定性の出力を検証します。
メタデータがある場合と欠落する場合の両方で、reader 取得後に元 DB のルート、大小文字区別設定、
Expand Down
4 changes: 2 additions & 2 deletions USER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2754,7 +2754,7 @@ same source location.
| `--quiet`, `-q`, `--silent` | All CLI commands | Suppress informational stderr without changing result stdout; errors remain visible. The flag can appear before or after the command. Use `--` before a query that literally starts with one of these tokens. |
| `--pretty` | JSON-capable commands except `mcp` | Pretty-print JSON output with indentation. Default `search --json` remains newline-delimited; use `search --json=array --pretty` for an indented search result array. |
| `--compact` | `map`, `inspect`, `outline` | Emit AI-oriented compact JSON with capped list sections and `truncation.sections.*` metadata. The default cap is 5 unless `--limit` / `--top` is supplied. |
| `--summary-only` | `map`, `recipes`, `audit`, `deps`, `hotspots`, and supported `search` JSON contexts | Emit aggregate/context JSON while omitting heavy result arrays where supported. For `deps`, use `--json` or `--format json-graph`; for `hotspots`, use `--json`. Machine-readable `deps` output emits `Progress:` diagnostics only with `--verbose`; other large graph queries emit them at `--limit 80+` or with `--verbose`. |
| `--summary-only` | `map`, `recipes`, `audit`, `deps`, `hotspots`, and supported `search` JSON contexts | Emit aggregate/context JSON while omitting heavy result arrays where supported. For `deps`, use `--json`; its count is a returned/page count with separate [count and completeness metadata](docs/deps-summary-counts.md#english), and `--format json-graph` is unsupported in summary mode. For `hotspots`, use `--json`. Machine-readable `deps` output emits `Progress:` diagnostics only with `--verbose`; other large graph queries emit them at `--limit 80+` or with `--verbose`. |
| `--sort <mode>` | `symbols`, `outline` | For `outline`, sort one file's symbols by `source`, `kind`, `references`, `size` / `span`, `complexity`, `path`, or `name` before `--limit` / cursor paging. |
| `--outline-fields <csv>` | `outline` | Project outline JSON symbol fields such as `name`, `line`, `kind`, `signature`, `container`, `range`, `body`, `reference_count`, `size_lines`, `complexity_score`, or `sort_mode`; pass `all` for the full symbol payload with paging metadata. |
| `--fields <csv\|list>` | `inspect` | Select top-level inspect JSON groups or one-level collection leaves such as `definitions.name`, `definitions.path`, `references.line`, and `callers.path`. A parent keeps full rows and wins over its children; aliases, duplicates, and output order are normalized deterministically. `body` includes definition bodies and maps to `definitions`. Use `list` for the queryless typed catalog. |
Expand Down Expand Up @@ -6810,7 +6810,7 @@ raw match density を正確に測る、といった理由で全 raw chunk hit
| `--quiet`、`-q`、`--silent` | 全 CLI コマンド | 結果の stdout を変えずに informational stderr を抑制し、エラーは表示する。フラグはコマンドの前後どちらにも指定できる。これらのトークン自体で始まるクエリを検索する場合は、その前に `--` を指定する。 |
| `--pretty` | `mcp` を除く JSON 対応コマンド | JSON 出力をインデント付きで整形。既定の `search --json` は newline-delimited のまま維持されるため、検索結果配列を整形したい場合は `search --json=array --pretty` を使う。 |
| `--compact` | `map`、`inspect`、`outline` | list section を cap した AI 向け compact JSON を出力し、`truncation.sections.*` metadata を含める。既定 cap は 5 件で、`--limit` / `--top` 指定時はその値を使う。 |
| `--summary-only` | `map`、`recipes`、`audit`、`deps`、`hotspots`、および対応する `search` JSON 文脈 | 対応コマンドで重い結果配列を省き、集計と文脈中心の JSON を返す。`deps` では `--json` または `--format json-graph``hotspots` では `--json` と組み合わせる。machine-readable な `deps` 出力は `--verbose` 指定時だけ stderr へ `Progress:` 診断を出し、それ以外の大きい graph query は `--limit 80` 以上または `--verbose` 指定時に出す。 |
| `--summary-only` | `map`、`recipes`、`audit`、`deps`、`hotspots`、および対応する `search` JSON 文脈 | 対応コマンドで重い結果配列を省き、集計と文脈中心の JSON を返す。`deps` では `--json` と組み合わせ、返却ページの件数と独立した[件数・完全性メタデータ](docs/deps-summary-counts.md#日本語)を返す。summary で `--format json-graph` は非対応。`hotspots` では `--json` と組み合わせる。machine-readable な `deps` 出力は `--verbose` 指定時だけ stderr へ `Progress:` 診断を出し、それ以外の大きい graph query は `--limit 80` 以上または `--verbose` 指定時に出す。 |
| `--sort <mode>` | `symbols`、`outline` | `outline` では 1ファイル内のシンボルを `source`、`kind`、`references`、`size` / `span`、`complexity`、`path`、`name` で並べ替えてから `--limit` / カーソルページングを適用する。 |
| `--outline-fields <csv>` | `outline` | outline JSON のシンボルフィールドを投影する。`name`、`line`、`kind`、`signature`、`container`、`range`、`body`、`reference_count`、`size_lines`、`complexity_score`、`sort_mode` などを指定でき、`all` を渡すとシンボルペイロード全体とページングメタデータを返す。 |
| `--fields <csv\|list>` | `inspect` | inspect JSON の top-level group または `definitions.name`、`definitions.path`、`references.line`、`callers.path` など 1 階層の collection leaf を選択する。parent は row 全体を保持して child より優先され、alias、重複、出力順は決定的に正規化される。`body` は definition body を含め、`definitions` に対応する。query 不要の型付き catalog は `list` で取得できる。 |
Expand Down
17 changes: 17 additions & 0 deletions changelog.d/unreleased/5346.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
category: fixed
issues:
- 5346
affected:
- src/CodeIndex/Cli/QueryCommandRunner.Dependencies.cs
- src/CodeIndex/Database/DbReader.DependencyQueryExecution.cs
- docs/deps-summary-counts.md
---

## English

- **Dependency summaries distinguish returned counts from complete totals (#5346)** — `deps --summary-only --json` now reports count units, additional-result evidence, candidate coverage, query exhaustion, and total-count availability/authority. Bounded lookahead preserves existing candidate budgets; cycle summaries reuse their analysis totals, and incomplete graphs or stale SQL contracts anywhere in the query scope cannot make totals authoritative.

## 日本語

- **依存関係 summary が返却件数と完全な総件数を区別します (#5346)** — `deps --summary-only --json` は件数の単位、追加結果の証拠、候補範囲、検索完了、総件数の確定可否と authority を報告します。先読みは既存の候補上限を維持し、循環 summary は解析済みの総件数を再利用します。不完全なグラフやクエリ範囲内の古い SQL 契約がある場合は、総件数を authoritative としません。
105 changes: 105 additions & 0 deletions docs/deps-summary-counts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Dependency summary counts

## English

`cdidx deps --summary-only --json --limit 2 --exclude-tests` reports the
same **returned/page count** as the corresponding dependency query. Omitting
the edge array does not turn `count` into a whole-graph total. This also applies
to `--cycles --summary-only`: its unit is a dependency cycle (SCC).

| Field | Meaning |
| --- | --- |
| `count`, `returned_count` | Dependency rows selected for this page after filters; summary mode omits the edge array. |
| `count_kind`, `count_unit` | `returned`, with unit `dependency_edges` or `dependency_cycles`. |
| `page_limit` | Requested display limit; distinct from candidate and graph work budgets. |
| `has_more` | `true` proves an additional matching row was observed. `false` means the available query result was exhausted; `null` means exhaustion could not be established within the candidate window. For cycles it retains the existing meaning: more SCCs in the analyzed candidate graph. |
| `candidate_scan_complete` | No candidate safety boundary was reached. For cycles this matches `analysis_complete`; it does not establish extraction completeness. |
| `query_exhausted` | Candidate coverage is complete and there is no later page. This proves exhaustion of the indexed query, independently of extraction coverage. |
| `total_count`, `total_count_available` | Exact indexed-query total when already known, otherwise `null` / `false`. Ordinary summaries expose it only on exhaustion. Cycles can reuse the total from complete SCC analysis even on a partial page. |
| `total_count_authoritative` | The total is available, the reference graph is complete, its graph contract is not degraded, and workspace graph coverage is verified. It is not a claim of compiler-complete dependency analysis. |
| `total_count_unavailable_reason` | `page_limit`, `candidate_scan_incomplete`, `workspace_candidate_scan_unverified`, or `graph_edge_budget`; `null` when available. |
| `total_count_non_authoritative_reason` | When a numeric total is available but not authoritative: `reference_graph_incomplete`, `graph_contract_degraded`, or `workspace_graph_coverage_unverified`. |
| `truncated`, `truncated_reason` | Ordinary summaries identify a partial page or unverified candidate coverage. Cycles retain their existing page/graph-budget truncation contract. |

On three matching edges, limits 1 and 2 return their respective counts with
`has_more=true`, `query_exhausted=false`, and no total. Limits 3 and above return
3 with `has_more=false` and `query_exhausted=true`, unless a candidate boundary
prevents that proof. An exhausted zero-row query can report a total of zero;
an incomplete or missing graph still prevents authoritative absence claims.

Ordinary summaries look ahead by at most one **ranked result** inside the
existing SQL ranking window; they do not increase that window or either C#
source-candidate budget. C# name candidates and resolved-identity reference
candidates are checked separately before relying on the edge count. Reaching
a candidate boundary, even exactly, is conservatively incomplete. Filters can
remove the lookahead row, so an unexamined remainder remains unknown.
That filtered remainder uses `page_limit`, even when `candidate_scan_complete=true`.
Workspace fan-out currently lacks combined candidate-exhaustion evidence:
its ordinary summary preserves the existing query budget and reports unknown
`has_more` and an unavailable total. Narrow to one database for this proof.

The broad-summary guard (250 candidate files without a narrowing filter),
generated/test exclusions, noise/evidence filters, and incomplete-graph warnings
remain in force. `--summary-only --format json-graph` remains unsupported.
`reference_graph_complete=true` alone never proves query exhaustion.
Cycle node sampling (`display_truncated`) is separate from SCC pagination.
Summary authority retains SQL readiness for the full query scope, including SQL
files that produce no returned edge or SCC. A non-SQL page cannot hide that degradation.

`--max-json-bytes` is a response budget, not a query-work budget. A summary that
cannot fit returns `E028_RESPONSE_BUDGET_TOO_SMALL`; it does not silently discard
the count/coverage metadata or return an empty success. Successful batch child
summary payloads carry the same fields. These additions describe CLI summary
output; detailed output and MCP retain their existing contracts.

## 日本語

`cdidx deps --summary-only --json --limit 2 --exclude-tests` の `count` は、
対応する依存関係クエリと同じ **返却ページの件数** です。edge 配列を省略しても、
グラフ全体の総件数にはなりません。`--cycles --summary-only` でも同様で、
件数の単位は依存循環(SCC)です。

| フィールド | 意味 |
| --- | --- |
| `count`、`returned_count` | フィルター後にこのページへ選択された依存関係の件数。summary では edge 配列を省略します。 |
| `count_kind`、`count_unit` | `returned` と、単位 `dependency_edges` または `dependency_cycles`。 |
| `page_limit` | 要求された表示上限。候補走査やグラフ解析の処理量上限とは別です。 |
| `has_more` | `true` は追加の一致を確認済み、`false` は利用できるクエリ結果を走査済み、`null` は候補範囲内では完了を証明できなかったことを示します。cycles では従来どおり、解析対象の候補グラフに後続の SCC があるかを示します。 |
| `candidate_scan_complete` | 候補の安全上限に達していないこと。cycles では `analysis_complete` と一致し、抽出の完全性は保証しません。 |
| `query_exhausted` | 候補範囲の確認が完了し、後続ページがないこと。索引に対するクエリの完了を示し、抽出範囲とは独立です。 |
| `total_count`、`total_count_available` | 既知の場合は索引に対するクエリの正確な総件数、それ以外は `null` / `false`。通常の summary は完了時のみ返します。cycles は完全な SCC 解析の総件数を部分ページでも再利用できます。 |
| `total_count_authoritative` | 総件数が既知で、参照グラフが完全かつ契約が縮退しておらず、workspace のグラフ範囲も確認済みであること。コンパイラーと同等の依存解析を保証するものではありません。 |
| `total_count_unavailable_reason` | `page_limit`、`candidate_scan_incomplete`、`workspace_candidate_scan_unverified`、`graph_edge_budget`。総件数が既知なら `null`。 |
| `total_count_non_authoritative_reason` | 数値の総件数が既知でも authoritative ではない理由。`reference_graph_incomplete`、`graph_contract_degraded`、`workspace_graph_coverage_unverified`。 |
| `truncated`、`truncated_reason` | 通常の summary では部分ページまたは未確認の候補範囲を示します。cycles は従来のページ/グラフ上限の契約を維持します。 |

一致する edge が3件なら、limit 1/2 はそれぞれの返却件数とともに
`has_more=true`、`query_exhausted=false`、総件数未確定を返します。
limit 3以上は、候補上限によって証明が妨げられない限り、3件と
`has_more=false`、`query_exhausted=true` を返します。0件の完了クエリも
総件数0を返せますが、抽出が不完全、またはグラフがない場合は
authoritative な不在の証拠にはなりません。

通常の summary は既存の SQL ranking window 内で、順位付きの結果を最大1件だけ
先読みします。この範囲や C# の候補上限は増やしません。C# の名前候補と
解決済み参照の候補を別々に確認し、edge 件数だけから完了を推測しません。
候補上限ちょうどの場合も安全側に倒して未完了とします。フィルターが先読み結果を
除去した場合、未確認の残りがあれば追加結果の有無は不明です。
この場合は `candidate_scan_complete=true` でも省略理由を `page_limit` とします。
複数 DB の workspace 集計には候補範囲を統合した完了証拠がないため、既存の
処理量上限を維持して `has_more` を不明、総件数を未確定とします。
完了を確認する場合は単一 DB に絞ってください。

絞り込みがない場合の250候補ファイルの guard、生成コード/テスト除外、
noise/参照証拠のフィルター、不完全なグラフの警告は維持します。
`--summary-only --format json-graph` は引き続き非対応です。
`reference_graph_complete=true` だけでは検索完了を証明できません。
循環内の node の表示省略(`display_truncated`)も SCC のページングとは別です。
summary の authority は、返却 edge や SCC を生成しなかった SQL ファイルも含む
クエリ全体の SQL readiness を確認します。ページに SQL がなくても縮退状態は隠しません。

`--max-json-bytes` は応答サイズの上限であり、クエリの処理量上限ではありません。
summary が収まらなければ `E028_RESPONSE_BUDGET_TOO_SMALL` を返し、件数や範囲の
メタデータを黙って捨てたり、空の成功応答を返したりしません。成功した batch の
子 summary も同じフィールドを持ちます。この追加は CLI の summary 出力が対象で、
詳細出力と MCP は既存の契約を維持します。
2 changes: 1 addition & 1 deletion src/CodeIndex/Cli/CliFlagSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ private static IReadOnlyList<CliFlag> BuildAll()
Description = "Map: comma-separated response sections to include, or list to discover sections",
PrimaryCommands = Set(MapSectionCommands),
},
new() { Name = "--summary-only", Description = "Map/Diff/Recipes/Audit/Files/Symbols/Deps/Hotspots/Languages: return only aggregate summary fields where supported", PrimaryCommands = Set(SummaryOnlyCommands) },
new() { Name = "--summary-only", Description = "Map/Diff/Recipes/Audit/Files/Symbols/Deps/Hotspots/Languages: return aggregate summary fields where supported; Deps counts returned rows and reports query exhaustion separately from graph completeness", PrimaryCommands = Set(SummaryOnlyCommands) },
new() { Name = "--detailed", Description = "Diff: compare deterministic row-level records", PrimaryCommands = Set("diff") },
new() { Name = "--include-content", Description = "Diff detailed JSON: include indexed content instead of redacted hashes", PrimaryCommands = Set("diff") },
new() { Name = "--data-only", Description = "Diff: include indexed data and schema in identity while excluding readiness/provenance and volatile telemetry", PrimaryCommands = Set("diff") },
Expand Down
Loading
Loading