Skip to content

Commit 4863874

Browse files
committed
Preserve partial archive trust on scoped updates (#5053)
1 parent f58c4bd commit 4863874

8 files changed

Lines changed: 107 additions & 80 deletions

File tree

DEVELOPER_GUIDE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Development contracts:
5656
| 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. |
5757
| 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. |
5858

59-
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 reset unknown-extension summaries. Import repeats that normalization for legacy manifests without scope metadata, while current full-snapshot manifests preserve trust.
59+
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`.
6060

6161
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.
6262

@@ -3719,7 +3719,7 @@ net9 CI lane に合わせる場合は `FRAMEWORK=net9.0 make test` を使いま
37193719
| binary compatibility | [COMPATIBILITY.md](COMPATIBILITY.md) | `cdidx` binary の upgrade / downgrade をまたぐ database compatibility を記載します。readiness bit、`codeindex_meta` contract stamp、rebuild requirement を変える場合は、この policy も更新してください。 |
37203720
| 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` を含みます。 |
37213721

3722-
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 を reset します。scope metadata がない legacy manifest は import 時に同じ正規化を行い、現行の full-snapshot manifest は trust を維持します。
3722+
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 します
37233723

37243724
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 となり、変更前に拒否されます。
37253725

TESTING_GUIDE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ Use `docs/test-doc-maintenance-plan.md` before moving oversized suites or adding
225225
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`.
226226
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.
227227
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.
228-
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 or unknown-extension trust, fails `status --check`, and leaves the source DB unchanged. 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.
228+
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.
229229
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.
230230
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.
231231
Dry-run JSON coverage for ambiguous `.h` files locks the bounded `language_detections` entries and their stable source/confidence codes without mutating the index.
@@ -1223,7 +1223,7 @@ dotnet test --filter "FullyQualifiedName~GitHelperTests"
12231223
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 を確認します。
12241224
`ProgramCliTests.cs` の quiet flag coverage は1つの seeded symbols database を text、NDJSON、JSON array の各 mode で再利用し、末尾に quiet alias を付けた場合と付けない場合の stdout を比較して、quiet mode が informational stderr だけを変えることを固定します。
12251225
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 を汚染しないようにします。
1226-
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 / unknown-extension trust を持たず、`status --check` が失敗し、source DB が変更されないことを検証してください。full import はそれらの trust field を維持し、scope を除いた manifest のコピーは同じ保守的な partial state を materialize します。default import と replacement は別々の CLI 呼び出しと destination に保ち、pristine archive を直接変更しないでください。
1226+
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 を直接変更しないでください。
12271227
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 名を同時に検証します。
12281228
ctags export JSON coverage は1つの seeded database を既定と `--include-generated` variant で再利用し、固定された skip-reason key の合計が `skipped_count` と一致することを検証します。`files.generated` がない場合の縮退は別の legacy-schema fixture に保ってください。
12291229
曖昧な `.h` に対する dry-run JSON coverage は、index を変更せず、上限付き `language_detections` entry と安定した判定元・信頼度 code を固定します。

USER_GUIDE.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -511,9 +511,11 @@ full archive and preserves the source database's index completeness,
511511
indexed-HEAD provenance, run telemetry, and unknown-extension summary. A
512512
filtered archive is instead stamped `index_complete: false` with the stable
513513
`partial_archive` reason, clears source-wide indexed-HEAD and run metadata, and
514-
resets unknown-extension summaries so `status` cannot present the subset as a
515-
fresh full index. This normalization applies only to the exported snapshot and
516-
does not mutate the source database.
514+
omits unavailable unknown-extension summaries so `status` cannot present the
515+
subset as a fresh full index or an authoritative zero-result scan. This
516+
normalization applies only to the exported snapshot and does not mutate the
517+
source database. A later scoped index request falls back to a full workspace
518+
scan before clearing `partial_archive`.
517519
Portable export refuses an existing destination by default; pass `--overwrite`
518520
only when replacing it is intentional. The archive is built in an owner-only
519521
sibling temporary file and atomically published, and POSIX archives are verified
@@ -4014,9 +4016,11 @@ file count が含まれます。scope には `represents_entire_source_database`
40144016
scope flag を指定しない full archive は source database の index completeness、
40154017
indexed-HEAD provenance、run telemetry、unknown-extension summary を維持します。一方、
40164018
filter 済み archive は `index_complete: false` と stable reason `partial_archive` を記録し、
4017-
source 全体に対する indexed-HEAD / run metadata を消去して unknown-extension summary を
4018-
reset するため、`status` が subset を fresh な full index として表示することはありません。
4019-
この正規化は export snapshot だけに適用され、source database は変更しません。
4019+
source 全体に対する indexed-HEAD / run metadata を消去し、未計測の unknown-extension
4020+
summary を省略するため、`status` が subset を fresh な full index や authoritative な
4021+
0 件 scan として表示することはありません。この正規化は export snapshot だけに適用され、
4022+
source database は変更しません。後続の scoped index request は `partial_archive` を解除する前に
4023+
full workspace scan へ fallback します。
40204024
portable export は既存 destination を既定で拒否します。意図して置き換える場合だけ
40214025
`--overwrite` を指定してください。archive は owner-only の sibling temporary file に
40224026
構築して atomic に publish し、POSIX では mode `0600` であることも検証します。

changelog.d/unreleased/5053.fixed.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ affected:
66
- src/CodeIndex/Cli/ExportImportCommandRunner.ArchiveScope.cs
77
- src/CodeIndex/Cli/ExportImportCommandRunner.Manifest.cs
88
- src/CodeIndex/Cli/ExportImportManifestCodec.cs
9+
- src/CodeIndex/Cli/IndexCommandRunner.cs
10+
- src/CodeIndex/Cli/IndexCommandRunner.Update.cs
911
- tests/CodeIndex.Tests/ExportImportCommandRunnerTests.cs
1012
- USER_GUIDE.md
1113
- DEVELOPER_GUIDE.md
@@ -14,8 +16,8 @@ affected:
1416

1517
## English
1618

17-
- **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, and reset unknown-extension summaries, while full unfiltered archives preserve their trust metadata.
19+
- **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.
1820

1921
## 日本語
2022

21-
- **filter 済み portable archive が保守的な trust metadata を報告するようになりました (#5053)** — scope 付き export と scope 情報がない legacy import は `partial_archive` により incomplete とし、source 全体に対する HEAD / run provenance を削除して unknown-extension summary を reset します。filter なしの full archive は従来の trust metadata を維持します。
23+
- **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 を維持します。

0 commit comments

Comments
 (0)