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
2 changes: 2 additions & 0 deletions DEVELOPER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1974,6 +1974,7 @@ access.
| Human-readable default | Query commands (`search`, `definition`, `references`, `callers`, `callees`, `symbols`, `files`, `excerpt`, `map`, `inspect`, `outline`, `suggestions`) default to **human-readable output**. |
| `--json` | Emits JSON lines output, one JSON object per line, designed for easy parsing by AI agents. |
| Delegated audit command identity | `audit` delegates recipe execution to `search` internally while retaining the public `audit` identity in human usage, recovery hints, and generated replay commands. Explicit `audit --json` usage errors emit stable versioned command-error objects with `command: "audit"` and no human-readable `usage`; direct `search` errors retain `search` identity. |
| Recipe issue-draft summary | `search --recipe ... --format issue-drafts --summary-only` and its `audit` alias use a dedicated summary DTO instead of rendering full issue bodies. Each positive recipe query contributes one compact `drafts[]` row with query/title identity, result and file counts, at most five counted evidence paths plus explicit path omission metadata, labels, severity, confidence, optional result cursor, and a full-detail replay command. The root reports `total_count`, its authority/lower bound, `returned_count`, `omitted_count`, `truncated`, and an uncapped summary `recovery_command`. `--max-json-bytes` measures the exact UTF-8 document plus its final newline and removes only complete trailing summary rows; a cap below the zero-row envelope returns typed `E028_RESPONSE_BUDGET_TOO_SMALL` guidance under the invoked `search` or `audit` identity. Full issue-draft mode retains the established recipe metadata, evidence, source, triage, and rendered body shape. |
| `definition --json` miss | A default-format definition lookup that finds no matching symbol emits the shared versioned `E018_QUERY_NOT_FOUND` command-error object and exits `2`, with or without `--body`; it never succeeds with empty stdout. Bounded-envelope controls move the object to `metadata.error` and keep `results` empty instead of projecting it as a location row. The object is preflighted against `--max-json-bytes`; an impossible cap returns a usage error without oversized stdout. `--count` still returns its structured zero-count object, and explicit location formats retain their existing format-specific empty-result output. |
| Raw discovery JSON shape | `symbols` and `files` build each result row through the same DTO path for array, NDJSON, and envelope output. `symbols --json=array` therefore preserves `exact_index_available` just like NDJSON. Every cardinality and `--max-json-bytes` path keeps the selected flat shape: zero-result NDJSON is an empty stream, `--json=array` is always an array, and byte-capped output omits whole trailing rows without changing the top-level type. Bounded projections keep rows in `results`, pagination facts in `metadata`, and exact-query readiness in `metadata.response_context`; they never reuse a result row as response context. Use `--format compact` or `--json-envelope` when truncation and freshness metadata must accompany the results. |
| Generated-code filtering metadata | DB-backed discovery `query_context` always reports `include_generated`, `generated_code_policy`, and `generated_file_filter_available`. The `files --count --json` and every JSON `map` summary (including `issue-drafts`) also report `generated_file_count_excluded` and `generated_file_count_excluded_authoritative`. The excluded count is `0` when generated files are included. For a legacy DB without `files.generated` when filtering is requested, the policy is `unavailable`, the count is `null`, and the authoritative/available flags are `false` rather than claiming that an unavailable filter ran; explicit `--include-generated` remains `include` with an authoritative excluded count of `0`. Byte-capped and uncapped raw discovery arrays retain SQLite trust diagnostics even when the query returns no result rows. |
Expand Down Expand Up @@ -5673,6 +5674,7 @@ help はすべてこのレジストリを参照します。field 名は大文字
| human-readable default | query command(`search`、`definition`、`references`、`callers`、`callees`、`symbols`、`files`、`excerpt`、`map`、`inspect`、`outline`、`suggestions`)は既定で**人間向け出力**です。 |
| `--json` | JSON lines output(1 行 1 JSON object)に切り替えます。AI agent が容易に parse できるよう設計されています。 |
| 委譲された audit command identity | `audit` は内部で recipe 実行を `search` へ委譲しますが、人間向け usage、復旧 hint、生成する replay command では公開された `audit` identity を維持します。明示的な `audit --json` の usage error は `command: "audit"` を持つ安定した version 付き command-error object を出力し、人間向けの `usage` を含めません。直接の `search` error は `search` identity を維持します。 |
| recipe issue-draft summary | `search --recipe ... --format issue-drafts --summary-only` と `audit` alias は、完全な issue body を描画せず専用 summary DTO を使います。結果がある各 recipe query は、query / title identity、result / file 件数、最大 5 件の count 付き evidence path と明示的な path 省略 metadata、label、severity、confidence、任意の result cursor、full-detail replay command を持つ compact な `drafts[]` row を 1 件生成します。root は `total_count` とその authority / lower bound、`returned_count`、`omitted_count`、`truncated`、上限なし summary 用の `recovery_command` を返します。`--max-json-bytes` は最後の改行を含む正確な UTF-8 document を計測し、末尾の完全な summary row だけを省略します。0 row envelope も収まらない上限では、呼び出された `search` または `audit` identity の型付き `E028_RESPONSE_BUDGET_TOO_SMALL` guidance を返します。full issue-draft mode は既存の recipe metadata、evidence、source、triage、描画済み body shape を維持します。 |
| `definition --json` の未検出 | 既定 format の definition lookup で一致する symbol がない場合、`--body` の有無にかかわらず、共通の versioned `E018_QUERY_NOT_FOUND` command-error object を出力して終了コード `2` を返します。空の stdout のまま成功することはありません。bounded-envelope control の使用時は object を location row として projection せず `metadata.error` に移し、`results` は空のままにします。この object は `--max-json-bytes` に対して事前検査され、収まらない上限では oversized stdout を出さず usage error を返します。`--count` は引き続き構造化された 0 件 object を返し、明示的な location format も既存の format 固有の empty-result output を維持します。 |
| raw discovery JSON shape | `symbols` と `files` は、array、NDJSON、envelope の各出力で同じ DTO 経路から result row を構築します。そのため `symbols --json=array` も NDJSON と同様に `exact_index_available` を保持します。結果件数や `--max-json-bytes` の有無にかかわらず選択した flat shape を維持し、0 件の NDJSON は空 stream、`--json=array` は常に array となり、byte cap 到達時は top-level type を変えずに末尾の完全な row を省略します。bounded projection は row を `results`、pagination fact を `metadata`、exact-query readiness を `metadata.response_context` に保持し、result row を response context として再利用しません。truncation / freshness metadata も結果と一緒に必要な場合は `--format compact` または `--json-envelope` を使用します。 |
| generated-code filtering metadata | DB-backed discovery の `query_context` は常に `include_generated`、`generated_code_policy`、`generated_file_filter_available` を返します。`files --count --json` と `issue-drafts` を含むすべての JSON `map` summary は、`generated_file_count_excluded` と `generated_file_count_excluded_authoritative` も返します。generated file を含める場合、除外数は `0` です。`files.generated` が無い legacy DB で filter が要求された場合、未実行の filter を実行済みと誤認させないよう、policy は `unavailable`、count は `null`、authoritative / available flag は `false` になります。明示的な `--include-generated` は `include` のままで、authoritative な除外数 `0` を返します。byte cap の有無にかかわらず、raw discovery array は query result row が 0 件でも SQLite trust diagnostics を維持します。 |
Expand Down
2 changes: 2 additions & 0 deletions TESTING_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Use the full suite by default. Use targeted filters only while iterating locally
## Test Stack

