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
4 changes: 4 additions & 0 deletions .github/scripts/run-dotnet-tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ function Invoke-TestRun {
$runArgs += @("--filter", $TestFilter)
}

# Performance budgets must distinguish instrumented runs from ordinary retries.
# performance budget が coverage 計測中と通常の retry を区別できるようにする。
$env:CODEINDEX_TEST_COVERAGE = if ($IncludeCoverage) { "true" } else { "false" }

[int]$failureLogTailLineLimit = 2000
$retainedOutputTail = [System.Collections.Generic.Queue[string]]::new($failureLogTailLineLimit)
[long]$totalOutputLineCount = 0
Expand Down
33 changes: 33 additions & 0 deletions DEVELOPER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1531,6 +1531,24 @@ Current stable codes and triggers:
| Memory tracing | `index --json --memory-trace` adds a `memory_timeline` block to the CLI index result and persists peak working-set MB into `last_index_run`; dry-run results also emit live `start`, `snapshot`, `scan`, and `finalize` samples but never persist run metadata. `index --dry-run --rebuild` bypasses destructive confirmation because it does not delete or rewrite the index. `CDIDX_MEM_WARN_MB=<mb>` prints a warning when the sampled working set crosses that threshold. |
| Newer schema protection | Writable opens reject databases whose `PRAGMA user_version` contains readiness bits outside the current binary's `CurrentSchemaVersion` mask. Read-only status/query paths may still surface `index_newer_than_reader=true` as a degraded audit signal, but write-capable paths must fail with `E003_SCHEMA_TOO_NEW` so an older cdidx cannot silently rewrite a DB stamped by a newer one. |

Status freshness summaries are classified by one shared evaluator. An
authoritative `status --check` supplies the file-level result. Without that check,
`last_workspace_freshened_at >= latest_modified` can prove a checksum-reused
no-op update fresh only when the worktree is clean and the runtime,
workspace-verified, and latest-index HEAD SHAs all agree, and Git reports no
`skip-worktree` or `assume-unchanged` entry that could hide a later change.
The Git dirtiness probe explicitly requests all untracked files, overriding a
repository-level `status.showUntrackedFiles=no` setting. Missing provenance,
hidden index state, future timestamps, and an ordinary-status dirty worktree are
`unknown`; a later modification is `stale`, and changed HEAD remains conservative.
An authoritative file check may prove freshness in a dirty repository when every
workspace path matches, so already-indexed untracked paths and dirtiness outside a
subdirectory index do not fail check mode. Status-level HEAD/branch drift is still
evaluated before that file check and propagated into checked failures, exit status,
and workspace member health. Ordinary
`head_freshness=head_current` semantics remain distinct from the authoritative
checked `fresh` value.

`vacuum --dry-run` accepts supported local SQLite URI spellings such as `file:/absolute/path/codeindex.db`, Windows `file:/C:/absolute/path/codeindex.db`, and canonical `file:///...` forms. Single-slash paths are canonicalized while retaining their original query string and ignoring URI fragments, and validation plus metric collection use that same query-only URI so an explicit `immutable=1` keeps its stale-snapshot semantics.

### Data directory resolution
Expand Down Expand Up @@ -5708,6 +5726,21 @@ apply 時は `PRAGMA optimize` を実行します。
| memory tracing | `index --json --memory-trace` は CLI index 結果に `memory_timeline` block を追加し、peak working-set MB を `last_index_run` に保存します。dry-run 結果も live な `start`、`snapshot`、`scan`、`finalize` sample を返しますが、run metadata は保存しません。`index --dry-run --rebuild` は index を削除も rewrite もしないため destructive confirmation を bypass します。`CDIDX_MEM_WARN_MB=<mb>` は sampled working set がしきい値を超えたときに warning を出します。 |
| newer schema protection | writable open は、`PRAGMA user_version` に current binary の `CurrentSchemaVersion` mask 外の readiness bit が含まれる database も拒否します。read-only status/query path は degraded audit signal として `index_newer_than_reader=true` を表示できますが、write-capable path は古い cdidx が新しい binary で stamp された DB を黙って rewrite しないよう `E003_SCHEMA_TOO_NEW` で失敗しなければなりません。 |

