Skip to content

Commit d65ea68

Browse files
authored
Merge pull request #2748 from Widthdom/fix-issue1718-1721
2 parents bb8ba98 + 4f282a0 commit d65ea68

13 files changed

Lines changed: 757 additions & 12 deletions

COMPATIBILITY.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# CodeIndex DB Compatibility
2+
3+
> **[日本語版はこちら / Japanese version](#codeindex-db-compatibility日本語)**
4+
5+
This document defines the compatibility contract between `cdidx` binaries and
6+
the local SQLite database under `.cdidx/codeindex.db`.
7+
8+
## Supported Readers
9+
10+
The public compatibility boundary is the `cdidx` CLI and MCP server reading a
11+
database created by a released `cdidx` binary. The SQLite schema is an internal
12+
storage format, not a public API.
13+
14+
Within a supported release line, newer binaries must read older databases and
15+
degrade optional features explicitly when stored readiness metadata is missing
16+
or stale. Older binaries may read newer databases only when the newer database
17+
does not advertise unknown readiness or contract stamps. If an older binary sees
18+
unknown persisted contract stamps, it must degrade loudly in `status` output and
19+
must refuse writes that could silently discard newer data.
20+
21+
## Schema and Readiness Stamps
22+
23+
`PRAGMA user_version` is a readiness bitmap, not a linear migration number:
24+
25+
| Bit | Field | Meaning |
26+
|---|---|---|
27+
| `1` | `graph_table_available` / graph readiness | `symbol_references` has been fully populated for graph queries. |
28+
| `2` | `issues_table_available` / issue readiness | `file_issues` has been populated for validation results. |
29+
| `4` | `fold_ready` | Folded-name columns are current for Unicode-aware exact-name matching. |
30+
31+
Additional per-feature contract versions live in `codeindex_meta`, including
32+
folded-key metadata, C# symbol-name and metadata-target versions, SQL graph
33+
contract stamps, hotspot-family readiness, index writer version, indexed HEAD
34+
metadata, unknown-extension counts, filesystem case-sensitivity, MAC profile,
35+
and DB/WAL/status diagnostics. These stamps let readers distinguish a feature
36+
that is absent, stale, or newer than the running binary.
37+
38+
## Version Skew Behavior
39+
40+
Use `cdidx status --json` or `cdidx status --check --json` before relying on a
41+
database across binary upgrades or downgrades.
42+
43+
| Scenario | Expected behavior | Operator action |
44+
|---|---|---|
45+
| New binary reads an older DB | Queries continue where possible. Missing readiness fields report degraded status and include remediation strings. | Run the recommended maintenance command from `status`, usually `cdidx backfill-fold` or `cdidx index <projectPath> --rebuild`. |
46+
| Same binary reads its own DB | `status --check --json` reports `index_matches_workspace: true` when file content and HEAD metadata match. | No rebuild required. |
47+
| Older binary reads a newer DB | `index_newer_than_reader` becomes `true` when unknown readiness bits or contract stamps exceed the binary's maximum. Mutating commands refuse to write unsafe newer DBs. | Use the newer `cdidx` binary that wrote the DB, or rebuild the index with the older binary only after accepting loss of newer feature data. |
48+
| Read-only CI artifact | Query commands may use `--read-only` / `--immutable`. Mutating commands reject read-only DBs. | Pin the `cdidx` binary version with the DB artifact when possible. |
49+
50+
## Rebuild Requirements
51+
52+
Additive schema changes should be readable by newer binaries without requiring a
53+
full rebuild. Prefer in-place maintenance for derived data, such as
54+
`cdidx backfill-fold`, when a feature can be refreshed from existing rows.
55+
56+
A rebuild is required when:
57+
58+
- `status` recommends `cdidx index <projectPath> --rebuild`;
59+
- the workspace and DB are intentionally being reset to an older binary version;
60+
- the database is corrupt or fails `cdidx db --integrity-check`;
61+
- a release note explicitly calls out a breaking storage change.
62+
63+
Breaking DB changes must be rare and must document the minimum binary version,
64+
the downgrade behavior, and the rebuild path in release notes.
65+
66+
## CodeIndex DB Compatibility(日本語)
67+
68+
この文書は、`cdidx` binary と `.cdidx/codeindex.db` のローカル SQLite database
69+
の互換性契約を定義します。
70+
71+
## 対応する reader
72+
73+
公開される互換性境界は、release 済み `cdidx` binary が作成した database を
74+
`cdidx` CLI / MCP server が読むことです。SQLite schema は内部 storage format
75+
であり、公開 API ではありません。
76+
77+
対応 release line 内では、新しい binary は古い database を読み、保存済みの
78+
readiness metadata が不足または stale の場合は optional feature を明示的に
79+
degrade しなければなりません。古い binary が新しい database を読めるのは、
80+
その database が未知の readiness / contract stamp を示していない場合だけです。
81+
未知の永続 contract stamp を見た古い binary は `status` で明示的に degrade を
82+
報告し、新しい data を黙って破棄しうる write を拒否します。
83+
84+
## Schema と readiness stamp
85+
86+
`PRAGMA user_version` は線形 migration number ではなく readiness bitmap です。
87+
88+
| Bit | Field | 意味 |
89+
|---|---|---|
90+
| `1` | `graph_table_available` / graph readiness | graph query 用の `symbol_references` が完全に作成済み。 |
91+
| `2` | `issues_table_available` / issue readiness | validation result 用の `file_issues` が作成済み。 |
92+
| `4` | `fold_ready` | Unicode-aware exact-name matching 用の folded-name column が最新。 |
93+
94+
追加の feature contract version は `codeindex_meta` に保存されます。これには
95+
folded-key metadata、C# symbol-name / metadata-target version、SQL graph
96+
contract stamp、hotspot-family readiness、index writer version、indexed HEAD
97+
metadata、unknown-extension count、filesystem case-sensitivity、MAC profile、
98+
DB/WAL/status diagnostics が含まれます。reader はこれらの stamp により、feature
99+
が存在しないのか、stale なのか、実行中 binary より新しいのかを判別できます。
100+
101+
## Version skew 時の動作
102+
103+
binary upgrade / downgrade をまたいで database を使う前に、
104+
`cdidx status --json` または `cdidx status --check --json` を確認してください。
105+
106+
| 状況 | 期待される動作 | 操作者の対応 |
107+
|---|---|---|
108+
| 新しい binary が古い DB を読む | 可能な query は継続します。不足した readiness field は degraded status と remediation を返します。 | `status` の推奨に従い、通常は `cdidx backfill-fold` または `cdidx index <projectPath> --rebuild` を実行します。 |
109+
| 同じ binary が自身の DB を読む | file content と HEAD metadata が一致すると `status --check --json``index_matches_workspace: true` を返します。 | rebuild は不要です。 |
110+
| 古い binary が新しい DB を読む | 未知の readiness bit または contract stamp が binary の最大値を超えると `index_newer_than_reader``true` になります。mutating command は unsafe な write を拒否します。 | その DB を書いた新しい `cdidx` binary を使うか、新しい feature data が失われることを受け入れて古い binary で index を作り直します。 |
111+
| read-only CI artifact | query command は `--read-only` / `--immutable` を利用できます。mutating command は read-only DB を拒否します。 | 可能なら DB artifact と `cdidx` binary version を一緒に pin します。 |
112+
113+
## Rebuild が必要な場合
114+
115+
Additive schema change は、full rebuild を要求せずに新しい binary で読めるべきです。
116+
既存 row から再生成できる derived data は、`cdidx backfill-fold` のような
117+
in-place maintenance を優先します。
118+
119+
rebuild が必要なのは次の場合です。
120+
121+
- `status``cdidx index <projectPath> --rebuild` を推奨している;
122+
- workspace と DB を意図的に古い binary version へ戻す;
123+
- database が壊れている、または `cdidx db --integrity-check` に失敗する;
124+
- release note が breaking storage change を明示している。
125+
126+
Breaking DB change は稀であるべきで、minimum binary version、downgrade behavior、
127+
rebuild path を release note に記載しなければなりません。

DEVELOPER_GUIDE.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,18 @@ cdidx search AuthService --db /artifacts/codeindex.db --immutable
6161
Mutating commands such as `index`, `backfill-fold`, `optimize`, and `vacuum`
6262
require writable storage and reject read-only database opens.
6363

64+
Use `cdidx db checkpoint <name>` to take a filesystem snapshot of
65+
`codeindex.db` plus existing WAL/SHM sidecars before risky maintenance, and use
66+
`cdidx db restore <name>` to roll back. Checkpoints live next to the DB under
67+
`<db>.checkpoints/<name>/`; restore keeps the pre-restore files under
68+
`<db>.restore-backup-<timestamp>/`. `backfill-fold` creates an automatic
69+
checkpoint before it mutates rows unless `--no-checkpoint` is passed.
70+
71+
Database compatibility across `cdidx` binary upgrades and downgrades is
72+
documented in [COMPATIBILITY.md](COMPATIBILITY.md). Keep that policy updated
73+
whenever readiness bits, `codeindex_meta` contract stamps, or rebuild
74+
requirements change.
75+
6476
`backfill-fold --dry-run` previews the folded-key rows that would be rewritten
6577
without mutating the DB or stamping FoldReady. The MCP `backfill_fold` tool
6678
accepts the same preview as `dry_run: true`, and also accepts `force: true` to

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ After the first command, use these cues and follow-up commands:
7272
| Edits or branch switches | Refresh incrementally with `--files`, `--commits`, or `--changed-between <old-ref> <new-ref>` instead of rebuilding. See [Quick Start](USER_GUIDE.md#quick-start) and [Incremental update reliability](USER_GUIDE.md#incremental-update-reliability). |
7373
| Intentional rebuilds | Interactive terminals ask before deleting the DB. Scripts and CI must pass `--yes` or `--force`. |
7474
| Long-lived DB compaction | Run `cdidx optimize` or `cdidx index <projectPath> --optimize` to compact FTS5 segments immediately. Incremental refreshes also optimize opportunistically. |
75+
| Maintenance rollback | Run `cdidx db checkpoint <name>` before risky DB maintenance and `cdidx db restore <name>` to roll back. `backfill-fold` creates an automatic checkpoint unless `--no-checkpoint` is passed. |
7576
| Permission or I/O scan errors | `cdidx` records the scan error, continues other directories, and writes `.cdidx/scan-checkpoint.json` so same-HEAD retries can skip completed directories. |
7677

7778
Output controls:
@@ -109,6 +110,8 @@ Install choice and network notes:
109110

110111
See [DISTRIBUTION.md](DISTRIBUTION.md) for the full channel matrix and
111112
[isolated network install notes](USER_GUIDE.md#isolated-networks-and-proxies).
113+
For database compatibility across `cdidx` upgrades and downgrades, see
114+
[COMPATIBILITY.md](COMPATIBILITY.md).
112115

113116
### Validate
114117

@@ -331,6 +334,7 @@ extractor fixture を確認できます。詳細は
331334
| 編集後やブランチ切り替え後 | 再構築ではなく `--files``--commits``--changed-between <old-ref> <new-ref>` で差分更新します。詳細は [クイックスタート](USER_GUIDE.md#クイックスタート)[インクリメンタル更新の信頼性](USER_GUIDE.md#インクリメンタル更新の信頼性) を参照してください。 |
332335
| 意図的な再構築 | interactive terminal では既存 DB 削除前に確認を求めます。script / CI では `--yes` または `--force` が必要です。 |
333336
| 長期間使っている DB の compact | `cdidx optimize` または `cdidx index <projectPath> --optimize` で FTS5 segment をすぐに compact できます。差分更新中も必要に応じて自動 optimize します。 |
337+
| 保守作業の rollback | risky な DB 保守の前に `cdidx db checkpoint <name>`、戻す場合は `cdidx db restore <name>` を使います。`backfill-fold``--no-checkpoint` を渡さない限り自動 checkpoint を作成します。 |
334338
| 権限や I/O の scan error | `cdidx` は scan error を記録し、他のディレクトリの走査を続けます。同じ HEAD の再実行では `.cdidx/scan-checkpoint.json` により成功済みディレクトリを読み飛ばせます。 |
335339

336340
出力を整える option:
@@ -345,6 +349,9 @@ extractor fixture を確認できます。詳細は
345349
| UTF-8 JSON pipeline | CLI の `--json` 出力は BOM なし UTF-8 で書き出され、human output 向けに色を強制していても ANSI escape sequence を含みません。 |
346350
| script 向け query pipeline の stderr を静かにする | `--quiet``-q``--silent``CDIDX_QUIET=1` で informational stderr を抑制し、error 行だけを残します。`--quiet``--verbose` より優先されます。 |
347351

352+
`cdidx` の upgrade / downgrade をまたぐ database 互換性については
353+
[COMPATIBILITY.md](COMPATIBILITY.md) を参照してください。
354+
348355
ターミナル、スクリプト、CI、AI ツールから同じリポジトリを繰り返し検索する
349356
場合は `cdidx` が向いています。1回限りのテキスト検索には `rg` が向いています。
350357

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
category: docs
3+
issues:
4+
- 1718
5+
affected:
6+
- COMPATIBILITY.md
7+
- README.md
8+
- DEVELOPER_GUIDE.md
9+
---
10+
11+
## English
12+
13+
- **Documented DB compatibility policy (#1718)** — Added a bilingual compatibility contract for schema readiness bits, `codeindex_meta` stamps, upgrade/downgrade behavior, and rebuild requirements.
14+
15+
## 日本語
16+
17+
- **DB 互換性ポリシーを文書化しました (#1718)** — schema readiness bit、`codeindex_meta` stamp、upgrade / downgrade 時の動作、rebuild が必要な条件を説明する bilingual compatibility contract を追加しました。
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
category: added
3+
issues:
4+
- 1721
5+
affected:
6+
- src/CodeIndex/Cli/DbCommandRunner.cs
7+
- src/CodeIndex/Cli/IndexCommandRunner.Maintenance.cs
8+
- src/CodeIndex/Cli/IndexCommandRunner.cs
9+
- src/CodeIndex/Cli/ConsoleUi.cs
10+
- src/CodeIndex/Cli/CliFlagSchema.cs
11+
- src/CodeIndex/Cli/JsonOutputContracts.cs
12+
- tests/CodeIndex.Tests/DbCommandRunnerTests.cs
13+
- README.md
14+
- DEVELOPER_GUIDE.md
15+
---
16+
17+
## English
18+
19+
- **Added DB checkpoints and restore (#1721)**`cdidx db checkpoint`, `cdidx db checkpoints --list`, and `cdidx db restore` can snapshot and roll back `codeindex.db`, while `backfill-fold` now creates an automatic checkpoint before mutating rows unless `--no-checkpoint` is passed.
20+
21+
## 日本語
22+
23+
- **DB checkpoint / restore を追加しました (#1721)**`cdidx db checkpoint``cdidx db checkpoints --list``cdidx db restore``codeindex.db` を snapshot / rollback でき、`backfill-fold``--no-checkpoint` を渡さない限り row を変更する前に自動 checkpoint を作成します。

src/CodeIndex/Cli/CliFlagSchema.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ private static IReadOnlyList<CliFlag> BuildAll()
274274
new() { Name = "--rebuild", Description = "Delete existing DB and rebuild from scratch", Commands = Set("index") },
275275
new() { Name = "--optimize", Description = "Optimize the existing FTS5 table without scanning files", Commands = Set("index") },
276276
new() { Name = "--dry-run", Description = "Preview without writing", Commands = Set("index", "backfill-fold") },
277+
new() { Name = "--no-checkpoint", Description = "Skip the automatic DB checkpoint before maintenance", Commands = Set("backfill-fold") },
277278
new() { Name = "--force", Description = "Bypass the per-database index lock", Commands = Set("index") },
278279
new() { Name = "--duration-format", ValuePlaceholder = "<auto|seconds|hms>", Description = "Index elapsed time display format", Commands = Set("index") },
279280
new() { Name = "--max-file-bytes", ValuePlaceholder = "<bytes>", Description = "Override the per-file indexing size limit", Commands = Set("index") },

src/CodeIndex/Cli/ConsoleUi.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ private static readonly (string Command, string Usage)[] CommandUsageLines =
7070
[
7171
("index", "cdidx index <projectPath> [--db <path>] [--rebuild] [--optimize] [--verbose] [--dry-run] [--force] [--quiet] [--json] [--memory-trace] [--duration-format <auto|seconds|hms>] [--notify <auto|bell|osc9|desktop|none>] [--max-file-bytes <bytes>] [--follow-symlinks <none|internal|all>] [--include-symbol-kind <kind>[,<kind>]] [--exclude-symbol-kind <kind>[,<kind>]] [--watch [--debounce <ms>]]"),
7272
("hooks", "cdidx hooks <install|uninstall|status> [--project <path>] [--force] [--json]"),
73-
("backfill-fold", "cdidx backfill-fold [--db <path>] [--dry-run] [--json]"),
73+
("backfill-fold", "cdidx backfill-fold [--db <path>] [--dry-run] [--no-checkpoint] [--json]"),
7474
("optimize", "cdidx optimize [--db <path>] [--json]"),
7575
("vacuum", "cdidx vacuum [--db <path>] [--json]"),
7676
("index-commits", "cdidx index <projectPath> --commits <id> [id ...] [--db <path>] [--verbose] [--dry-run] [--json] [--memory-trace] [--duration-format <auto|seconds|hms>] [--max-file-bytes <bytes>] [--include-symbol-kind <kind>[,<kind>]] [--exclude-symbol-kind <kind>[,<kind>]]"),
@@ -93,7 +93,7 @@ private static readonly (string Command, string Usage)[] CommandUsageLines =
9393
("workspace", "cdidx workspace <list|status|use|current> [name] [--json]"),
9494
("config", "cdidx config show [--json]"),
9595
("validate-config", "cdidx validate-config"),
96-
("db", "cdidx db --integrity-check|schema|prune [--dry-run|--apply] [--db <path>] [--json]"),
96+
("db", "cdidx db --integrity-check|schema|prune [--dry-run|--apply] [--db <path>] [--json] | cdidx db checkpoint [name] [--db <path>] [--json] | cdidx db checkpoints --list [--db <path>] [--json] | cdidx db restore <name> [--db <path>] [--json]"),
9797
("diff", "cdidx diff <db1> <db2> [--json] [--summary-only] [--detailed] [--limit <n>]"),
9898
("report", "cdidx report --output <path> [--db <path>] [--json] [--log-lines <n>] [--no-log] [--include-args]"),
9999
("validate", "cdidx validate [--db <path>] [--json] [--format <text|json|count|compact|csv|tsv|lsp|qf|sarif>] [--verbose] [--kind <kind>] [--path <glob>]"),

0 commit comments

Comments
 (0)