- `WorkspaceCheckTruncationIssue5055Tests` owns the bounded `workspace_check` list contract. Keep zero, below-limit, exact-limit, and over-limit coverage for all six categories, plus the 1260/20/1240 example and one shared filesystem fixture for raw JSON, list-only projection, compact output, byte-budget trimming, deterministic order, and human sample labeling.
- Recipe issue-draft summary coverage in `QueryCommandRunnerSearchTests` keeps the dedicated compact DTO separate from full draft bodies, asserts returned/total/omitted row cardinality (including `count == drafts.length` and positive queries hidden by `--total-limit`), preserves pre-limit evidence-path counts with authority/lower-bound metadata, measures the complete UTF-8 document with multibyte paths and its final newline, verifies whole-row truncation and typed `E028` audit identity, and preserves the full-output contract.
- Marker-gate reference coverage keeps cross-language positive syntax in `ReferenceExtractorMarkerGateTests.cs`, with dedicated GraphQL/HTML/Markdown and XAML/XML cases proving that markerless continuation lines still advance parser state. `ReferenceExtractorPerformanceBudgetTests` owns three complementary regressions: Kotlin infix detection must not enumerate a large known-name set, Docker instruction classification must allocate nothing and scale with the instruction prefix rather than irrelevant line length, and warmed C#/Java/Kotlin markerless-decoy extraction must produce no references while staying below 24 MiB of measured allocations and the 3-second primary-target runaway guard. Keep the broad allocation/time guards on `net8.0`; keep the focused positive and state-preservation tests cross-target.
- Framework: xUnit
- Target frameworks: `net8.0` and `net9.0`
Expand Down Expand Up @@ -1016,6 +1017,7 @@ dotnet test --filter "FullyQualifiedName~GitHelperTests"
## テストスタック

