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 DEVELOPER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ Development contracts:
| Binary compatibility | [COMPATIBILITY.md](COMPATIBILITY.md) | Database compatibility across `cdidx` binary upgrades and downgrades is documented there. Keep that policy updated whenever readiness bits, `codeindex_meta` contract stamps, or rebuild requirements change. |
| Fold backfill preview and recovery | `backfill-fold --dry-run`; `backfill-fold --checkpoint`; MCP `backfill_fold` with `dry_run: true` or `force: true` | Dry-run previews folded-key rows without mutating the DB or stamping FoldReady. `--checkpoint` explicitly preserves a snapshot even when CLI preflight finds no mutation, while the default completed no-op leaves no checkpoint artifacts. MCP accepts the same preview and can force rewriting all folded keys when an operator needs to recover from suspicious fold metadata or row state even though the stored version/fingerprint appears current. Non-dry-run row rewrites are resumable after interruption: completed row updates remain durable, and final FoldReady metadata is stamped only after verification succeeds. MCP responses include `progress.rows_done`, `progress.rows_total`, and `progress.fraction` so clients can report and retry long backfills. |

Portable archive trust is scope-aware. Unfiltered exports set `scope.represents_entire_source_database` and preserve completeness, indexed-HEAD, run, and unknown-extension metadata. Filtered exports normalize only the archive snapshot to `index_complete=false` with `partial_archive`, remove source-wide HEAD/run provenance, and omit unavailable unknown-extension summaries. Import repeats that normalization for legacy manifests without scope metadata, while current full-snapshot manifests preserve trust. Scoped indexing of a partial archive falls back to a full workspace scan before it may clear `partial_archive`.

Checkpoint plan drift detection covers DB/WAL/SHM content changes and sidecar appearance or disappearance through the final pre-publication validation. The plan's `uncertainty` value records the remaining post-validation race; copied outputs are independently hash-verified against the plan before atomic publication. DB/WAL/SHM candidates must pass native regular-file type validation before hashing so Unix FIFOs cannot block planning. `metadata_policy` reports `owner_only_files_and_directories` on POSIX and the actually inherited `inherited_windows_acls` policy on Windows. A database payload whose output name collides with `manifest.txt`, including filesystem-equivalent casing, makes the plan not ready and is rejected before mutation.

## Filesystem Permissions
Expand Down Expand Up @@ -3719,6 +3721,8 @@ net9 CI lane に合わせる場合は `FRAMEWORK=net9.0 make test` を使いま
| binary compatibility | [COMPATIBILITY.md](COMPATIBILITY.md) | `cdidx` binary の upgrade / downgrade をまたぐ database compatibility を記載します。readiness bit、`codeindex_meta` contract stamp、rebuild requirement を変える場合は、この policy も更新してください。 |
| Fold backfill の preview / recovery | `backfill-fold --dry-run`; `backfill-fold --checkpoint`; MCP `backfill_fold` の `dry_run: true` または `force: true` | dry-run は DB を変更せず FoldReady stamp も書かずに、rewrite 対象の folded-key row をプレビューします。CLI preflight でmutation不要と判断された場合でもsnapshotを明示的に保存するには `--checkpoint` を使います。既定の完了済みno-opはcheckpoint artifactを作りません。MCP も同じ preview を受け付け、stored version / fingerprint が current に見える場合でも suspicious な fold metadata や row state を復旧するため `force: true` を受け付けます。non-dry-run rewrite は中断後に resume でき、完了済み row update は durable に残り、最終 FoldReady metadata は verification 成功後にだけ stamp されます。MCP response は `progress.rows_done`、`progress.rows_total`、`progress.fraction` を含みます。 |

portable archive の trust は scope を考慮します。filter なし export は `scope.represents_entire_source_database` を設定し、completeness、indexed-HEAD、run、unknown-extension metadata を維持します。filter 済み export は archive snapshot だけを `index_complete=false` / `partial_archive` に正規化し、source 全体に対する HEAD / run provenance を削除して、未計測の unknown-extension summary を省略します。scope metadata がない legacy manifest は import 時に同じ正規化を行い、現行の full-snapshot manifest は trust を維持します。partial archive に対する scoped index は `partial_archive` を解除する前に full workspace scan へ fallback します。

checkpoint plan の drift 検出は、publish 前の最終検証までに起きる DB/WAL/SHM content の変更と sidecar の出現・消失を対象にします。plan の `uncertainty` 値は最終検証後に残る race を記録し、copy 済み output は atomic publish 前に plan の hash と個別に照合されます。DB/WAL/SHM 候補は hash 読み取り前に native regular-file type validation を通すため、Unix FIFO が plan 作成を停止させることはありません。`metadata_policy` は POSIX では `owner_only_files_and_directories`、Windows では実際に継承される `inherited_windows_acls` policy を報告します。database payload の output 名が filesystem 上で同一の大小文字を含め `manifest.txt` と衝突する場合、plan は not ready となり、変更前に拒否されます。

