Skip to content

Commit f202ff0

Browse files
committed
Merge remote-tracking branch 'origin/main' into fix-issue1679-1786-1789
2 parents eef9dec + 26ac4aa commit f202ff0

24 files changed

Lines changed: 681 additions & 51 deletions

AGENT_GUIDE.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,9 @@ CI watching must be bounded. Do not loop indefinitely.
131131

132132
## Status Contract
133133

134-
- `status --json` and related JSON/MCP payloads currently expose the trust fields documented in `README.md` and `DEVELOPER_GUIDE.md`, including `fold_ready`, `fold_ready_reason`, `graph_table_available`, `issues_table_available`, `sql_graph_contract_ready`, `sql_graph_contract_degraded_reason`, `hotspot_family_ready`, `hotspot_family_degraded_reason`, `csharp_symbol_name_ready`, `csharp_metadata_target_ready`, `csharp_metadata_target_degraded_reason`, `indexed_head_commit`, `worktree_head_changed`, `index_writer_version`, `index_newer_than_reader`, `index_newer_than_reader_reason`, `unknown_extension_file_count`, `path_case_sensitive`, `data_dir`, `data_dir_source`, `data_dir_mode`, `mac_profile`, `db_pragma_settings` (`journal_mode`, `synchronous`, `wal_autocheckpoint`, `page_count`, `freelist_count`, `page_size`), `hooks`, MCP-only `mcp_session`, and the `status --check`-only `stale_after_seconds` / `index_age_seconds` threshold audit fields.
135-
- When `fold_ready` or `csharp_metadata_target_ready` is the only degraded readiness bit, the CLI also adds `degraded_reason`, `recommended_action`, and `alternative_action`.
134+
- `status --json` and related JSON/MCP payloads currently expose the trust fields documented in `README.md` and `DEVELOPER_GUIDE.md`, including `fold_ready`, `fold_ready_reason`, `graph_table_available`, `issues_table_available`, `file_issues_data_current`, `migration_in_progress`, `sql_graph_contract_ready`, `sql_graph_contract_degraded_reason`, `hotspot_family_ready`, `hotspot_family_degraded_reason`, `csharp_symbol_name_ready`, `csharp_metadata_target_ready`, `csharp_metadata_target_degraded_reason`, `indexed_head_commit`, `worktree_head_changed`, `index_writer_version`, `index_newer_than_reader`, `index_newer_than_reader_reason`, `unknown_extension_file_count`, `path_case_sensitive`, `data_dir`, `data_dir_source`, `data_dir_mode`, `mac_profile`, `db_pragma_settings` (`journal_mode`, `synchronous`, `wal_autocheckpoint`, `page_count`, `freelist_count`, `page_size`), `hooks`, MCP-only `mcp_session`, and the `status --check`-only `stale_after_seconds` / `index_age_seconds` threshold audit fields.
135+
- When any readiness field is degraded, the CLI adds `degraded_root_cause`, `degraded_reason`, `recommended_action`, `alternative_action`, and `readiness_degradations[]`. `degraded_root_cause` is the primary stable machine code; `readiness_degradations[]` lists every degraded field with `root_cause`, human reason, and remediation strings.
136+
- `issues_table_available` reports physical `file_issues` table presence only. `file_issues_data_current` reports whether the table is also stamped current for the active index generation.
136137
- `index_writer_version` records the `cdidx` version that last wrote to the DB (stamped into `codeindex_meta` as `cdidx_writer_version` on every full scan, update, and MCP index). `index_newer_than_reader` flips to `true` whenever any persisted numeric contract stamp in `codeindex_meta` (or unknown `PRAGMA user_version` readiness bits) exceeds the current binary's compiled maximum, so an older CLI re-opening a DB written by a newer CLI degrades loudly with an audit trail instead of silently dropping back to text-search fallbacks. `index_newer_than_reader_reason` enumerates the specific newer-than-reader stamps.
137138
- `status` also surfaces indexed-HEAD freshness via `indexed_head_sha`, `indexed_head_branch`, `indexed_head_timestamp`, and `commits_ahead_of_indexed_head`. They are stamped by `cdidx index` on every successful run (full scan AND partial update, distinct from `indexed_head_commit` which is full-scan only) on a best-effort basis (never blocks an otherwise-successful index) and omitted on non-git workspaces, detached HEAD (branch only), or legacy DBs created before this contract.
138139
- `status` also surfaces unknown-extension scan coverage via `unknown_extension_file_count`, stamped by successful full-repository index runs (`cdidx index <projectPath>` and MCP `index_project`) as the number of non-indexed files with non-empty extensions that do not map to a known language. It is omitted on legacy DBs or before a current full scan has stamped the value.