status freshness summary は1つの共有 evaluator で分類します。authoritative な
`status --check` は file-level の結果を提供します。check がない場合、
`last_workspace_freshened_at >= latest_modified` が checksum 再利用 no-op update の
freshness を証明できるのは、worktree が clean で、runtime、workspace 検証済み、直近
index の HEAD SHA がすべて一致し、後続変更を隠せる `skip-worktree` / `assume-unchanged`
entry が Git index に無い場合だけです。Git の dirtiness probe は未追跡 file を明示的に
すべて要求し、repository の `status.showUntrackedFiles=no` 設定を上書きします。provenance
不足、隠れた index state、未来 timestamp、通常 status の dirty worktree は `unknown`、
後続の変更は `stale` とし、HEAD 変更は保守的な判定を維持します。authoritative file check
は全 workspace path が一致する場合、dirty repository でも freshness を証明できるため、
index 済み未追跡 path や subdirectory index の scope 外にある dirtiness は check mode を
失敗させません。status-level の HEAD / branch drift は引き続き file check より先に評価し、
checked failure、終了 status、workspace member health に伝播します。通常 status
の `head_freshness=head_current` は、authoritative check 済みの `fresh` と引き続き区別します。

`vacuum --dry-run` は、`file:/absolute/path/codeindex.db`、Windows の `file:/C:/absolute/path/codeindex.db`、canonical な `file:///...` 形式を受け付けます。single-slash の path を canonicalize しつつ元の query string を維持して URI fragment を無視し、validation と metric 収集に同じ query-only URI を使うため、明示的な `immutable=1` の stale-snapshot semantics も維持されます。

### データディレクトリ解決
Expand Down
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,20 @@ visible here as a compact compatibility index.
| Remediation | `degraded_root_cause`, `degraded_reason`, `recommended_action`, `alternative_action`, `readiness_degradations`, `repair_commands`. |
| MCP-only session diagnostics | `mcp_session`, `mcp_session.metrics`, `queue_capacity`, `queue_depth`, `queued_event_count`, `written_event_count`, `dropped_event_count`, `queue_full_drop_count`, `serialization_failure_count`, `write_failure_count`, `rotation_failure_count`, `batch_flush_count`, `consecutive_failure_count`, `recovery_count`, `next_retry_at`, `last_recovery_at`, `last_failure`, `mcp_session.audit_log`, `queued_record_count`, `written_record_count`, `mcp.rate_limit.bucket_limit`, `mcp.rate_limit.bucket_limit_rejection_count`. |

Ordinary status summaries use `last_workspace_freshened_at` as freshness evidence
after a checksum-reused no-op update only when the runtime HEAD,
`workspace_verified_head_sha`, and `indexed_head_sha` agree and the worktree is
clean. Git index flags that can hide worktree changes (`skip-worktree` or
`assume-unchanged`) make this ordinary-status proof `unknown`, while the Git
dirtiness probe always includes untracked files even when
`status.showUntrackedFiles=no`. Missing provenance or a future timestamp also
yields `unknown`, as does a dirty worktree in ordinary status; an actual workspace
difference remains `stale`. `status --check` performs the authoritative workspace
comparison, so it may prove an already-indexed untracked path fresh even though
ordinary status remains conservatively unknown. A status-level HEAD/branch
transition still fails checked status and member health even when file checks
match. CLI, workspace, and MCP status surfaces share these outcomes.

Persisted JSON subdocuments for `last_index_run.reference_extraction_cap_hits`,
`last_index_run.rebuild_reclaim`, and
`last_failed_or_partial_index_run.file_errors` have a 512 KiB UTF-8 input limit
Expand Down Expand Up @@ -443,6 +457,19 @@ field group を表に残します。
| remediation | `degraded_root_cause`、`degraded_reason`、`recommended_action`、`alternative_action`、`readiness_degradations`、`repair_commands`。 |
| MCP-only session diagnostics | `mcp_session`、`mcp_session.metrics`、`queue_capacity`、`queue_depth`、`queued_event_count`、`written_event_count`、`dropped_event_count`、`queue_full_drop_count`、`serialization_failure_count`、`write_failure_count`、`rotation_failure_count`、`batch_flush_count`、`consecutive_failure_count`、`recovery_count`、`next_retry_at`、`last_recovery_at`、`last_failure`、`mcp_session.audit_log`、`queued_record_count`、`written_record_count`、`mcp.rate_limit.bucket_limit`、`mcp.rate_limit.bucket_limit_rejection_count`。 |