- `WorkspaceCheckTruncationIssue5055Tests` は上限付き `workspace_check` 一覧の契約を担当します。6カテゴリすべての0件・上限未満・上限一致・上限超過、1260/20/1240 の例、および raw JSON、一覧単独 projection、compact 出力、byte budget による短縮、決定的順序、human 向け sample 表示を1つの共有 filesystem fixture で検証する coverage を維持してください。
- `QueryCommandRunnerSearchTests` の recipe issue-draft summary coverage は、専用 compact DTO を完全版 draft body から分離し、返却 / total / omitted row の cardinality(`count == drafts.length` と `--total-limit` に隠れた positive query を含む)、limit 適用前の evidence-path count と authority / lower-bound metadata の維持、multibyte path と末尾改行を含む UTF-8 document 全体の計測、完全な row 単位の truncation、型付き `E028` の audit identity、完全版 output contract の維持を検証します。
- marker gate の reference coverage は、言語横断の正しい構文を `ReferenceExtractorMarkerGateTests.cs` にまとめ、GraphQL/HTML/Markdown と XAML/XML の専用 case で marker のない継続行でも parser state が更新されることを固定します。`ReferenceExtractorPerformanceBudgetTests` は相補的な3つの回帰契約を所有します。Kotlin infix 検出では大きな既知名集合を列挙しないこと、Docker instruction 分類では allocation が0で無関係な行長ではなく instruction prefix に応じて scale すること、warmup 済みの C#/Java/Kotlin markerless-decoy 抽出では reference が0件のまま計測 allocation 24 MiB未満かつ primary target の3秒 runaway guard内であることを検証します。広い allocation / time guard は `net8.0` に限定し、focused な正例とstate維持のテストはcross-targetのままにしてください。
- フレームワーク: xUnit
- メインのテストプロジェクト: `tests/CodeIndex.Tests/CodeIndex.Tests.csproj`
Expand Down
37 changes: 26 additions & 11 deletions USER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1674,12 +1674,21 @@ tune duplicate preflight strictness; the JSON summary reports `confidence` and
`minimum_score`. Draft bodies include evidence paths, representative source
snippets, omitted-result metadata, and recipe metadata. Add `--summary-only`
to recipe issue-draft export when agents only need compact top-level metadata:
the output keeps issue-ready draft evidence and per-draft source metadata, omits
the full top-level `recipe` metadata, emits `recipe_summary`, and includes
`query_freshness` for zero-result child queries. Add `--snippet-lines 0` for
path/line-only evidence and combine issue-draft export with `--max-json-bytes <n>`
when an automation budget must fail closed. These drafts are triage aids; review
duplicate guidance and current open issues before filing.
the output uses a dedicated summary contract with one compact row per positive
query instead of embedding full issue bodies, source rows, or repeated recipe
metadata. Each row reports counts, severity/confidence, labels, at most five
evidence paths with explicit omission counts, count authority/lower bounds when
the candidate window is incomplete, and a full-detail replay command. Positive
queries remain represented even when `--total-limit` leaves them with zero
returned results; the uncapped recovery command omits that run-wide limit.
The root reports total/returned/omitted row counts, whether the total is
authoritative, `query_freshness`, and an uncapped `recovery_command`. Combine it
with `--max-json-bytes <n>` to measure the complete UTF-8 document (including
its final newline) and keep only whole rows that fit. If even the zero-row
envelope cannot fit, the command fails closed with `E028` and preserves the
invoked `search` or `audit` command in its retry guidance. Without
`--summary-only`, the full issue-draft contract remains unchanged. These drafts
are triage aids; review duplicate guidance and current open issues before filing.

### Debugging queries