DEVELOPER_GUIDE.md

Lines changed: 28 additions & 2 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ The documented `status --json` trust contract covers these fields:
159159
<table>
160160
<tbody>
161161
<tr><td><code>fold_ready</code></td><td><code>fold_ready_reason</code></td><td><code>graph_table_available</code></td><td><code>issues_table_available</code></td></tr>
162+
<tr><td><code>file_issues_data_current</code></td><td><code>migration_in_progress</code></td><td><code>degraded_root_cause</code></td><td><code>readiness_degradations</code></td></tr>
162163
<tr><td><code>sql_graph_contract_ready</code></td><td><code>sql_graph_contract_degraded_reason</code></td><td><code>hotspot_family_ready</code></td><td><code>hotspot_family_degraded_reason</code></td></tr>
163164
<tr><td><code>csharp_symbol_name_ready</code></td><td><code>csharp_metadata_target_ready</code></td><td><code>csharp_metadata_target_degraded_reason</code></td><td><code>indexed_head_commit</code></td></tr>
164165
<tr><td><code>worktree_head_changed</code></td><td><code>indexed_head_sha</code></td><td><code>indexed_head_branch</code></td><td><code>indexed_head_timestamp</code></td></tr>
@@ -170,6 +171,8 @@ The documented `status --json` trust contract covers these fields:
170171
</tbody>
171172
</table>
172173

174+
When any readiness field is degraded, `degraded_root_cause` identifies the primary stable code and `readiness_degradations[]` lists every degraded field with `root_cause`, human `degraded_reason`, `recommended_action`, and `alternative_action`. `issues_table_available` reports physical table presence; use `file_issues_data_current` to decide whether `file_issues` rows are current for the index generation.
175+
173176
For MCP `status`, `mcp_session` is session-scoped diagnostic data rather than persisted index state. It includes `log_level`, `roots`, optional `client_info`, and optional `client_capabilities`.
174177

175178
`hotspot_family_degraded_reason` uses these values:
@@ -369,6 +372,7 @@ upgrade / downgrade 後はインストール済み補完 script を再生成し
369372
<table>
370373
<tbody>
371374
<tr><td><code>fold_ready</code></td><td><code>fold_ready_reason</code></td><td><code>graph_table_available</code></td><td><code>issues_table_available</code></td></tr>
375+
<tr><td><code>file_issues_data_current</code></td><td><code>migration_in_progress</code></td><td><code>degraded_root_cause</code></td><td><code>readiness_degradations</code></td></tr>
372376
<tr><td><code>sql_graph_contract_ready</code></td><td><code>sql_graph_contract_degraded_reason</code></td><td><code>hotspot_family_ready</code></td><td><code>hotspot_family_degraded_reason</code></td></tr>
373377
<tr><td><code>csharp_symbol_name_ready</code></td><td><code>csharp_metadata_target_ready</code></td><td><code>csharp_metadata_target_degraded_reason</code></td><td><code>indexed_head_commit</code></td></tr>
374378
<tr><td><code>worktree_head_changed</code></td><td><code>indexed_head_sha</code></td><td><code>indexed_head_branch</code></td><td><code>indexed_head_timestamp</code></td></tr>
@@ -380,6 +384,8 @@ upgrade / downgrade 後はインストール済み補完 script を再生成し
380384
</tbody>
381385
</table>
382386

387+
readiness field のいずれかが degraded の場合、`degraded_root_cause` は primary の安定コードを示し、`readiness_degradations[]` は degraded な各 field と `root_cause`、人間向け `degraded_reason``recommended_action``alternative_action` を列挙します。`issues_table_available` は物理 table の有無を表し、`file_issues` 行が現在の index generation に対して current かどうかは `file_issues_data_current` を使って判定します。
388+
383389
MCP `status``mcp_session` は永続化された index 状態ではなく、セッション単位の診断情報です。`log_level``roots`、任意の `client_info`、任意の `client_capabilities` を含みます。
384390