通常の status summary は、checksum 再利用による no-op update 後の鮮度証拠として
`last_workspace_freshened_at` を使います。ただし runtime HEAD、
`workspace_verified_head_sha`、`indexed_head_sha` が一致し、worktree が clean な場合に
限ります。worktree 変更を隠せる Git index flag(`skip-worktree` または
`assume-unchanged`)がある場合、この通常 status の証拠は `unknown` です。また Git の
dirtiness probe は `status.showUntrackedFiles=no` の設定時も未追跡 file を必ず含めます。
provenance が欠けている場合、timestamp が未来の場合、通常 status で worktree が dirty な
場合は `unknown`、実際の workspace 差分は引き続き `stale` です。`status --check` は
authoritative な workspace 比較を行うため、通常 status が保守的に unknown でも、index 済み
未追跡 path を fresh と証明できます。status-level の HEAD / branch 遷移は file check が
一致しても checked status と member health を失敗させます。CLI、workspace、MCP の status
surface はこれらの outcome を共有します。

`last_index_run.reference_extraction_cap_hits`、`last_index_run.rebuild_reclaim`、
`last_failed_or_partial_index_run.file_errors` の永続化 JSON subdocument には、
UTF-8 で 512 KiB の入力上限と最大 depth 16 を適用します。file error と cap-hit
Expand Down
2 changes: 2 additions & 0 deletions TESTING_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Use the full suite by default. Use targeted filters only while iterating locally

## Test Stack

- Issue #5227 status-freshness coverage belongs in `StatusFreshnessEvaluatorTests.cs`, `GitHelperTests.cs`, `GitProcessRunnerTests.cs`, `IndexCommandRunnerTests.cs`, `PathCompatibilityMatrixTests.cs`, `WorkspaceCommandRunnerTests.cs`, and `WorkspaceMetadataEnricherTests.cs`. Keep deterministic timestamp boundaries for checksum-reused no-op updates, later real modifications, missing evidence, future timestamps, dirty worktrees, changed HEAD/branch provenance, `status.showUntrackedFiles=no`, and `skip-worktree` / `assume-unchanged` index flags, including already-indexed untracked paths whose authoritative content check matches and tracked-path output beyond the bounded diagnostic capture size. The integration fixture must keep `indexed_at` unchanged while `last_workspace_freshened_at` advances and must assert ordinary CLI, `status --check`, `head_freshness`, workspace member health/exit status, and MCP classification/check parity or an explicit conservative `unknown` across both target frameworks. The Git-index visibility scan must remain gated behind every ordinary-status trust precondition and must not run for authoritative check mode.
- Issue #5226 impact-count coverage belongs in `DbReaderIssue5226Tests.cs`, `QueryCommandRunnerIssue5226Tests.cs`, `QueryCommandRunnerImpactTests.cs`, and `McpServerIssue5226Tests.cs`. Keep zero, one, above-default, multi-hop, include/exclude-filter, incomplete-graph, dedicated safety-cap, heuristic-fallback, cross-language SQL-readiness, and ordinary row-limited cases together. Human, JSON, compact, and MCP count modes must ignore the presentation limit while preserving authoritative/lower-bound metadata and omitting count-only result rows; capped human output must retain numeric stdout and warn with the reason on stderr.
- Issue #5225 scoped C# dry-run coverage belongs in `IndexCommandRunnerDryRunTests.cs`. Keep paired preview/execution fixtures for `--files`, `--commits`, and `--changed-between`, plus static-interface and member-read expansion identities. Preserve non-C# no-expansion, candidate-cap lower-bound metadata, preflight-error and cancellation controls, human/JSON count and truncation output, and database/source non-mutation assertions across both target frameworks.
- Issue #5197 dependency-cycle coverage belongs in `QueryCommandRunnerIssue5197Tests.cs`, `McpServerIssue5197Tests.cs`, and the `deps-cycles-summary.json` golden in `JsonOutputSnapshotTests.cs`. Keep a cycle larger than the 50-node presentation limit to verify complete analysis, authoritative counts, bounded default materialization in human, JSON, DOT, GraphML, and JSON graph output, compact summaries, explicit raw expansion, expansion-aware recovery guidance, largest-component/grouping metadata, and CLI/MCP parity. A later JSON graph cursor page must report its own materialized and omitted-node totals even when they differ from the global largest component. Verify that SCC summaries aggregate every advertised evidence dimension and that actual MCP summaries and expanded results validate against the advertised `deps` output schema, including node arrays beyond the ordinary 10,000-item row bound. MCP must reject summary mode combined with `format=json-graph` just as the CLI does. Keep the C# suppression fixture mixed: unresolved qualified calls and resolved same-name decoys are removable evidence only with a current identity contract, stale and absent contracts retain qualified calls with unavailable resolution evidence, and confirmed resolved targets must remain and drive the surviving SCC even when their target file contains same-name overloads.
Expand Down Expand Up @@ -1173,6 +1174,7 @@ dotnet test --filter "FullyQualifiedName~GitHelperTests"