Expand Down Expand Up @@ -5139,11 +5148,17 @@ duplicate-preflight metadata を持つ issue draft object を出力します。
JSON summary には `confidence` と `minimum_score` が出力されます。draft body は evidence path、
代表的な source snippet、omitted-result metadata、recipe metadata を含みます。エージェントが compact な
top-level metadata だけを必要とする場合は、recipe issue-draft export に `--summary-only` を追加します。
この出力は Issue 作成に必要な draft evidence と draft ごとの source metadata を保ち、top-level の
完全な `recipe` metadata を省略し、`recipe_summary` と zero-result child query 用の `query_freshness` を出力します。
path / line だけの evidence にしたい場合は `--snippet-lines 0` を追加し、automation budget を超える出力を閉じたい場合は
issue-draft export に `--max-json-bytes <n>` を併用します。これらの draft は triage aid なので、起票前に
duplicate guidance と現在の open issue を確認してください。
この出力は専用の summary contract を使い、完全な Issue body、source row、query ごとに重複する
recipe metadata を埋め込まず、結果がある query ごとに compact な row を1件出力します。各 row は
count、severity / confidence、label、最大5件の evidence path、明示的な省略件数、candidate window が
不完全な場合の count authority / lower bound、完全な詳細を取得する replay command を返します。
`--total-limit` により返却 result が0件になった positive query も row として保持し、上限なしの recovery
command からは run 全体のその limit を除外します。root は total / returned / omitted row count、total が authoritative か、
`query_freshness`、上限なしの `recovery_command` を返します。`--max-json-bytes <n>` を併用すると、末尾の
改行を含む UTF-8 document 全体を計測し、上限に収まる完全な row だけを保持します。row 0件の envelope
さえ収まらない場合は `E028` で fail-closed にし、retry guidance でも実行元の `search` または `audit`
command を維持します。`--summary-only` を付けない完全版 issue-draft contract は変更しません。これらの
draft は triage aid なので、起票前に duplicate guidance と現在の open issue を確認してください。

### クエリのデバッグ

Expand Down
21 changes: 21 additions & 0 deletions changelog.d/unreleased/5058.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
category: fixed
issues:
- 5058
affected:
- src/CodeIndex/Cli/QueryCommandRunner.SearchRecipes.cs
- src/CodeIndex/Cli/SearchAuditRecipes.cs
- src/CodeIndex/Cli/JsonOutputContracts.cs
- tests/CodeIndex.Tests/QueryCommandRunnerSearchTests.cs
- USER_GUIDE.md
- DEVELOPER_GUIDE.md
- TESTING_GUIDE.md
---

## English

- **Recipe issue-draft summaries now fit bounded automation payloads (#5058; follow-up to #4064, #4118, and #4308)** — `--summary-only` now uses a dedicated compact contract with one whole row per positive query, including queries hidden by `--total-limit`, bounded evidence paths with truthful authority/lower-bound metadata, full-detail replay commands, and an uncapped recovery command. `--max-json-bytes` measures the complete UTF-8 document including its final newline, truncates only at row boundaries, and preserves the invoked `search` or `audit` identity in `E028` guidance; full issue-draft output remains unchanged.

## 日本語

- **recipe issue-draft summary が automation の上限付き payload に収まるよう修正しました (#5058、#4064、#4118、#4308 の follow-up)** — `--summary-only` は、`--total-limit` に隠れた query を含む結果がある query ごとの完全な row、正確な authority / lower-bound metadata を伴う上限付き evidence path、完全な詳細を取得する replay command、上限なしの recovery command を持つ専用 compact contract を使います。`--max-json-bytes` は末尾改行を含む UTF-8 document 全体を計測し、row 境界だけで truncate し、`E028` guidance でも実行元の `search` または `audit` identity を維持します。完全版 issue-draft output は変更しません。
2 changes: 2 additions & 0 deletions src/CodeIndex/Cli/JsonOutputContracts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1339,6 +1339,8 @@ internal sealed record ValidateConfigJsonResult(
[JsonSerializable(typeof(SearchRecipeScopeJsonResult))]
[JsonSerializable(typeof(SearchRecipeExcludedDiagnosticJsonResult))]
[JsonSerializable(typeof(SearchIssueDraftExportJsonResult))]
[JsonSerializable(typeof(SearchIssueDraftSummaryExportJsonResult))]
[JsonSerializable(typeof(SearchIssueDraftSummaryJsonResult))]
[JsonSerializable(typeof(SearchIssueDraftJsonResult))]
[JsonSerializable(typeof(SearchIssueDraftEvidenceJsonResult))]
[JsonSerializable(typeof(SearchIssueDraftSourceJsonResult))]
Expand Down
Loading
Loading