385391
`hotspot_family_degraded_reason` は次の値を使います。
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
category: fixed
3+
issues:
4+
- 1484
5+
- 1486
6+
- 1761
7+
- 1931
8+
affected:
9+
- src/CodeIndex/Cli/QueryCommandRunner.cs
10+
- src/CodeIndex/Database/DbReader.FilesStatus.cs
11+
- src/CodeIndex/Models/QueryResults.cs
12+
---
13+
14+
## English
15+
16+
- **Status readiness degradation now has structured guidance (#1484, #1931)**`status --json` now reports `degraded_root_cause` and `readiness_degradations[]` for every degraded readiness field, including multi-degraded states.
17+
- **Status separates issue-table presence from issue-row freshness (#1486)**`issues_table_available` now reports physical table presence, while `file_issues_data_current` reports whether validate issue rows are current for the index generation.
18+
- **Status identifies active migration/write windows (#1761)**`status --json` now exposes `migration_in_progress` so clients can distinguish temporary writer activity from permanent readiness degradation.
19+
20+
## 日本語
21+
22+
- **status readiness degradation に構造化 guidance を追加しました (#1484, #1931)**`status --json` は multi-degraded 状態を含むすべての degraded readiness field について `degraded_root_cause``readiness_degradations[]` を返すようになりました。
23+
- **status が issue table の存在と issue row の鮮度を分離しました (#1486)**`issues_table_available` は物理 table の存在を表し、`file_issues_data_current` が validate issue row が現在の index generation に対して current かどうかを表します。
24+
- **status が active migration/write window を識別するようになりました (#1761)**`status --json``migration_in_progress` を公開し、クライアントが一時的な writer activity と恒久的な readiness degradation を区別できるようになりました。
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
category: added
3+
issues:
4+
- 1730
5+
affected:
6+
- src/CodeIndex/Cli/QueryCommandRunner.cs
7+
- src/CodeIndex/Database/DbContext.cs
8+
- DEVELOPER_GUIDE.md
9+
---
10+
11+
## English
12+
13+
- **Added read-only database opens for query commands (#1730)** — query commands now accept `--read-only` / `--immutable` and translate normal database paths into SQLite immutable read-only URIs.
14+
15+
## 日本語
16+
17+
- **クエリコマンドで読み取り専用 DB オープンを追加しました (#1730)** — クエリコマンドは `--read-only` / `--immutable` を受け付け、通常の DB パスを SQLite の immutable read-only URI に変換します。
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
category: security
3+
issues:
4+
- 1794
5+
affected:
6+
- src/CodeIndex/Database/DbContext.cs
7+
- src/CodeIndex/Models/QueryResults.cs
8+
- DEVELOPER_GUIDE.md
9+
---
10+
11+
## English
12+
13+
- **Restricted SQLite database file permissions on POSIX (#1794)** — cdidx now applies `0600` to `codeindex.db` and WAL/SHM sidecars and reports `db_file_mode` in `status --json`.
14+
15+
## 日本語
16+
17+
- **POSIX で SQLite DB ファイル権限を制限しました (#1794)** — cdidx は `codeindex.db` と WAL/SHM sidecar に `0600` を適用し、`status --json``db_file_mode` を出します。
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
category: fixed
3+
issues:
4+
- 1798
5+
affected:
6+
- src/CodeIndex/Cli/IndexCommandRunner.cs
7+
- src/CodeIndex/Database/DbContext.cs
8+
- src/CodeIndex/Database/DbReader.FilesStatus.cs
9+
- src/CodeIndex/Models/QueryResults.cs
10+
---
11+
12+
## English
13+
14+
- **Checkpoint WAL before read-only fallback (#1798)** — writable-open fallback now attempts `wal_checkpoint(TRUNCATE)` first and exposes fallback/checkpoint diagnostics in `status --json`.
15+
16+
## 日本語
17+
18+
- **読み取り専用フォールバック前に WAL checkpoint を試みるようにしました (#1798)** — writable open のフォールバック前に `wal_checkpoint(TRUNCATE)` を試行し、fallback / checkpoint 診断を `status --json` に出します。

src/CodeIndex/Cli/CliFlagSchema.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,13 @@ internal static class CliFlagSchema
164164
"validate", "deps", "impact", "unused", "hotspots", "batch",
165165
];
166166

167+
private static readonly string[] ReadOnlyDbCommands =
168+
[
169+
"search", "definition", "goto", "references", "callers", "callees",
170+
"symbols", "files", "find", "excerpt", "map", "inspect", "outline", "status",
171+
"validate", "deps", "impact", "unused", "hotspots",
172+
];
173+
167174
private static readonly string[] JsonCommands =
168175
[
169176
"index", "backfill-fold", "optimize", "vacuum", "search", "definition", "goto", "references", "callers", "callees",
@@ -193,6 +200,8 @@ private static IReadOnlyList<CliFlag> BuildAll()
193200
return new List<CliFlag>
194201
{
195202
new() { Name = "--db", ValuePlaceholder = "<path>", Description = "Database path", Commands = Set(DbPathCommands) },
203+
new() { Name = "--read-only", Description = "Open the query database as immutable read-only storage", Commands = Set(ReadOnlyDbCommands) },
204+
new() { Name = "--immutable", Description = "Alias for --read-only", Commands = Set(ReadOnlyDbCommands) },
196205
new() { Name = "--workspace-db", ValuePlaceholder = "<path>", Description = "Additional workspace member database path for dependency aggregation", Commands = Set(WorkspaceDbCommands) },
197206
new() { Name = "--data-dir", ValuePlaceholder = "<dir>", Description = "Directory containing codeindex.db; overrides CDIDX_DATA_DIR/XDG/workspace defaults", Commands = Set(DataDirCommands) },
198207
new() { Name = "--json", Description = "JSON output; search also accepts --json=array for a single JSON array", Commands = Set(JsonCommands) },

src/CodeIndex/Cli/IndexCommandRunner.Parse.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public static partial class IndexCommandRunner
1717
"--parallelism",
1818
"--commits", "--changed-between", "--files", "--solution", "--project",
1919
"--include-symbol-kind", "--exclude-symbol-kind", "--optimize", "--help",
20+
"--read-only", "--immutable",
2021
];
2122

2223
internal const string IndexParallelismEnvironmentVariable = "CDIDX_INDEX_PARALLELISM";
@@ -32,6 +33,7 @@ public static IndexCommandOptions ParseArgs(string[] args)
3233
bool quiet = false;
3334
bool dryRun = false;
3435
bool force = false;
36+
bool readOnly = false;
3537
bool yes = false;
3638
bool watch = false;
3739
bool optimizeOnly = false;
@@ -98,6 +100,11 @@ public static IndexCommandOptions ParseArgs(string[] args)
98100
case "--force":
99101
force = true;
100102
break;
103+
case "--read-only":
104+
case "--immutable":
105+
readOnly = true;
106+
parseError ??= $"{args[i]} is only supported by query commands; index mutates the database and cannot run read-only";
107+
break;
101108
case "--yes":
102109
yes = true;
103110
break;
@@ -274,6 +281,7 @@ public static IndexCommandOptions ParseArgs(string[] args)
274281
EasterEgg = easterEgg,
275282
DryRun = dryRun,
276283
Force = force,
284+
ReadOnly = readOnly,
277285
Yes = yes,
278286
Watch = watch,
279287
OptimizeOnly = optimizeOnly,

src/CodeIndex/Cli/IndexCommandRunner.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,16 @@ internal static int Run(string[] indexArgs, JsonSerializerOptions jsonOptions, C
178178
using (indexLock)
179179
{
180180
using var db = new DbContext(dbPath);
181+
if (db.ReadOnlyFallback)
182+
{
183+
return WriteCommandError(
184+
options.Json,
185+
jsonOptions,
186+
$"database opened through stale read-only fallback after WAL checkpoint failed: {resolvedDbPath}; index requires a writable database",
187+
CommandExitCodes.DatabaseError,
188+
"Move the database to writable storage, stop the writer holding the WAL lock, or rerun the query command with --read-only if you only need read access.",
189+
CommandErrorCodes.DbNotWritable);
190+
}
181191

182192
// Capture prior readiness BEFORE we clear it. Update mode (--commits / --files) only
183193
// touches a subset of files, so trust bits the DB did NOT previously carry must not
@@ -1154,6 +1164,7 @@ public sealed class IndexCommandOptions
11541164
public string? EasterEgg { get; init; }
11551165
public bool DryRun { get; init; }
11561166
public bool Force { get; init; }
1167+
public bool ReadOnly { get; init; }
11571168
public bool Yes { get; init; }
11581169
public bool Watch { get; init; }
11591170
public bool OptimizeOnly { get; init; }

0 commit comments

Comments
 (0)