## テストスタック

- Issue #5227 の status freshness coverage は `StatusFreshnessEvaluatorTests.cs`、`GitHelperTests.cs`、`GitProcessRunnerTests.cs`、`IndexCommandRunnerTests.cs`、`PathCompatibilityMatrixTests.cs`、`WorkspaceCommandRunnerTests.cs`、`WorkspaceMetadataEnricherTests.cs` が担当します。checksum 再利用による no-op update、後続の実変更、証拠不足、未来 timestamp、dirty worktree、HEAD / branch provenance 変更、`status.showUntrackedFiles=no`、`skip-worktree` / `assume-unchanged` index flag、authoritative な content check が一致する index 済み未追跡 path、および bounded diagnostic capture size を超える tracked-path 出力について、決定的な境界を維持してください。integration fixture では `indexed_at` が変わらず `last_workspace_freshened_at` だけが進むことを確認し、通常 CLI、`status --check`、`head_freshness`、workspace member health / 終了 status、MCP の分類と check が両 target framework で一致するか、明示的に保守的な `unknown` となることを assertion します。Git index visibility scan は通常 status の全 trust precondition が成立した場合だけ実行し、authoritative check mode では実行してはいけません。
- Issue #5226 の impact count coverage は `DbReaderIssue5226Tests.cs`、`QueryCommandRunnerIssue5226Tests.cs`、`QueryCommandRunnerImpactTests.cs`、`McpServerIssue5226Tests.cs` が担当します。0件、1件、既定上限超過、multi-hop、include / exclude filter、不完全 graph、専用 safety cap、heuristic fallback、cross-language の SQL readiness、通常の row 上限制限を一緒に維持してください。human、JSON、compact、MCP の count mode は表示用 limit を無視し、authoritative / lower-bound metadata を保持しながら count-only の result row を生成しないことを検証します。cap 到達時の human 出力は stdout を数値のみのまま保ち、stderr に理由付き warning を出します。
- Issue #5225 の scoped C# dry-run coverage は `IndexCommandRunnerDryRunTests.cs` が担当します。`--files`、`--commits`、`--changed-between` の preview / 実行を対にした fixture と、static-interface / member-read 展開の target identity を維持してください。両 target framework で、非 C# の非展開、candidate cap の lower-bound metadata、preflight error / cancellation control、human / JSON の件数・truncation 出力、database / source の非変更 assertion も保ちます。
- Issue #5197 の dependency-cycle coverage は `QueryCommandRunnerIssue5197Tests.cs`、`McpServerIssue5197Tests.cs`、`JsonOutputSnapshotTests.cs` の `deps-cycles-summary.json` golden が担当します。50 node の表示上限を超える cycle を維持し、完全な解析、authoritative な件数、human、JSON、DOT、GraphML、JSON graph 出力における既定の上限付き materialization、compact summary、明示的な raw 展開、展開状態を考慮した recovery guidance、最大 component / grouping metadata、CLI / MCP parity を検証してください。後続の JSON graph cursor page は global な最大 component と異なる場合も、その page 自身の materialize 済み node 数と省略 node 数を報告します。SCC summary が公開するすべての evidence dimension を集計し、実際の MCP summary と展開結果が通常の 10,000 item の row 上限を超える node array も含めて公開 `deps` output schema に適合することを検証します。また MCP は CLI と同様に summary mode と `format=json-graph` の併用を拒否します。C# 抑制 fixture は、current な identity contract がある場合だけ未解決の修飾 call と解決済みcallの同名decoyを除外可能とし、stale / absent contract では unavailable な resolution evidence として修飾 call を保持し、target file に同名 overload がある場合も確認済みの解決済みtargetが残る SCC を構成する混在状態を維持します。
Expand Down
Loading
Loading