## ファイルシステム権限
Expand Down
4 changes: 2 additions & 2 deletions TESTING_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ Use `docs/test-doc-maintenance-plan.md` before moving oversized suites or adding
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.
Archive-import validation coverage reuses one pristine database export across read-only dry-run and check modes with distinct destinations. Rejection coverage copies one pristine export into manifest-count, database-hash, and user-version variants before mutating any ZIP so one corruption cannot contaminate another.
Archive success-path coverage seeds one metadata-rich database and shares its pristine export across scoped manifest inspection, a default import into a nonexistent destination, a copied legacy-manifest import, and a separate `--no-backup` replacement. Keep the default import and replacement as distinct CLI calls and destinations, and never mutate the pristine archive.
Archive success-path coverage seeds one metadata-rich database and shares its pristine export across scoped manifest inspection, a default import into a nonexistent destination, a copied legacy-manifest import, and a separate `--no-backup` replacement. Scope coverage must prove a filtered snapshot is incomplete with `partial_archive`, has no source-wide HEAD/run trust, omits unavailable unknown-extension coverage, fails `status --check`, and leaves the source DB unchanged. A later scoped index must fall back to a full workspace scan before restoring complete trust. Full-import coverage preserves those trust fields, while the copied scope-less manifest materializes the same conservative partial state. Keep the default import and replacement as distinct CLI calls and destinations, and never mutate the pristine archive.
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.
Dry-run JSON coverage for ambiguous `.h` files locks the bounded `language_detections` entries and their stable source/confidence codes without mutating the index.
Expand Down Expand Up @@ -1226,7 +1226,7 @@ dotnet test --filter "FullyQualifiedName~GitHelperTests"
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 だけを変えることを固定します。
archive import validation coverage は、read-only な dry-run / check mode で1つの pristine database export を別々の destination から共有してください。拒否 coverage では、mutation 前に1つの pristine export を manifest-count、database-hash、user-version 用の3つの ZIP へコピーし、ある corruption が別 case を汚染しないようにします。
archive success-path coverage は、metadata-rich な database を1回 seed し、その pristine export を scoped manifest inspection、存在しない destination への default import、コピーした legacy manifest の import、別 destination への `--no-backup` replacement で共有します。default import と replacement は別々の CLI 呼び出しと destination に保ち、pristine archive を直接変更しないでください。
archive success-path coverage は、metadata-rich な database を1回 seed し、その pristine export を scoped manifest inspection、存在しない destination への default import、コピーした legacy manifest の import、別 destination への `--no-backup` replacement で共有します。scope coverage では filter 済み snapshot が `partial_archive` により incomplete となり、source 全体に対する HEAD / run trust を持たず、未計測の unknown-extension coverage を省略し、`status --check` が失敗し、source DB が変更されないことを検証してください。後続の scoped index は complete trust を復元する前に full workspace scan へ fallback しなければなりません。full import はそれらの trust field を維持し、scope を除いた manifest のコピーは同じ保守的な partial state を materialize します。default import と replacement は別々の CLI 呼び出しと destination に保ち、pristine archive を直接変更しないでください。
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 に保ってください。
曖昧な `.h` に対する dry-run JSON coverage は、index を変更せず、上限付き `language_detections` entry と安定した判定元・信頼度 code を固定します。
Expand Down
34 changes: 29 additions & 5 deletions USER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,17 @@ exclusion, and test filters then narrow that scope. The exported SQLite
snapshot contains only the retained files and their dependent chunks, symbols,
references, and diagnostics, and is vacuumed before packaging. JSON output and
`manifest.json` include the requested scope, resolved project paths, and source
and exported file counts. An export without scope flags remains a full archive.
and exported file counts. The scope also reports
`represents_entire_source_database`. An export without scope flags remains a
full archive and preserves the source database's index completeness,
indexed-HEAD provenance, run telemetry, and unknown-extension summary. A
filtered archive is instead stamped `index_complete: false` with the stable
`partial_archive` reason, clears source-wide indexed-HEAD and run metadata, and
omits unavailable unknown-extension summaries so `status` cannot present the
subset as a fresh full index or an authoritative zero-result scan. This
normalization applies only to the exported snapshot and does not mutate the
source database. A later scoped index request falls back to a full workspace
scan before clearing `partial_archive`.
Portable export refuses an existing destination by default; pass `--overwrite`
only when replacing it is intentional. The archive is built in an owner-only
sibling temporary file and atomically published, and POSIX archives are verified
Expand All @@ -521,8 +531,11 @@ database. `--prune-paths` rewrites the imported `indexed_project_root` metadata
to the import target project root. Imports targeting `.../.cdidx/codeindex.db`
use the sibling project directory; other database paths fall back to the process
current directory. `--dry-run` and its `--check` alias also compare an existing
destination DB with the validated archive without replacing it. JSON
`destination_delta.comparison` reports schema and count deltas plus bounded
destination DB with the validated archive without replacing it. JSON results
expose the normalized `index_complete`, `index_incomplete_reasons`, and `scope`
values. Archives with no scope metadata are treated conservatively as partial
during import; current unfiltered archives explicitly preserve full-snapshot
trust. JSON `destination_delta.comparison` reports schema and count deltas plus bounded
file, symbol, reference-edge, chunk, and metadata records. Text fields in those
records are represented by named SHA-256 and UTF-8 byte-length metadata rather
than source content or paths. Use `--limit <n<=10000>` and `--offset <n>` to
Expand Down Expand Up @@ -3999,7 +4012,15 @@ archive export では `--lang`、繰り返し指定できる `--path` / `--exclu
さらに絞り込みます。出力する SQLite snapshot には残した file と、それに従属する
chunk、symbol、reference、diagnostic だけを保持し、packaging 前に vacuum します。
JSON output と `manifest.json` には指定 scope、解決済み project path、元と出力後の
file count が含まれます。scope flag を指定しなければ従来どおり full archive です。
file count が含まれます。scope には `represents_entire_source_database` も含まれます。
scope flag を指定しない full archive は source database の index completeness、
indexed-HEAD provenance、run telemetry、unknown-extension summary を維持します。一方、
filter 済み archive は `index_complete: false` と stable reason `partial_archive` を記録し、
source 全体に対する indexed-HEAD / run metadata を消去し、未計測の unknown-extension
summary を省略するため、`status` が subset を fresh な full index や authoritative な
0 件 scan として表示することはありません。この正規化は export snapshot だけに適用され、
source database は変更しません。後続の scoped index request は `partial_archive` を解除する前に
full workspace scan へ fallback します。
portable export は既存 destination を既定で拒否します。意図して置き換える場合だけ
`--overwrite` を指定してください。archive は owner-only の sibling temporary file に
構築して atomic に publish し、POSIX では mode `0600` であることも検証します。
Expand All @@ -4014,7 +4035,10 @@ SQLite file が CodeIndex DB であることを検証してから destination da
`.../.cdidx/codeindex.db` を import 先にした場合は sibling の project directory を使い、
それ以外の database path では process current directory に fallback します。
`--dry-run` と alias の `--check` は置換せず、既存 destination DB と検証済み archive を
比較します。JSON の `destination_delta.comparison` には schema / count delta と、
比較します。JSON result は正規化後の `index_complete`、`index_incomplete_reasons`、
`scope` を公開します。scope metadata がない archive は import 時に保守的に partial と
扱い、現行の filter なし archive だけが full snapshot の trust を明示的に維持します。
JSON の `destination_delta.comparison` には schema / count delta と、
file、symbol、reference edge、chunk、metadata の bounded record が含まれます。
これらの record の text field は source content や path そのものではなく、名前付きの
SHA-256 と UTF-8 byte length metadata として表現されます。record の paging には
Expand Down
23 changes: 23 additions & 0 deletions changelog.d/unreleased/5053.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
category: fixed
issues:
- 5053
affected:
- src/CodeIndex/Cli/ExportImportCommandRunner.ArchiveScope.cs
- src/CodeIndex/Cli/ExportImportCommandRunner.Manifest.cs
- src/CodeIndex/Cli/ExportImportManifestCodec.cs
- src/CodeIndex/Cli/IndexCommandRunner.cs
- src/CodeIndex/Cli/IndexCommandRunner.Update.cs
- tests/CodeIndex.Tests/ExportImportCommandRunnerTests.cs
- USER_GUIDE.md
- DEVELOPER_GUIDE.md
- TESTING_GUIDE.md
---

## English

- **Filtered portable archives now report conservative trust metadata (#5053)** — Scoped exports and legacy scope-less imports are marked incomplete with `partial_archive`, clear source-wide HEAD/run provenance, omit unavailable unknown-extension summaries, and require a full workspace scan before scoped indexing can restore complete trust, while full unfiltered archives preserve their trust metadata.

## 日本語

- **filter 済み portable archive が保守的な trust metadata を報告するようになりました (#5053)** — scope 付き export と scope 情報がない legacy import は `partial_archive` により incomplete とし、source 全体に対する HEAD / run provenance と未計測の unknown-extension summary を削除します。scoped index が complete trust を復元する前には full workspace scan を必須とし、filter なしの full archive は従来の trust metadata を維持します。
Loading
Loading