From 93b62896a47d64d84aa9decbc8e1c70d514b9f11 Mon Sep 17 00:00:00 2001 From: Widthdom Date: Mon, 13 Apr 2026 19:38:11 +0900 Subject: [PATCH 1/8] Close absolute-path cdidx loophole and unblock cloud sessions Add Bash(~/.local/bin/cdidx:*) to the tracked deny list so agents cannot bypass the cdidx:* deny via the install.sh absolute path on Linux / macOS. Because Claude Code treats deny as absolute, add a Step 1.5 to CLOUD_BOOTSTRAP_PROMPT.md telling SDK-less cloud sessions to strip the two cdidx deny entries from the workspace copy of .claude/settings.json (session-local, uncommitted) so the installed binary remains usable. Sync CLAUDE.md and the existing Unreleased CHANGELOG entry in both English and Japanese. Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/settings.json | 3 ++- CHANGELOG.md | 4 ++-- CLAUDE.md | 4 ++-- CLOUD_BOOTSTRAP_PROMPT.md | 23 +++++++++++++++++++++++ 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/.claude/settings.json b/.claude/settings.json index 26268337c9..d71b42dc84 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -16,7 +16,8 @@ "Bash(locate:*)", "Bash(mlocate:*)", "Bash(mdfind:*)", - "Bash(cdidx:*)" + "Bash(cdidx:*)", + "Bash(~/.local/bin/cdidx:*)" ] } } diff --git a/CHANGELOG.md b/CHANGELOG.md index bdef51e24a..5e24e007a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ### [Unreleased] #### Added -- **Tracked `.claude/settings.json` enforces cdidx-first code search for Claude Code agents** — Ship a repo-tracked Claude Code permissions file that denies the full set of code-search / file-discovery shell commands AI agents typically reach for: `Bash(rg:*)`, `Bash(grep:*)`, `Bash(egrep:*)`, `Bash(fgrep:*)`, `Bash(zgrep:*)`, `Bash(rgrep:*)`, `Bash(ripgrep:*)`, `Bash(ag:*)`, `Bash(ack:*)`, `Bash(ack-grep:*)`, `Bash(git grep:*)`, `Bash(find:*)`, `Bash(locate:*)`, `Bash(mlocate:*)`, `Bash(mdfind:*)`, and `Bash(cdidx:*)`. SELF_IMPROVEMENT.md already told contributors to use the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` instead of ripgrep / grep / the globally installed `cdidx`, but nothing enforced it at the harness level — agents could still silently fall back to whichever search tool happened to be installed, or to a stale global `cdidx` whose DB schema and extraction rules lag this branch. The new settings file turns that guidance into a hard gate so agents are forced to use the Grep / Glob built-ins or the freshly built local binary. Contributors who intentionally want shell-level access to any of these commands can allow-list them in their own untracked `.claude/settings.local.json`. Affected: `.claude/settings.json`. +- **Tracked `.claude/settings.json` enforces cdidx-first code search for Claude Code agents** — Ship a repo-tracked Claude Code permissions file that denies the full set of code-search / file-discovery shell commands AI agents typically reach for: `Bash(rg:*)`, `Bash(grep:*)`, `Bash(egrep:*)`, `Bash(fgrep:*)`, `Bash(zgrep:*)`, `Bash(rgrep:*)`, `Bash(ripgrep:*)`, `Bash(ag:*)`, `Bash(ack:*)`, `Bash(ack-grep:*)`, `Bash(git grep:*)`, `Bash(find:*)`, `Bash(locate:*)`, `Bash(mlocate:*)`, `Bash(mdfind:*)`, and `Bash(cdidx:*)`. SELF_IMPROVEMENT.md already told contributors to use the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` instead of ripgrep / grep / the globally installed `cdidx`, but nothing enforced it at the harness level — agents could still silently fall back to whichever search tool happened to be installed, or to a stale global `cdidx` whose DB schema and extraction rules lag this branch. The new settings file turns that guidance into a hard gate so agents are forced to use the Grep / Glob built-ins or the freshly built local binary. Contributors who intentionally want shell-level access to any of these commands can allow-list them in their own untracked `.claude/settings.local.json`. The deny list also includes `Bash(~/.local/bin/cdidx:*)` to close the absolute-path loophole used by `install.sh` on Linux / macOS. Because Claude Code treats `deny` as absolute (`settings.local.json` allows cannot override it), `CLOUD_BOOTSTRAP_PROMPT.md` gains a Step 1.5 instructing cloud sessions to strip the two `cdidx` deny entries from the workspace copy of `.claude/settings.json` (session-local, uncommitted) so the installed binary remains usable in SDK-less containers. Affected: `.claude/settings.json`, `CLOUD_BOOTSTRAP_PROMPT.md`, `CLAUDE.md`. - **`--exact` extended to `definition` / `references` / `callers` / `callees` / `inspect` (#83)** — The case-insensitive exact-match semantic introduced in #81 now also applies to `cdidx definition`, `cdidx references`, `cdidx callers`, `cdidx callees`, `cdidx inspect`, and their MCP tool counterparts (`analyze_symbol` included) via an `exact` boolean. `inspect` / `analyze_symbol` propagates `exact` into every bundled sub-query (definitions, references, callers, callees) so the one-round-trip AI workflow keeps the same precision contract as the leaf commands — `inspect Run --exact` no longer pulls `RunAsync` / `RunImpact` into the bundled response. Predicates use `s.name = @q COLLATE NOCASE` / `r.symbol_name = @q COLLATE NOCASE` / `r.container_name = @q COLLATE NOCASE`, backed by new `idx_symbol_refs_name_nocase` and `idx_symbol_refs_container_nocase` covering indexes on `symbol_references` so multi-exact lookups stay SARGable. Closes the round-trip gap where an AI client had `symbols --exact` for name resolution but still had to fall back to substring matching for the follow-up definition / reference / call graph calls. ASCII-only NOCASE limitation from #81 still applies (non-ASCII casing is not folded; Unicode folding tracked in #86). Affected: `src/CodeIndex/Database/DbReader.cs`, `src/CodeIndex/Database/DbSymbolReader.cs`, `src/CodeIndex/Database/DbContext.cs`, `src/CodeIndex/Cli/QueryCommandRunner.cs`, `src/CodeIndex/Cli/ConsoleUi.cs`, `src/CodeIndex/Mcp/McpToolDefinitions.cs`, `src/CodeIndex/Mcp/McpToolHandlers.cs`, `tests/CodeIndex.Tests/DbReaderTests.cs`, `README.md`, `CLAUDE.md`. Closes #83. - **`--exact` on `symbols` for precise name resolution (#81)** — `cdidx symbols` and MCP `symbols` now accept `--exact` / `exact: true` to match symbol names by case-insensitive equality instead of `LIKE %...%` substring. When AI clients pass a resolved candidate list from an earlier `map` / `inspect` / `search` call, querying `Run` no longer also returns `RunAsync`, `RunImpact`, etc., saving a client-side filter pass and reducing token output. Composes with repeated `--name` / positional names (OR-joined per-name equality), and with all existing filters (`--kind`, `--lang`, `--path`, `--exclude-path`, `--exclude-tests`, `--since`, `--limit`). Default behavior (substring) is unchanged. The exact-match predicate uses `s.name = @q COLLATE NOCASE` (not `lower(col) = lower(@q)`) backed by a new `idx_symbols_name_nocase` covering index so multi-name exact lookups stay O(log n) per name instead of a full-table scan. Case-insensitivity follows SQLite's `NOCASE` collation (ASCII only) — non-ASCII casing pairs such as `Ä` / `ä` are not folded; pass the exact casing for non-ASCII identifiers. Unicode folding is tracked in #86. Affected: `src/CodeIndex/Database/DbSymbolReader.cs`, `src/CodeIndex/Database/DbContext.cs`, `src/CodeIndex/Cli/QueryCommandRunner.cs`, `src/CodeIndex/Cli/ConsoleUi.cs`, `src/CodeIndex/Mcp/McpToolDefinitions.cs`, `src/CodeIndex/Mcp/McpToolHandlers.cs`, `tests/CodeIndex.Tests/DbReaderTests.cs`, `README.md`. Closes #81. - **Multi-name `symbols` query (#69)** — `symbols` now accepts multiple names in a single call so AI clients can resolve a candidate list without issuing one command per name. Supported forms: repeatable positional (`cdidx symbols A B C`) and repeatable `--name` flag (`--name A --name B`). Names are OR-joined server-side with per-name candidate fetch + round-robin merge under the user's `--limit` cap (so a popular name cannot starve others, and `--limit` still bounds total results). `|` is treated as a literal name character so operator symbols such as `operator |` remain searchable. All existing filters (`--kind`, `--lang`, `--path`, `--exclude-tests`, `--since`) still apply, and MCP `symbols` gains a parallel `names` array. Fully additive — single-name calls behave identically. Affected: `src/CodeIndex/Cli/QueryCommandRunner.cs`, `src/CodeIndex/Database/DbSymbolReader.cs`, `src/CodeIndex/Mcp/McpToolHandlers.cs`, `src/CodeIndex/Mcp/McpToolDefinitions.cs`, `tests/CodeIndex.Tests/DbReaderTests.cs`, `README.md`. Closes #69. @@ -601,7 +601,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ### [Unreleased] #### 追加 -- **リポジトリ追跡の `.claude/settings.json` で cdidx 最優先のコード検索を強制** — AI エージェントが代用しがちなコード検索/ファイル探索系のシェルコマンドを網羅的に deny するリポジトリ追跡版 Claude Code 権限ファイルを追加(`Bash(rg:*)`、`Bash(grep:*)`、`Bash(egrep:*)`、`Bash(fgrep:*)`、`Bash(zgrep:*)`、`Bash(rgrep:*)`、`Bash(ripgrep:*)`、`Bash(ag:*)`、`Bash(ack:*)`、`Bash(ack-grep:*)`、`Bash(git grep:*)`、`Bash(find:*)`、`Bash(locate:*)`、`Bash(mlocate:*)`、`Bash(mdfind:*)`、`Bash(cdidx:*)`)。SELF_IMPROVEMENT.md では「ripgrep / grep / グローバル `cdidx` ではなく、ローカルビルドした `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を使う」ルールを既に定義していたが、harness レベルで強制する仕組みが無く、エージェントが黙ってインストール済みの検索ツールや、ブランチ差分を反映しない古い DB スキーマ・抽出ルールのグローバル `cdidx` にフォールバックできてしまっていた。この設定ファイルで、そのガイドラインをハード gate に昇格し、Grep / Glob 組み込みツールか新しくビルドしたローカルバイナリの使用を強制する。shell レベルでこれらのコマンドを使いたい貢献者は、個人ごとの追跡外 `.claude/settings.local.json` で allow-list すれば引き続き使える。対象: `.claude/settings.json`。 +- **リポジトリ追跡の `.claude/settings.json` で cdidx 最優先のコード検索を強制** — AI エージェントが代用しがちなコード検索/ファイル探索系のシェルコマンドを網羅的に deny するリポジトリ追跡版 Claude Code 権限ファイルを追加(`Bash(rg:*)`、`Bash(grep:*)`、`Bash(egrep:*)`、`Bash(fgrep:*)`、`Bash(zgrep:*)`、`Bash(rgrep:*)`、`Bash(ripgrep:*)`、`Bash(ag:*)`、`Bash(ack:*)`、`Bash(ack-grep:*)`、`Bash(git grep:*)`、`Bash(find:*)`、`Bash(locate:*)`、`Bash(mlocate:*)`、`Bash(mdfind:*)`、`Bash(cdidx:*)`)。SELF_IMPROVEMENT.md では「ripgrep / grep / グローバル `cdidx` ではなく、ローカルビルドした `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を使う」ルールを既に定義していたが、harness レベルで強制する仕組みが無く、エージェントが黙ってインストール済みの検索ツールや、ブランチ差分を反映しない古い DB スキーマ・抽出ルールのグローバル `cdidx` にフォールバックできてしまっていた。この設定ファイルで、そのガイドラインをハード gate に昇格し、Grep / Glob 組み込みツールか新しくビルドしたローカルバイナリの使用を強制する。shell レベルでこれらのコマンドを使いたい貢献者は、個人ごとの追跡外 `.claude/settings.local.json` で allow-list すれば引き続き使える。deny リストには Linux / macOS の `install.sh` が配置する絶対パス経由の逃げ道を塞ぐ `Bash(~/.local/bin/cdidx:*)` も含む。Claude Code は `deny` を絶対視し `settings.local.json` の allow では上書きできないため、`CLOUD_BOOTSTRAP_PROMPT.md` に Step 1.5 を追加し、Cloud セッションではワークスペース上の `.claude/settings.json` から `cdidx` 系 deny 2 行をセッション限定で削除(コミットしない)する運用を明記した。SDK のないコンテナでもインストール済みバイナリを使える状態を保つため。対象: `.claude/settings.json`、`CLOUD_BOOTSTRAP_PROMPT.md`、`CLAUDE.md`。 - **`--exact` を `definition` / `references` / `callers` / `callees` / `inspect` にも拡張 (#83)** — #81 で symbols に入れた大文字小文字無視の完全一致セマンティクスを、`cdidx definition`、`cdidx references`、`cdidx callers`、`cdidx callees`、`cdidx inspect` と対応する MCP ツール(`analyze_symbol` を含む)にも `exact` boolean として展開。`inspect` / `analyze_symbol` は bundle 内の全 sub-query(定義、参照、caller、callee)に `exact` を伝播するため、一発解決の AI ワークフローも leaf コマンドと同じ precision contract を維持する — `inspect Run --exact` が `RunAsync` / `RunImpact` を含んだ bundle を返すことは無い。述語は `s.name = @q COLLATE NOCASE` / `r.symbol_name = @q COLLATE NOCASE` / `r.container_name = @q COLLATE NOCASE` を使い、新規の `idx_symbol_refs_name_nocase` / `idx_symbol_refs_container_nocase` covering index を貼ることで multi-exact 検索も SARGable に保つ。AI クライアントが `symbols --exact` で名前を解決した後、definition / reference / call graph の追撃で substring に戻らざるを得なかった往復ロスを解消する。#81 の ASCII NOCASE 限定は引き続き適用される(非 ASCII の casing は畳み込まれず、Unicode fold は #86 で追跡)。対象: `src/CodeIndex/Database/DbReader.cs`、`src/CodeIndex/Database/DbSymbolReader.cs`、`src/CodeIndex/Database/DbContext.cs`、`src/CodeIndex/Cli/QueryCommandRunner.cs`、`src/CodeIndex/Cli/ConsoleUi.cs`、`src/CodeIndex/Mcp/McpToolDefinitions.cs`、`src/CodeIndex/Mcp/McpToolHandlers.cs`、`tests/CodeIndex.Tests/DbReaderTests.cs`、`README.md`、`CLAUDE.md`。Closes #83. - **`symbols` に `--exact` を追加し名前の正確な解決を可能に (#81)** — `cdidx symbols` と MCP の `symbols` が `--exact` / `exact: true` を受け付け、`LIKE %...%` の部分一致ではなく大文字小文字を無視した名前の完全一致で検索するようになった。AI クライアントが先行の `map` / `inspect` / `search` 結果から解決済みの候補リストを渡す場合、`Run` を指定しても `RunAsync` / `RunImpact` 等に広がらないため、クライアント側での後段フィルタが不要になりトークン出力も減る。繰り返しの `--name` や positional 名と組み合わせれば名前ごとの完全一致を OR 結合でき、既存フィルタ(`--kind`、`--lang`、`--path`、`--exclude-path`、`--exclude-tests`、`--since`、`--limit`)もそのまま適用される。既定挙動(部分一致)は変わらない。完全一致述語は `lower(col) = lower(@q)` ではなく `s.name = @q COLLATE NOCASE` を使い、新規の `idx_symbols_name_nocase` covering index を貼ることで multi-name exact 時にもフルスキャンにならず O(log n) × 名前数で解決する。大文字小文字無視は SQLite の `NOCASE`(ASCII 限定)に従うため、`Ä` / `ä` のような非 ASCII の casing 差分は畳み込まれない — 非 ASCII 識別子はインデックス時と同じ casing を渡すこと。Unicode fold の対応は #86 で追跡。対象: `src/CodeIndex/Database/DbSymbolReader.cs`、`src/CodeIndex/Database/DbContext.cs`、`src/CodeIndex/Cli/QueryCommandRunner.cs`、`src/CodeIndex/Cli/ConsoleUi.cs`、`src/CodeIndex/Mcp/McpToolDefinitions.cs`、`src/CodeIndex/Mcp/McpToolHandlers.cs`、`tests/CodeIndex.Tests/DbReaderTests.cs`、`README.md`。Closes #81. - **`symbols` の複数名クエリ (#69)** — `symbols` が 1 回の呼び出しで複数のシンボル名を解決できるようになり、AI クライアントが候補リストをコマンドごとに分けて問い合わせる必要がなくなった。対応形式: 繰り返しの positional(`cdidx symbols A B C`)、繰り返しの `--name` フラグ(`--name A --name B`)。名前はサーバー側で OR 結合され、名前ごとの候補取得 + round-robin マージを `--limit` の範囲内で行うため、人気名が他を押し出すことなく `--limit` は従来どおり合計の上限として働く。`|` はシンボル名の文字として扱うので `operator |` のような演算子シンボルも検索可能。既存フィルタ(`--kind`、`--lang`、`--path`、`--exclude-tests`、`--since`)はそのまま適用される。MCP の `symbols` にも `names` 配列を追加。単一名呼び出しは従来どおり動作する完全な追加変更。対象: `src/CodeIndex/Cli/QueryCommandRunner.cs`、`src/CodeIndex/Database/DbSymbolReader.cs`、`src/CodeIndex/Mcp/McpToolHandlers.cs`、`src/CodeIndex/Mcp/McpToolDefinitions.cs`、`tests/CodeIndex.Tests/DbReaderTests.cs`、`README.md`。Closes #69. diff --git a/CLAUDE.md b/CLAUDE.md index 8d0ff661e7..e7589274b7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -175,7 +175,7 @@ The only production dependency is **Microsoft.Data.Sqlite** — keep it that way Code review uses the **locally built binary** from the current commit (`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`) to search and verify the codebase. This means the reviewer sees exactly what the code actually does — not what tests claim it does, not what documentation says it does, but what the running binary produces. **It is strictly forbidden to intentionally implement incomplete, hollow, or deceptive code that passes tests or review on paper but fails in practice.** Every feature must work correctly when exercised by the binary itself. Cutting corners to "pass review" defeats the purpose of the self-improvement loop and will be caught by dogfooding. ### Code search tools (Claude Code / AI harnesses) -Repo-tracked `.claude/settings.json` denies the full set of shell code-search and file-discovery commands (`rg`, `grep`, `egrep`, `fgrep`, `zgrep`, `rgrep`, `ripgrep`, `ag`, `ack`, `ack-grep`, `git grep`, `find`, `locate`, `mlocate`, `mdfind`, `cdidx`) so Claude Code agents cannot silently fall back to any of them. Use the built-in Grep / Glob tools and the **locally built binary** (`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`) for searches — the global `cdidx` may have an older DB schema, missing query features, or stale extraction logic that silently returns wrong results. Contributors who want shell-level access to any of these commands can allow-list them in their own untracked `.claude/settings.local.json`. +Repo-tracked `.claude/settings.json` denies the full set of shell code-search and file-discovery commands (`rg`, `grep`, `egrep`, `fgrep`, `zgrep`, `rgrep`, `ripgrep`, `ag`, `ack`, `ack-grep`, `git grep`, `find`, `locate`, `mlocate`, `mdfind`, `cdidx`, `~/.local/bin/cdidx`) so Claude Code agents cannot silently fall back to any of them. The `~/.local/bin/cdidx` entry closes the absolute-path loophole used by `install.sh` on Linux / macOS. Cloud Claude Code sessions rely on that installed binary, so `CLOUD_BOOTSTRAP_PROMPT.md` instructs those sessions to strip the two `cdidx` deny entries from the workspace copy of `.claude/settings.json` (session-local, uncommitted). Use the built-in Grep / Glob tools and the **locally built binary** (`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`) for searches — the global `cdidx` may have an older DB schema, missing query features, or stale extraction logic that silently returns wrong results. Contributors who want shell-level access to any of these commands can allow-list them in their own untracked `.claude/settings.local.json`. ### Method signature changes When changing a method's return type or parameters (e.g. `BuildRecord` from `(FileRecord, string)` to `(FileRecord, string, string?)`), **update ALL callers** in the same commit: @@ -417,7 +417,7 @@ tests/CodeIndex.Tests/ コードレビューは現在のコミットから**ローカルビルドしたバイナリ**(`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`)を使ってコードベースを検索・検証します。つまりレビュアーは、テストが主張する動作でもドキュメントが述べる動作でもなく、実行中のバイナリが実際に出す結果を見ます。**テストやレビューを表面上パスするが実際には動作しない、不完全・中身のない・欺瞞的なコードを意図的に実装することは厳禁です。** すべての機能はバイナリ自身で実行したときに正しく動作しなければなりません。「レビューを通す」ための手抜きは自己改善ループの目的を損ない、ドッグフーディングで必ず発覚します。 ### コード検索ツール(Claude Code / AI ハーネス) -リポジトリ追跡の `.claude/settings.json` で、shell のコード検索・ファイル探索系コマンドを網羅的に deny しています(`rg`、`grep`、`egrep`、`fgrep`、`zgrep`、`rgrep`、`ripgrep`、`ag`、`ack`、`ack-grep`、`git grep`、`find`、`locate`、`mlocate`、`mdfind`、`cdidx`)。これにより Claude Code エージェントは、これらのいずれにも黙ってフォールバックできません。検索には組み込みの Grep / Glob ツール、または**ローカルビルドしたバイナリ**(`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`)を使ってください — グローバル版 `cdidx` は DB スキーマが古い、クエリ機能が欠けている、抽出ロジックが古くて誤った結果を返す恐れがあります。shell レベルで使いたい貢献者は、自分の追跡外 `.claude/settings.local.json` で allow-list してください。 +リポジトリ追跡の `.claude/settings.json` で、shell のコード検索・ファイル探索系コマンドを網羅的に deny しています(`rg`、`grep`、`egrep`、`fgrep`、`zgrep`、`rgrep`、`ripgrep`、`ag`、`ack`、`ack-grep`、`git grep`、`find`、`locate`、`mlocate`、`mdfind`、`cdidx`、`~/.local/bin/cdidx`)。これにより Claude Code エージェントは、これらのいずれにも黙ってフォールバックできません。`~/.local/bin/cdidx` は Linux / macOS の `install.sh` が配置する絶対パスからの逃げ道を塞ぐためのエントリです。Cloud の Claude Code セッションはそのインストール済みバイナリに依存するため、`CLOUD_BOOTSTRAP_PROMPT.md` では該当セッションに対してワークスペース上の `.claude/settings.json` から `cdidx` 系 deny 2 行をセッション限定で削除(コミットしない)するよう案内しています。検索には組み込みの Grep / Glob ツール、または**ローカルビルドしたバイナリ**(`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`)を使ってください — グローバル版 `cdidx` は DB スキーマが古い、クエリ機能が欠けている、抽出ロジックが古くて誤った結果を返す恐れがあります。shell レベルで使いたい貢献者は、自分の追跡外 `.claude/settings.local.json` で allow-list してください。 ### メソッドシグネチャの変更 メソッドの戻り値やパラメータを変更した場合(例: `BuildRecord`を`(FileRecord, string)`から`(FileRecord, string, string?)`に変更)、**同じコミットで全ての呼び出し元を更新すること**: diff --git a/CLOUD_BOOTSTRAP_PROMPT.md b/CLOUD_BOOTSTRAP_PROMPT.md index c6500704df..9b9f59b85a 100644 --- a/CLOUD_BOOTSTRAP_PROMPT.md +++ b/CLOUD_BOOTSTRAP_PROMPT.md @@ -34,6 +34,17 @@ copies the binary **plus the adjacent runtime assets** (`version.json` and library is loaded via P/Invoke from the binary's directory, and `version.json` is what `cdidx --version` reads. +### Step 1.5 — Unblock `cdidx` in this session's permissions + +The repo-tracked `.claude/settings.json` denies `Bash(cdidx:*)` and +`Bash(~/.local/bin/cdidx:*)` to keep local sessions from silently falling +back to a stale global binary. In this container those denies would block +every smoke-test command below. Claude Code treats `deny` as absolute — +`settings.local.json` allows cannot override it — so the only workable +escape is to remove those two entries from the **workspace copy** of +`.claude/settings.json` and **do not commit the change**. It is a +session-local unblock, not a repo edit. + ### Step 2 — Smoke test the installed binary end-to-end Run every command below. If any of them fails on a clean install, that @@ -140,6 +151,18 @@ export PATH="$HOME/.local/bin:$PATH" ライブラリはバイナリのディレクトリから P/Invoke でロードされ、 `version.json` は `cdidx --version` が読むファイルです。 +### Step 1.5 — このセッションの permissions で `cdidx` を通す + +リポジトリ追跡の `.claude/settings.json` は、ローカルセッションが古い +グローバルバイナリに黙ってフォールバックしないよう +`Bash(cdidx:*)` と `Bash(~/.local/bin/cdidx:*)` を deny しています。 +このコンテナではその deny が以降のスモークテストを全部ブロックします。 +Claude Code の `deny` は絶対で `settings.local.json` の allow では +上書きできないため、唯一の現実的な回避策は**ワークスペース上の** +`.claude/settings.json` からその2エントリを削除し、**その変更を +コミットしない**ことです。リポジトリへの修正ではなくセッション限定の +一時解除として扱ってください。 + ### Step 2 — インストール済みバイナリをエンドツーエンドでスモーク 以下を全部実行してください。クリーンインストール直後にどれか1つでも From ef72a6678b2953dd9441ae2b57d37bd3faab1d6a Mon Sep 17 00:00:00 2001 From: Widthdom Date: Mon, 13 Apr 2026 19:45:41 +0900 Subject: [PATCH 2/8] Resolve contradiction on deny override path CLAUDE.md and the CHANGELOG entry previously said contributors could allow-list a denied command in .claude/settings.local.json, but the Cloud Bootstrap workaround added in the prior commit states that Claude Code treats deny as absolute and settings.local.json cannot override it. Align all three docs on the single truthful recovery path: edit the workspace copy of .claude/settings.json for the session only and do not commit the change. Co-Authored-By: Claude Opus 4.6 (1M context) --- CHANGELOG.md | 4 ++-- CLAUDE.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e24e007a0..e4c475667f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ### [Unreleased] #### Added -- **Tracked `.claude/settings.json` enforces cdidx-first code search for Claude Code agents** — Ship a repo-tracked Claude Code permissions file that denies the full set of code-search / file-discovery shell commands AI agents typically reach for: `Bash(rg:*)`, `Bash(grep:*)`, `Bash(egrep:*)`, `Bash(fgrep:*)`, `Bash(zgrep:*)`, `Bash(rgrep:*)`, `Bash(ripgrep:*)`, `Bash(ag:*)`, `Bash(ack:*)`, `Bash(ack-grep:*)`, `Bash(git grep:*)`, `Bash(find:*)`, `Bash(locate:*)`, `Bash(mlocate:*)`, `Bash(mdfind:*)`, and `Bash(cdidx:*)`. SELF_IMPROVEMENT.md already told contributors to use the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` instead of ripgrep / grep / the globally installed `cdidx`, but nothing enforced it at the harness level — agents could still silently fall back to whichever search tool happened to be installed, or to a stale global `cdidx` whose DB schema and extraction rules lag this branch. The new settings file turns that guidance into a hard gate so agents are forced to use the Grep / Glob built-ins or the freshly built local binary. Contributors who intentionally want shell-level access to any of these commands can allow-list them in their own untracked `.claude/settings.local.json`. The deny list also includes `Bash(~/.local/bin/cdidx:*)` to close the absolute-path loophole used by `install.sh` on Linux / macOS. Because Claude Code treats `deny` as absolute (`settings.local.json` allows cannot override it), `CLOUD_BOOTSTRAP_PROMPT.md` gains a Step 1.5 instructing cloud sessions to strip the two `cdidx` deny entries from the workspace copy of `.claude/settings.json` (session-local, uncommitted) so the installed binary remains usable in SDK-less containers. Affected: `.claude/settings.json`, `CLOUD_BOOTSTRAP_PROMPT.md`, `CLAUDE.md`. +- **Tracked `.claude/settings.json` enforces cdidx-first code search for Claude Code agents** — Ship a repo-tracked Claude Code permissions file that denies the full set of code-search / file-discovery shell commands AI agents typically reach for: `Bash(rg:*)`, `Bash(grep:*)`, `Bash(egrep:*)`, `Bash(fgrep:*)`, `Bash(zgrep:*)`, `Bash(rgrep:*)`, `Bash(ripgrep:*)`, `Bash(ag:*)`, `Bash(ack:*)`, `Bash(ack-grep:*)`, `Bash(git grep:*)`, `Bash(find:*)`, `Bash(locate:*)`, `Bash(mlocate:*)`, `Bash(mdfind:*)`, and `Bash(cdidx:*)`. SELF_IMPROVEMENT.md already told contributors to use the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` instead of ripgrep / grep / the globally installed `cdidx`, but nothing enforced it at the harness level — agents could still silently fall back to whichever search tool happened to be installed, or to a stale global `cdidx` whose DB schema and extraction rules lag this branch. The new settings file turns that guidance into a hard gate so agents are forced to use the Grep / Glob built-ins or the freshly built local binary. Claude Code treats tracked `deny` as absolute — `.claude/settings.local.json` allows cannot override it — so contributors who intentionally need shell-level access must edit the workspace copy of `.claude/settings.json` for that session only and not commit the change. The deny list also includes `Bash(~/.local/bin/cdidx:*)` to close the absolute-path loophole used by `install.sh` on Linux / macOS. Because Claude Code treats `deny` as absolute (`settings.local.json` allows cannot override it), `CLOUD_BOOTSTRAP_PROMPT.md` gains a Step 1.5 instructing cloud sessions to strip the two `cdidx` deny entries from the workspace copy of `.claude/settings.json` (session-local, uncommitted) so the installed binary remains usable in SDK-less containers. Affected: `.claude/settings.json`, `CLOUD_BOOTSTRAP_PROMPT.md`, `CLAUDE.md`. - **`--exact` extended to `definition` / `references` / `callers` / `callees` / `inspect` (#83)** — The case-insensitive exact-match semantic introduced in #81 now also applies to `cdidx definition`, `cdidx references`, `cdidx callers`, `cdidx callees`, `cdidx inspect`, and their MCP tool counterparts (`analyze_symbol` included) via an `exact` boolean. `inspect` / `analyze_symbol` propagates `exact` into every bundled sub-query (definitions, references, callers, callees) so the one-round-trip AI workflow keeps the same precision contract as the leaf commands — `inspect Run --exact` no longer pulls `RunAsync` / `RunImpact` into the bundled response. Predicates use `s.name = @q COLLATE NOCASE` / `r.symbol_name = @q COLLATE NOCASE` / `r.container_name = @q COLLATE NOCASE`, backed by new `idx_symbol_refs_name_nocase` and `idx_symbol_refs_container_nocase` covering indexes on `symbol_references` so multi-exact lookups stay SARGable. Closes the round-trip gap where an AI client had `symbols --exact` for name resolution but still had to fall back to substring matching for the follow-up definition / reference / call graph calls. ASCII-only NOCASE limitation from #81 still applies (non-ASCII casing is not folded; Unicode folding tracked in #86). Affected: `src/CodeIndex/Database/DbReader.cs`, `src/CodeIndex/Database/DbSymbolReader.cs`, `src/CodeIndex/Database/DbContext.cs`, `src/CodeIndex/Cli/QueryCommandRunner.cs`, `src/CodeIndex/Cli/ConsoleUi.cs`, `src/CodeIndex/Mcp/McpToolDefinitions.cs`, `src/CodeIndex/Mcp/McpToolHandlers.cs`, `tests/CodeIndex.Tests/DbReaderTests.cs`, `README.md`, `CLAUDE.md`. Closes #83. - **`--exact` on `symbols` for precise name resolution (#81)** — `cdidx symbols` and MCP `symbols` now accept `--exact` / `exact: true` to match symbol names by case-insensitive equality instead of `LIKE %...%` substring. When AI clients pass a resolved candidate list from an earlier `map` / `inspect` / `search` call, querying `Run` no longer also returns `RunAsync`, `RunImpact`, etc., saving a client-side filter pass and reducing token output. Composes with repeated `--name` / positional names (OR-joined per-name equality), and with all existing filters (`--kind`, `--lang`, `--path`, `--exclude-path`, `--exclude-tests`, `--since`, `--limit`). Default behavior (substring) is unchanged. The exact-match predicate uses `s.name = @q COLLATE NOCASE` (not `lower(col) = lower(@q)`) backed by a new `idx_symbols_name_nocase` covering index so multi-name exact lookups stay O(log n) per name instead of a full-table scan. Case-insensitivity follows SQLite's `NOCASE` collation (ASCII only) — non-ASCII casing pairs such as `Ä` / `ä` are not folded; pass the exact casing for non-ASCII identifiers. Unicode folding is tracked in #86. Affected: `src/CodeIndex/Database/DbSymbolReader.cs`, `src/CodeIndex/Database/DbContext.cs`, `src/CodeIndex/Cli/QueryCommandRunner.cs`, `src/CodeIndex/Cli/ConsoleUi.cs`, `src/CodeIndex/Mcp/McpToolDefinitions.cs`, `src/CodeIndex/Mcp/McpToolHandlers.cs`, `tests/CodeIndex.Tests/DbReaderTests.cs`, `README.md`. Closes #81. - **Multi-name `symbols` query (#69)** — `symbols` now accepts multiple names in a single call so AI clients can resolve a candidate list without issuing one command per name. Supported forms: repeatable positional (`cdidx symbols A B C`) and repeatable `--name` flag (`--name A --name B`). Names are OR-joined server-side with per-name candidate fetch + round-robin merge under the user's `--limit` cap (so a popular name cannot starve others, and `--limit` still bounds total results). `|` is treated as a literal name character so operator symbols such as `operator |` remain searchable. All existing filters (`--kind`, `--lang`, `--path`, `--exclude-tests`, `--since`) still apply, and MCP `symbols` gains a parallel `names` array. Fully additive — single-name calls behave identically. Affected: `src/CodeIndex/Cli/QueryCommandRunner.cs`, `src/CodeIndex/Database/DbSymbolReader.cs`, `src/CodeIndex/Mcp/McpToolHandlers.cs`, `src/CodeIndex/Mcp/McpToolDefinitions.cs`, `tests/CodeIndex.Tests/DbReaderTests.cs`, `README.md`. Closes #69. @@ -601,7 +601,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ### [Unreleased] #### 追加 -- **リポジトリ追跡の `.claude/settings.json` で cdidx 最優先のコード検索を強制** — AI エージェントが代用しがちなコード検索/ファイル探索系のシェルコマンドを網羅的に deny するリポジトリ追跡版 Claude Code 権限ファイルを追加(`Bash(rg:*)`、`Bash(grep:*)`、`Bash(egrep:*)`、`Bash(fgrep:*)`、`Bash(zgrep:*)`、`Bash(rgrep:*)`、`Bash(ripgrep:*)`、`Bash(ag:*)`、`Bash(ack:*)`、`Bash(ack-grep:*)`、`Bash(git grep:*)`、`Bash(find:*)`、`Bash(locate:*)`、`Bash(mlocate:*)`、`Bash(mdfind:*)`、`Bash(cdidx:*)`)。SELF_IMPROVEMENT.md では「ripgrep / grep / グローバル `cdidx` ではなく、ローカルビルドした `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を使う」ルールを既に定義していたが、harness レベルで強制する仕組みが無く、エージェントが黙ってインストール済みの検索ツールや、ブランチ差分を反映しない古い DB スキーマ・抽出ルールのグローバル `cdidx` にフォールバックできてしまっていた。この設定ファイルで、そのガイドラインをハード gate に昇格し、Grep / Glob 組み込みツールか新しくビルドしたローカルバイナリの使用を強制する。shell レベルでこれらのコマンドを使いたい貢献者は、個人ごとの追跡外 `.claude/settings.local.json` で allow-list すれば引き続き使える。deny リストには Linux / macOS の `install.sh` が配置する絶対パス経由の逃げ道を塞ぐ `Bash(~/.local/bin/cdidx:*)` も含む。Claude Code は `deny` を絶対視し `settings.local.json` の allow では上書きできないため、`CLOUD_BOOTSTRAP_PROMPT.md` に Step 1.5 を追加し、Cloud セッションではワークスペース上の `.claude/settings.json` から `cdidx` 系 deny 2 行をセッション限定で削除(コミットしない)する運用を明記した。SDK のないコンテナでもインストール済みバイナリを使える状態を保つため。対象: `.claude/settings.json`、`CLOUD_BOOTSTRAP_PROMPT.md`、`CLAUDE.md`。 +- **リポジトリ追跡の `.claude/settings.json` で cdidx 最優先のコード検索を強制** — AI エージェントが代用しがちなコード検索/ファイル探索系のシェルコマンドを網羅的に deny するリポジトリ追跡版 Claude Code 権限ファイルを追加(`Bash(rg:*)`、`Bash(grep:*)`、`Bash(egrep:*)`、`Bash(fgrep:*)`、`Bash(zgrep:*)`、`Bash(rgrep:*)`、`Bash(ripgrep:*)`、`Bash(ag:*)`、`Bash(ack:*)`、`Bash(ack-grep:*)`、`Bash(git grep:*)`、`Bash(find:*)`、`Bash(locate:*)`、`Bash(mlocate:*)`、`Bash(mdfind:*)`、`Bash(cdidx:*)`)。SELF_IMPROVEMENT.md では「ripgrep / grep / グローバル `cdidx` ではなく、ローカルビルドした `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を使う」ルールを既に定義していたが、harness レベルで強制する仕組みが無く、エージェントが黙ってインストール済みの検索ツールや、ブランチ差分を反映しない古い DB スキーマ・抽出ルールのグローバル `cdidx` にフォールバックできてしまっていた。この設定ファイルで、そのガイドラインをハード gate に昇格し、Grep / Glob 組み込みツールか新しくビルドしたローカルバイナリの使用を強制する。Claude Code は追跡された `deny` を絶対視し `.claude/settings.local.json` の allow では上書きできないため、どうしても shell レベルで使いたい貢献者はそのセッションに限りワークスペース上の `.claude/settings.json` を編集してコミットしない運用を取る必要がある。deny リストには Linux / macOS の `install.sh` が配置する絶対パス経由の逃げ道を塞ぐ `Bash(~/.local/bin/cdidx:*)` も含む。Claude Code は `deny` を絶対視し `settings.local.json` の allow では上書きできないため、`CLOUD_BOOTSTRAP_PROMPT.md` に Step 1.5 を追加し、Cloud セッションではワークスペース上の `.claude/settings.json` から `cdidx` 系 deny 2 行をセッション限定で削除(コミットしない)する運用を明記した。SDK のないコンテナでもインストール済みバイナリを使える状態を保つため。対象: `.claude/settings.json`、`CLOUD_BOOTSTRAP_PROMPT.md`、`CLAUDE.md`。 - **`--exact` を `definition` / `references` / `callers` / `callees` / `inspect` にも拡張 (#83)** — #81 で symbols に入れた大文字小文字無視の完全一致セマンティクスを、`cdidx definition`、`cdidx references`、`cdidx callers`、`cdidx callees`、`cdidx inspect` と対応する MCP ツール(`analyze_symbol` を含む)にも `exact` boolean として展開。`inspect` / `analyze_symbol` は bundle 内の全 sub-query(定義、参照、caller、callee)に `exact` を伝播するため、一発解決の AI ワークフローも leaf コマンドと同じ precision contract を維持する — `inspect Run --exact` が `RunAsync` / `RunImpact` を含んだ bundle を返すことは無い。述語は `s.name = @q COLLATE NOCASE` / `r.symbol_name = @q COLLATE NOCASE` / `r.container_name = @q COLLATE NOCASE` を使い、新規の `idx_symbol_refs_name_nocase` / `idx_symbol_refs_container_nocase` covering index を貼ることで multi-exact 検索も SARGable に保つ。AI クライアントが `symbols --exact` で名前を解決した後、definition / reference / call graph の追撃で substring に戻らざるを得なかった往復ロスを解消する。#81 の ASCII NOCASE 限定は引き続き適用される(非 ASCII の casing は畳み込まれず、Unicode fold は #86 で追跡)。対象: `src/CodeIndex/Database/DbReader.cs`、`src/CodeIndex/Database/DbSymbolReader.cs`、`src/CodeIndex/Database/DbContext.cs`、`src/CodeIndex/Cli/QueryCommandRunner.cs`、`src/CodeIndex/Cli/ConsoleUi.cs`、`src/CodeIndex/Mcp/McpToolDefinitions.cs`、`src/CodeIndex/Mcp/McpToolHandlers.cs`、`tests/CodeIndex.Tests/DbReaderTests.cs`、`README.md`、`CLAUDE.md`。Closes #83. - **`symbols` に `--exact` を追加し名前の正確な解決を可能に (#81)** — `cdidx symbols` と MCP の `symbols` が `--exact` / `exact: true` を受け付け、`LIKE %...%` の部分一致ではなく大文字小文字を無視した名前の完全一致で検索するようになった。AI クライアントが先行の `map` / `inspect` / `search` 結果から解決済みの候補リストを渡す場合、`Run` を指定しても `RunAsync` / `RunImpact` 等に広がらないため、クライアント側での後段フィルタが不要になりトークン出力も減る。繰り返しの `--name` や positional 名と組み合わせれば名前ごとの完全一致を OR 結合でき、既存フィルタ(`--kind`、`--lang`、`--path`、`--exclude-path`、`--exclude-tests`、`--since`、`--limit`)もそのまま適用される。既定挙動(部分一致)は変わらない。完全一致述語は `lower(col) = lower(@q)` ではなく `s.name = @q COLLATE NOCASE` を使い、新規の `idx_symbols_name_nocase` covering index を貼ることで multi-name exact 時にもフルスキャンにならず O(log n) × 名前数で解決する。大文字小文字無視は SQLite の `NOCASE`(ASCII 限定)に従うため、`Ä` / `ä` のような非 ASCII の casing 差分は畳み込まれない — 非 ASCII 識別子はインデックス時と同じ casing を渡すこと。Unicode fold の対応は #86 で追跡。対象: `src/CodeIndex/Database/DbSymbolReader.cs`、`src/CodeIndex/Database/DbContext.cs`、`src/CodeIndex/Cli/QueryCommandRunner.cs`、`src/CodeIndex/Cli/ConsoleUi.cs`、`src/CodeIndex/Mcp/McpToolDefinitions.cs`、`src/CodeIndex/Mcp/McpToolHandlers.cs`、`tests/CodeIndex.Tests/DbReaderTests.cs`、`README.md`。Closes #81. - **`symbols` の複数名クエリ (#69)** — `symbols` が 1 回の呼び出しで複数のシンボル名を解決できるようになり、AI クライアントが候補リストをコマンドごとに分けて問い合わせる必要がなくなった。対応形式: 繰り返しの positional(`cdidx symbols A B C`)、繰り返しの `--name` フラグ(`--name A --name B`)。名前はサーバー側で OR 結合され、名前ごとの候補取得 + round-robin マージを `--limit` の範囲内で行うため、人気名が他を押し出すことなく `--limit` は従来どおり合計の上限として働く。`|` はシンボル名の文字として扱うので `operator |` のような演算子シンボルも検索可能。既存フィルタ(`--kind`、`--lang`、`--path`、`--exclude-tests`、`--since`)はそのまま適用される。MCP の `symbols` にも `names` 配列を追加。単一名呼び出しは従来どおり動作する完全な追加変更。対象: `src/CodeIndex/Cli/QueryCommandRunner.cs`、`src/CodeIndex/Database/DbSymbolReader.cs`、`src/CodeIndex/Mcp/McpToolHandlers.cs`、`src/CodeIndex/Mcp/McpToolDefinitions.cs`、`tests/CodeIndex.Tests/DbReaderTests.cs`、`README.md`。Closes #69. diff --git a/CLAUDE.md b/CLAUDE.md index e7589274b7..8c35a102b2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -175,7 +175,7 @@ The only production dependency is **Microsoft.Data.Sqlite** — keep it that way Code review uses the **locally built binary** from the current commit (`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`) to search and verify the codebase. This means the reviewer sees exactly what the code actually does — not what tests claim it does, not what documentation says it does, but what the running binary produces. **It is strictly forbidden to intentionally implement incomplete, hollow, or deceptive code that passes tests or review on paper but fails in practice.** Every feature must work correctly when exercised by the binary itself. Cutting corners to "pass review" defeats the purpose of the self-improvement loop and will be caught by dogfooding. ### Code search tools (Claude Code / AI harnesses) -Repo-tracked `.claude/settings.json` denies the full set of shell code-search and file-discovery commands (`rg`, `grep`, `egrep`, `fgrep`, `zgrep`, `rgrep`, `ripgrep`, `ag`, `ack`, `ack-grep`, `git grep`, `find`, `locate`, `mlocate`, `mdfind`, `cdidx`, `~/.local/bin/cdidx`) so Claude Code agents cannot silently fall back to any of them. The `~/.local/bin/cdidx` entry closes the absolute-path loophole used by `install.sh` on Linux / macOS. Cloud Claude Code sessions rely on that installed binary, so `CLOUD_BOOTSTRAP_PROMPT.md` instructs those sessions to strip the two `cdidx` deny entries from the workspace copy of `.claude/settings.json` (session-local, uncommitted). Use the built-in Grep / Glob tools and the **locally built binary** (`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`) for searches — the global `cdidx` may have an older DB schema, missing query features, or stale extraction logic that silently returns wrong results. Contributors who want shell-level access to any of these commands can allow-list them in their own untracked `.claude/settings.local.json`. +Repo-tracked `.claude/settings.json` denies the full set of shell code-search and file-discovery commands (`rg`, `grep`, `egrep`, `fgrep`, `zgrep`, `rgrep`, `ripgrep`, `ag`, `ack`, `ack-grep`, `git grep`, `find`, `locate`, `mlocate`, `mdfind`, `cdidx`, `~/.local/bin/cdidx`) so Claude Code agents cannot silently fall back to any of them. The `~/.local/bin/cdidx` entry closes the absolute-path loophole used by `install.sh` on Linux / macOS. Cloud Claude Code sessions rely on that installed binary, so `CLOUD_BOOTSTRAP_PROMPT.md` instructs those sessions to strip the two `cdidx` deny entries from the workspace copy of `.claude/settings.json` (session-local, uncommitted). Use the built-in Grep / Glob tools and the **locally built binary** (`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`) for searches — the global `cdidx` may have an older DB schema, missing query features, or stale extraction logic that silently returns wrong results. Claude Code treats tracked `deny` entries as absolute — `.claude/settings.local.json` allows cannot override them. Contributors who intentionally need shell-level access to a denied command must edit the workspace copy of `.claude/settings.json` for that session only and not commit the change (same mechanism as the Cloud Bootstrap Step 1.5). ### Method signature changes When changing a method's return type or parameters (e.g. `BuildRecord` from `(FileRecord, string)` to `(FileRecord, string, string?)`), **update ALL callers** in the same commit: @@ -417,7 +417,7 @@ tests/CodeIndex.Tests/ コードレビューは現在のコミットから**ローカルビルドしたバイナリ**(`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`)を使ってコードベースを検索・検証します。つまりレビュアーは、テストが主張する動作でもドキュメントが述べる動作でもなく、実行中のバイナリが実際に出す結果を見ます。**テストやレビューを表面上パスするが実際には動作しない、不完全・中身のない・欺瞞的なコードを意図的に実装することは厳禁です。** すべての機能はバイナリ自身で実行したときに正しく動作しなければなりません。「レビューを通す」ための手抜きは自己改善ループの目的を損ない、ドッグフーディングで必ず発覚します。 ### コード検索ツール(Claude Code / AI ハーネス) -リポジトリ追跡の `.claude/settings.json` で、shell のコード検索・ファイル探索系コマンドを網羅的に deny しています(`rg`、`grep`、`egrep`、`fgrep`、`zgrep`、`rgrep`、`ripgrep`、`ag`、`ack`、`ack-grep`、`git grep`、`find`、`locate`、`mlocate`、`mdfind`、`cdidx`、`~/.local/bin/cdidx`)。これにより Claude Code エージェントは、これらのいずれにも黙ってフォールバックできません。`~/.local/bin/cdidx` は Linux / macOS の `install.sh` が配置する絶対パスからの逃げ道を塞ぐためのエントリです。Cloud の Claude Code セッションはそのインストール済みバイナリに依存するため、`CLOUD_BOOTSTRAP_PROMPT.md` では該当セッションに対してワークスペース上の `.claude/settings.json` から `cdidx` 系 deny 2 行をセッション限定で削除(コミットしない)するよう案内しています。検索には組み込みの Grep / Glob ツール、または**ローカルビルドしたバイナリ**(`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`)を使ってください — グローバル版 `cdidx` は DB スキーマが古い、クエリ機能が欠けている、抽出ロジックが古くて誤った結果を返す恐れがあります。shell レベルで使いたい貢献者は、自分の追跡外 `.claude/settings.local.json` で allow-list してください。 +リポジトリ追跡の `.claude/settings.json` で、shell のコード検索・ファイル探索系コマンドを網羅的に deny しています(`rg`、`grep`、`egrep`、`fgrep`、`zgrep`、`rgrep`、`ripgrep`、`ag`、`ack`、`ack-grep`、`git grep`、`find`、`locate`、`mlocate`、`mdfind`、`cdidx`、`~/.local/bin/cdidx`)。これにより Claude Code エージェントは、これらのいずれにも黙ってフォールバックできません。`~/.local/bin/cdidx` は Linux / macOS の `install.sh` が配置する絶対パスからの逃げ道を塞ぐためのエントリです。Cloud の Claude Code セッションはそのインストール済みバイナリに依存するため、`CLOUD_BOOTSTRAP_PROMPT.md` では該当セッションに対してワークスペース上の `.claude/settings.json` から `cdidx` 系 deny 2 行をセッション限定で削除(コミットしない)するよう案内しています。検索には組み込みの Grep / Glob ツール、または**ローカルビルドしたバイナリ**(`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`)を使ってください — グローバル版 `cdidx` は DB スキーマが古い、クエリ機能が欠けている、抽出ロジックが古くて誤った結果を返す恐れがあります。Claude Code は追跡された `deny` を絶対視し `.claude/settings.local.json` の allow でも上書きできません。denyされたコマンドを意図的に shell レベルで使う必要がある貢献者は、そのセッションに限りワークスペース上の `.claude/settings.json` を編集してコミットしない方式を使ってください(Cloud Bootstrap の Step 1.5 と同じ手順)。 ### メソッドシグネチャの変更 メソッドの戻り値やパラメータを変更した場合(例: `BuildRecord`を`(FileRecord, string)`から`(FileRecord, string, string?)`に変更)、**同じコミットで全ての呼び出し元を更新すること**: From a3bd53ffa80057ea824872bfb0dcc0f61f081531 Mon Sep 17 00:00:00 2001 From: Widthdom Date: Mon, 13 Apr 2026 19:53:53 +0900 Subject: [PATCH 3/8] Soften deny-precedence claims and broaden install-path coverage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address Codex review #2: the prior wording treated "tracked deny cannot be overridden by settings.local.json allows" as a guaranteed rule, but this was written from observation without a public spec citation. Rewrite the claim across CLAUDE.md, CLOUD_BOOTSTRAP_PROMPT.md, and the Unreleased CHANGELOG entry (English + Japanese) as observed behavior with a verify-in-your-own-environment caveat, and offer the settings.local.json allow path as an equivalent alternative for builds where it does override deny. Also broaden install-path coverage: add Bash($HOME/.local/bin/cdidx:*) alongside the existing Bash(~/.local/bin/cdidx:*) to close both the tilde- and $HOME-spelled forms used by install.sh, and state plainly that Claude Code permission matching is textual — fully expanded absolute paths (/Users/alice/.local/bin/cdidx) are not covered and rely on contributor discipline. Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/settings.json | 3 ++- CHANGELOG.md | 4 ++-- CLAUDE.md | 4 ++-- CLOUD_BOOTSTRAP_PROMPT.md | 40 ++++++++++++++++++++++++--------------- 4 files changed, 31 insertions(+), 20 deletions(-) diff --git a/.claude/settings.json b/.claude/settings.json index d71b42dc84..ae10e5d8cb 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -17,7 +17,8 @@ "Bash(mlocate:*)", "Bash(mdfind:*)", "Bash(cdidx:*)", - "Bash(~/.local/bin/cdidx:*)" + "Bash(~/.local/bin/cdidx:*)", + "Bash($HOME/.local/bin/cdidx:*)" ] } } diff --git a/CHANGELOG.md b/CHANGELOG.md index e4c475667f..46011c5017 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ### [Unreleased] #### Added -- **Tracked `.claude/settings.json` enforces cdidx-first code search for Claude Code agents** — Ship a repo-tracked Claude Code permissions file that denies the full set of code-search / file-discovery shell commands AI agents typically reach for: `Bash(rg:*)`, `Bash(grep:*)`, `Bash(egrep:*)`, `Bash(fgrep:*)`, `Bash(zgrep:*)`, `Bash(rgrep:*)`, `Bash(ripgrep:*)`, `Bash(ag:*)`, `Bash(ack:*)`, `Bash(ack-grep:*)`, `Bash(git grep:*)`, `Bash(find:*)`, `Bash(locate:*)`, `Bash(mlocate:*)`, `Bash(mdfind:*)`, and `Bash(cdidx:*)`. SELF_IMPROVEMENT.md already told contributors to use the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` instead of ripgrep / grep / the globally installed `cdidx`, but nothing enforced it at the harness level — agents could still silently fall back to whichever search tool happened to be installed, or to a stale global `cdidx` whose DB schema and extraction rules lag this branch. The new settings file turns that guidance into a hard gate so agents are forced to use the Grep / Glob built-ins or the freshly built local binary. Claude Code treats tracked `deny` as absolute — `.claude/settings.local.json` allows cannot override it — so contributors who intentionally need shell-level access must edit the workspace copy of `.claude/settings.json` for that session only and not commit the change. The deny list also includes `Bash(~/.local/bin/cdidx:*)` to close the absolute-path loophole used by `install.sh` on Linux / macOS. Because Claude Code treats `deny` as absolute (`settings.local.json` allows cannot override it), `CLOUD_BOOTSTRAP_PROMPT.md` gains a Step 1.5 instructing cloud sessions to strip the two `cdidx` deny entries from the workspace copy of `.claude/settings.json` (session-local, uncommitted) so the installed binary remains usable in SDK-less containers. Affected: `.claude/settings.json`, `CLOUD_BOOTSTRAP_PROMPT.md`, `CLAUDE.md`. +- **Tracked `.claude/settings.json` enforces cdidx-first code search for Claude Code agents** — Ship a repo-tracked Claude Code permissions file that denies the full set of code-search / file-discovery shell commands AI agents typically reach for: `Bash(rg:*)`, `Bash(grep:*)`, `Bash(egrep:*)`, `Bash(fgrep:*)`, `Bash(zgrep:*)`, `Bash(rgrep:*)`, `Bash(ripgrep:*)`, `Bash(ag:*)`, `Bash(ack:*)`, `Bash(ack-grep:*)`, `Bash(git grep:*)`, `Bash(find:*)`, `Bash(locate:*)`, `Bash(mlocate:*)`, `Bash(mdfind:*)`, and `Bash(cdidx:*)`. SELF_IMPROVEMENT.md already told contributors to use the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` instead of ripgrep / grep / the globally installed `cdidx`, but nothing enforced it at the harness level — agents could still silently fall back to whichever search tool happened to be installed, or to a stale global `cdidx` whose DB schema and extraction rules lag this branch. The new settings file turns that guidance into a hard gate so agents are forced to use the Grep / Glob built-ins or the freshly built local binary. Observed Claude Code behavior is that tracked `deny` is not overridden by `.claude/settings.local.json` allows (not confirmed against a public spec — treat as an observed workaround). Contributors who intentionally need shell-level access should edit the workspace copy of `.claude/settings.json` for that session only and not commit the change. The deny list also adds `Bash(~/.local/bin/cdidx:*)` and `Bash($HOME/.local/bin/cdidx:*)` to cover the tilde- and `$HOME`-spelled absolute paths used by `install.sh` on Linux / macOS; fully expanded absolute paths (e.g. `/Users/alice/.local/bin/cdidx`) are not covered because Claude Code permission matching is textual, and rely on contributor discipline plus CLAUDE.md guidance. `CLOUD_BOOTSTRAP_PROMPT.md` gains a Step 1.5 instructing cloud sessions to strip the `cdidx` deny entries from the workspace copy of `.claude/settings.json` (session-local, uncommitted) so the installed binary remains usable in SDK-less containers. Affected: `.claude/settings.json`, `CLOUD_BOOTSTRAP_PROMPT.md`, `CLAUDE.md`. - **`--exact` extended to `definition` / `references` / `callers` / `callees` / `inspect` (#83)** — The case-insensitive exact-match semantic introduced in #81 now also applies to `cdidx definition`, `cdidx references`, `cdidx callers`, `cdidx callees`, `cdidx inspect`, and their MCP tool counterparts (`analyze_symbol` included) via an `exact` boolean. `inspect` / `analyze_symbol` propagates `exact` into every bundled sub-query (definitions, references, callers, callees) so the one-round-trip AI workflow keeps the same precision contract as the leaf commands — `inspect Run --exact` no longer pulls `RunAsync` / `RunImpact` into the bundled response. Predicates use `s.name = @q COLLATE NOCASE` / `r.symbol_name = @q COLLATE NOCASE` / `r.container_name = @q COLLATE NOCASE`, backed by new `idx_symbol_refs_name_nocase` and `idx_symbol_refs_container_nocase` covering indexes on `symbol_references` so multi-exact lookups stay SARGable. Closes the round-trip gap where an AI client had `symbols --exact` for name resolution but still had to fall back to substring matching for the follow-up definition / reference / call graph calls. ASCII-only NOCASE limitation from #81 still applies (non-ASCII casing is not folded; Unicode folding tracked in #86). Affected: `src/CodeIndex/Database/DbReader.cs`, `src/CodeIndex/Database/DbSymbolReader.cs`, `src/CodeIndex/Database/DbContext.cs`, `src/CodeIndex/Cli/QueryCommandRunner.cs`, `src/CodeIndex/Cli/ConsoleUi.cs`, `src/CodeIndex/Mcp/McpToolDefinitions.cs`, `src/CodeIndex/Mcp/McpToolHandlers.cs`, `tests/CodeIndex.Tests/DbReaderTests.cs`, `README.md`, `CLAUDE.md`. Closes #83. - **`--exact` on `symbols` for precise name resolution (#81)** — `cdidx symbols` and MCP `symbols` now accept `--exact` / `exact: true` to match symbol names by case-insensitive equality instead of `LIKE %...%` substring. When AI clients pass a resolved candidate list from an earlier `map` / `inspect` / `search` call, querying `Run` no longer also returns `RunAsync`, `RunImpact`, etc., saving a client-side filter pass and reducing token output. Composes with repeated `--name` / positional names (OR-joined per-name equality), and with all existing filters (`--kind`, `--lang`, `--path`, `--exclude-path`, `--exclude-tests`, `--since`, `--limit`). Default behavior (substring) is unchanged. The exact-match predicate uses `s.name = @q COLLATE NOCASE` (not `lower(col) = lower(@q)`) backed by a new `idx_symbols_name_nocase` covering index so multi-name exact lookups stay O(log n) per name instead of a full-table scan. Case-insensitivity follows SQLite's `NOCASE` collation (ASCII only) — non-ASCII casing pairs such as `Ä` / `ä` are not folded; pass the exact casing for non-ASCII identifiers. Unicode folding is tracked in #86. Affected: `src/CodeIndex/Database/DbSymbolReader.cs`, `src/CodeIndex/Database/DbContext.cs`, `src/CodeIndex/Cli/QueryCommandRunner.cs`, `src/CodeIndex/Cli/ConsoleUi.cs`, `src/CodeIndex/Mcp/McpToolDefinitions.cs`, `src/CodeIndex/Mcp/McpToolHandlers.cs`, `tests/CodeIndex.Tests/DbReaderTests.cs`, `README.md`. Closes #81. - **Multi-name `symbols` query (#69)** — `symbols` now accepts multiple names in a single call so AI clients can resolve a candidate list without issuing one command per name. Supported forms: repeatable positional (`cdidx symbols A B C`) and repeatable `--name` flag (`--name A --name B`). Names are OR-joined server-side with per-name candidate fetch + round-robin merge under the user's `--limit` cap (so a popular name cannot starve others, and `--limit` still bounds total results). `|` is treated as a literal name character so operator symbols such as `operator |` remain searchable. All existing filters (`--kind`, `--lang`, `--path`, `--exclude-tests`, `--since`) still apply, and MCP `symbols` gains a parallel `names` array. Fully additive — single-name calls behave identically. Affected: `src/CodeIndex/Cli/QueryCommandRunner.cs`, `src/CodeIndex/Database/DbSymbolReader.cs`, `src/CodeIndex/Mcp/McpToolHandlers.cs`, `src/CodeIndex/Mcp/McpToolDefinitions.cs`, `tests/CodeIndex.Tests/DbReaderTests.cs`, `README.md`. Closes #69. @@ -601,7 +601,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ### [Unreleased] #### 追加 -- **リポジトリ追跡の `.claude/settings.json` で cdidx 最優先のコード検索を強制** — AI エージェントが代用しがちなコード検索/ファイル探索系のシェルコマンドを網羅的に deny するリポジトリ追跡版 Claude Code 権限ファイルを追加(`Bash(rg:*)`、`Bash(grep:*)`、`Bash(egrep:*)`、`Bash(fgrep:*)`、`Bash(zgrep:*)`、`Bash(rgrep:*)`、`Bash(ripgrep:*)`、`Bash(ag:*)`、`Bash(ack:*)`、`Bash(ack-grep:*)`、`Bash(git grep:*)`、`Bash(find:*)`、`Bash(locate:*)`、`Bash(mlocate:*)`、`Bash(mdfind:*)`、`Bash(cdidx:*)`)。SELF_IMPROVEMENT.md では「ripgrep / grep / グローバル `cdidx` ではなく、ローカルビルドした `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を使う」ルールを既に定義していたが、harness レベルで強制する仕組みが無く、エージェントが黙ってインストール済みの検索ツールや、ブランチ差分を反映しない古い DB スキーマ・抽出ルールのグローバル `cdidx` にフォールバックできてしまっていた。この設定ファイルで、そのガイドラインをハード gate に昇格し、Grep / Glob 組み込みツールか新しくビルドしたローカルバイナリの使用を強制する。Claude Code は追跡された `deny` を絶対視し `.claude/settings.local.json` の allow では上書きできないため、どうしても shell レベルで使いたい貢献者はそのセッションに限りワークスペース上の `.claude/settings.json` を編集してコミットしない運用を取る必要がある。deny リストには Linux / macOS の `install.sh` が配置する絶対パス経由の逃げ道を塞ぐ `Bash(~/.local/bin/cdidx:*)` も含む。Claude Code は `deny` を絶対視し `settings.local.json` の allow では上書きできないため、`CLOUD_BOOTSTRAP_PROMPT.md` に Step 1.5 を追加し、Cloud セッションではワークスペース上の `.claude/settings.json` から `cdidx` 系 deny 2 行をセッション限定で削除(コミットしない)する運用を明記した。SDK のないコンテナでもインストール済みバイナリを使える状態を保つため。対象: `.claude/settings.json`、`CLOUD_BOOTSTRAP_PROMPT.md`、`CLAUDE.md`。 +- **リポジトリ追跡の `.claude/settings.json` で cdidx 最優先のコード検索を強制** — AI エージェントが代用しがちなコード検索/ファイル探索系のシェルコマンドを網羅的に deny するリポジトリ追跡版 Claude Code 権限ファイルを追加(`Bash(rg:*)`、`Bash(grep:*)`、`Bash(egrep:*)`、`Bash(fgrep:*)`、`Bash(zgrep:*)`、`Bash(rgrep:*)`、`Bash(ripgrep:*)`、`Bash(ag:*)`、`Bash(ack:*)`、`Bash(ack-grep:*)`、`Bash(git grep:*)`、`Bash(find:*)`、`Bash(locate:*)`、`Bash(mlocate:*)`、`Bash(mdfind:*)`、`Bash(cdidx:*)`)。SELF_IMPROVEMENT.md では「ripgrep / grep / グローバル `cdidx` ではなく、ローカルビルドした `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を使う」ルールを既に定義していたが、harness レベルで強制する仕組みが無く、エージェントが黙ってインストール済みの検索ツールや、ブランチ差分を反映しない古い DB スキーマ・抽出ルールのグローバル `cdidx` にフォールバックできてしまっていた。この設定ファイルで、そのガイドラインをハード gate に昇格し、Grep / Glob 組み込みツールか新しくビルドしたローカルバイナリの使用を強制する。観測された Claude Code の挙動として、追跡された `deny` は `.claude/settings.local.json` の allow では上書きされない(公開仕様で裏を取った記述ではないため、観測ベースの運用指針として扱う)。shell レベルで使いたい貢献者は、そのセッションに限りワークスペース上の `.claude/settings.json` を編集してコミットしない運用を取ること。deny リストには Linux / macOS の `install.sh` が配置する絶対パス系(チルダ形・`$HOME` 形)を塞ぐ `Bash(~/.local/bin/cdidx:*)` と `Bash($HOME/.local/bin/cdidx:*)` を追加する。Claude Code の permission matching はテキスト一致のため、完全展開した絶対パス(例: `/Users/alice/.local/bin/cdidx`)は塞げず、貢献者の運用と CLAUDE.md の指針に委ねる。`CLOUD_BOOTSTRAP_PROMPT.md` に Step 1.5 を追加し、Cloud セッションではワークスペース上の `.claude/settings.json` から `cdidx` 系 deny をセッション限定で削除(コミットしない)する運用を明記した。SDK のないコンテナでもインストール済みバイナリを使える状態を保つため。対象: `.claude/settings.json`、`CLOUD_BOOTSTRAP_PROMPT.md`、`CLAUDE.md`。 - **`--exact` を `definition` / `references` / `callers` / `callees` / `inspect` にも拡張 (#83)** — #81 で symbols に入れた大文字小文字無視の完全一致セマンティクスを、`cdidx definition`、`cdidx references`、`cdidx callers`、`cdidx callees`、`cdidx inspect` と対応する MCP ツール(`analyze_symbol` を含む)にも `exact` boolean として展開。`inspect` / `analyze_symbol` は bundle 内の全 sub-query(定義、参照、caller、callee)に `exact` を伝播するため、一発解決の AI ワークフローも leaf コマンドと同じ precision contract を維持する — `inspect Run --exact` が `RunAsync` / `RunImpact` を含んだ bundle を返すことは無い。述語は `s.name = @q COLLATE NOCASE` / `r.symbol_name = @q COLLATE NOCASE` / `r.container_name = @q COLLATE NOCASE` を使い、新規の `idx_symbol_refs_name_nocase` / `idx_symbol_refs_container_nocase` covering index を貼ることで multi-exact 検索も SARGable に保つ。AI クライアントが `symbols --exact` で名前を解決した後、definition / reference / call graph の追撃で substring に戻らざるを得なかった往復ロスを解消する。#81 の ASCII NOCASE 限定は引き続き適用される(非 ASCII の casing は畳み込まれず、Unicode fold は #86 で追跡)。対象: `src/CodeIndex/Database/DbReader.cs`、`src/CodeIndex/Database/DbSymbolReader.cs`、`src/CodeIndex/Database/DbContext.cs`、`src/CodeIndex/Cli/QueryCommandRunner.cs`、`src/CodeIndex/Cli/ConsoleUi.cs`、`src/CodeIndex/Mcp/McpToolDefinitions.cs`、`src/CodeIndex/Mcp/McpToolHandlers.cs`、`tests/CodeIndex.Tests/DbReaderTests.cs`、`README.md`、`CLAUDE.md`。Closes #83. - **`symbols` に `--exact` を追加し名前の正確な解決を可能に (#81)** — `cdidx symbols` と MCP の `symbols` が `--exact` / `exact: true` を受け付け、`LIKE %...%` の部分一致ではなく大文字小文字を無視した名前の完全一致で検索するようになった。AI クライアントが先行の `map` / `inspect` / `search` 結果から解決済みの候補リストを渡す場合、`Run` を指定しても `RunAsync` / `RunImpact` 等に広がらないため、クライアント側での後段フィルタが不要になりトークン出力も減る。繰り返しの `--name` や positional 名と組み合わせれば名前ごとの完全一致を OR 結合でき、既存フィルタ(`--kind`、`--lang`、`--path`、`--exclude-path`、`--exclude-tests`、`--since`、`--limit`)もそのまま適用される。既定挙動(部分一致)は変わらない。完全一致述語は `lower(col) = lower(@q)` ではなく `s.name = @q COLLATE NOCASE` を使い、新規の `idx_symbols_name_nocase` covering index を貼ることで multi-name exact 時にもフルスキャンにならず O(log n) × 名前数で解決する。大文字小文字無視は SQLite の `NOCASE`(ASCII 限定)に従うため、`Ä` / `ä` のような非 ASCII の casing 差分は畳み込まれない — 非 ASCII 識別子はインデックス時と同じ casing を渡すこと。Unicode fold の対応は #86 で追跡。対象: `src/CodeIndex/Database/DbSymbolReader.cs`、`src/CodeIndex/Database/DbContext.cs`、`src/CodeIndex/Cli/QueryCommandRunner.cs`、`src/CodeIndex/Cli/ConsoleUi.cs`、`src/CodeIndex/Mcp/McpToolDefinitions.cs`、`src/CodeIndex/Mcp/McpToolHandlers.cs`、`tests/CodeIndex.Tests/DbReaderTests.cs`、`README.md`。Closes #81. - **`symbols` の複数名クエリ (#69)** — `symbols` が 1 回の呼び出しで複数のシンボル名を解決できるようになり、AI クライアントが候補リストをコマンドごとに分けて問い合わせる必要がなくなった。対応形式: 繰り返しの positional(`cdidx symbols A B C`)、繰り返しの `--name` フラグ(`--name A --name B`)。名前はサーバー側で OR 結合され、名前ごとの候補取得 + round-robin マージを `--limit` の範囲内で行うため、人気名が他を押し出すことなく `--limit` は従来どおり合計の上限として働く。`|` はシンボル名の文字として扱うので `operator |` のような演算子シンボルも検索可能。既存フィルタ(`--kind`、`--lang`、`--path`、`--exclude-tests`、`--since`)はそのまま適用される。MCP の `symbols` にも `names` 配列を追加。単一名呼び出しは従来どおり動作する完全な追加変更。対象: `src/CodeIndex/Cli/QueryCommandRunner.cs`、`src/CodeIndex/Database/DbSymbolReader.cs`、`src/CodeIndex/Mcp/McpToolHandlers.cs`、`src/CodeIndex/Mcp/McpToolDefinitions.cs`、`tests/CodeIndex.Tests/DbReaderTests.cs`、`README.md`。Closes #69. diff --git a/CLAUDE.md b/CLAUDE.md index 8c35a102b2..e287121a3e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -175,7 +175,7 @@ The only production dependency is **Microsoft.Data.Sqlite** — keep it that way Code review uses the **locally built binary** from the current commit (`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`) to search and verify the codebase. This means the reviewer sees exactly what the code actually does — not what tests claim it does, not what documentation says it does, but what the running binary produces. **It is strictly forbidden to intentionally implement incomplete, hollow, or deceptive code that passes tests or review on paper but fails in practice.** Every feature must work correctly when exercised by the binary itself. Cutting corners to "pass review" defeats the purpose of the self-improvement loop and will be caught by dogfooding. ### Code search tools (Claude Code / AI harnesses) -Repo-tracked `.claude/settings.json` denies the full set of shell code-search and file-discovery commands (`rg`, `grep`, `egrep`, `fgrep`, `zgrep`, `rgrep`, `ripgrep`, `ag`, `ack`, `ack-grep`, `git grep`, `find`, `locate`, `mlocate`, `mdfind`, `cdidx`, `~/.local/bin/cdidx`) so Claude Code agents cannot silently fall back to any of them. The `~/.local/bin/cdidx` entry closes the absolute-path loophole used by `install.sh` on Linux / macOS. Cloud Claude Code sessions rely on that installed binary, so `CLOUD_BOOTSTRAP_PROMPT.md` instructs those sessions to strip the two `cdidx` deny entries from the workspace copy of `.claude/settings.json` (session-local, uncommitted). Use the built-in Grep / Glob tools and the **locally built binary** (`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`) for searches — the global `cdidx` may have an older DB schema, missing query features, or stale extraction logic that silently returns wrong results. Claude Code treats tracked `deny` entries as absolute — `.claude/settings.local.json` allows cannot override them. Contributors who intentionally need shell-level access to a denied command must edit the workspace copy of `.claude/settings.json` for that session only and not commit the change (same mechanism as the Cloud Bootstrap Step 1.5). +Repo-tracked `.claude/settings.json` denies the full set of shell code-search and file-discovery commands (`rg`, `grep`, `egrep`, `fgrep`, `zgrep`, `rgrep`, `ripgrep`, `ag`, `ack`, `ack-grep`, `git grep`, `find`, `locate`, `mlocate`, `mdfind`, `cdidx`, `~/.local/bin/cdidx`, `$HOME/.local/bin/cdidx`) so Claude Code agents cannot silently fall back to any of them. The `~/.local/bin/cdidx` and `$HOME/.local/bin/cdidx` entries cover the tilde- and `$HOME`-spelled absolute paths used by `install.sh` on Linux / macOS. Claude Code permission matching is textual, so fully expanded absolute paths (e.g. `/Users/alice/.local/bin/cdidx`) are not covered — those forms rely on contributor discipline plus the general guidance in this section. Cloud Claude Code sessions rely on that installed binary, so `CLOUD_BOOTSTRAP_PROMPT.md` instructs those sessions to strip the `cdidx` deny entries from the workspace copy of `.claude/settings.json` (session-local, uncommitted). Use the built-in Grep / Glob tools and the **locally built binary** (`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`) for searches — the global `cdidx` may have an older DB schema, missing query features, or stale extraction logic that silently returns wrong results. Observed Claude Code behavior: tracked `deny` entries are not overridden by `.claude/settings.local.json` allows. This is not cited from a public spec, so treat it as an observed workaround rather than a guaranteed rule — verify in your own environment before relying on it. Contributors who intentionally need shell-level access to a denied command should edit the workspace copy of `.claude/settings.json` for that session only and not commit the change (same mechanism as the Cloud Bootstrap Step 1.5). ### Method signature changes When changing a method's return type or parameters (e.g. `BuildRecord` from `(FileRecord, string)` to `(FileRecord, string, string?)`), **update ALL callers** in the same commit: @@ -417,7 +417,7 @@ tests/CodeIndex.Tests/ コードレビューは現在のコミットから**ローカルビルドしたバイナリ**(`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`)を使ってコードベースを検索・検証します。つまりレビュアーは、テストが主張する動作でもドキュメントが述べる動作でもなく、実行中のバイナリが実際に出す結果を見ます。**テストやレビューを表面上パスするが実際には動作しない、不完全・中身のない・欺瞞的なコードを意図的に実装することは厳禁です。** すべての機能はバイナリ自身で実行したときに正しく動作しなければなりません。「レビューを通す」ための手抜きは自己改善ループの目的を損ない、ドッグフーディングで必ず発覚します。 ### コード検索ツール(Claude Code / AI ハーネス) -リポジトリ追跡の `.claude/settings.json` で、shell のコード検索・ファイル探索系コマンドを網羅的に deny しています(`rg`、`grep`、`egrep`、`fgrep`、`zgrep`、`rgrep`、`ripgrep`、`ag`、`ack`、`ack-grep`、`git grep`、`find`、`locate`、`mlocate`、`mdfind`、`cdidx`、`~/.local/bin/cdidx`)。これにより Claude Code エージェントは、これらのいずれにも黙ってフォールバックできません。`~/.local/bin/cdidx` は Linux / macOS の `install.sh` が配置する絶対パスからの逃げ道を塞ぐためのエントリです。Cloud の Claude Code セッションはそのインストール済みバイナリに依存するため、`CLOUD_BOOTSTRAP_PROMPT.md` では該当セッションに対してワークスペース上の `.claude/settings.json` から `cdidx` 系 deny 2 行をセッション限定で削除(コミットしない)するよう案内しています。検索には組み込みの Grep / Glob ツール、または**ローカルビルドしたバイナリ**(`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`)を使ってください — グローバル版 `cdidx` は DB スキーマが古い、クエリ機能が欠けている、抽出ロジックが古くて誤った結果を返す恐れがあります。Claude Code は追跡された `deny` を絶対視し `.claude/settings.local.json` の allow でも上書きできません。denyされたコマンドを意図的に shell レベルで使う必要がある貢献者は、そのセッションに限りワークスペース上の `.claude/settings.json` を編集してコミットしない方式を使ってください(Cloud Bootstrap の Step 1.5 と同じ手順)。 +リポジトリ追跡の `.claude/settings.json` で、shell のコード検索・ファイル探索系コマンドを網羅的に deny しています(`rg`、`grep`、`egrep`、`fgrep`、`zgrep`、`rgrep`、`ripgrep`、`ag`、`ack`、`ack-grep`、`git grep`、`find`、`locate`、`mlocate`、`mdfind`、`cdidx`、`~/.local/bin/cdidx`、`$HOME/.local/bin/cdidx`)。これにより Claude Code エージェントは、これらのいずれにも黙ってフォールバックできません。`~/.local/bin/cdidx` と `$HOME/.local/bin/cdidx` は Linux / macOS の `install.sh` が配置する絶対パス系の書き方(チルダ形・`$HOME` 形)を塞ぐためのエントリです。Claude Code の permission matching はテキスト一致なので、完全展開した絶対パス(例: `/Users/alice/.local/bin/cdidx`)は本設定では塞げません — その形は貢献者の運用ルールと本セクションの指針に委ねています。Cloud の Claude Code セッションはそのインストール済みバイナリに依存するため、`CLOUD_BOOTSTRAP_PROMPT.md` では該当セッションに対してワークスペース上の `.claude/settings.json` から `cdidx` 系 deny をセッション限定で削除(コミットしない)するよう案内しています。検索には組み込みの Grep / Glob ツール、または**ローカルビルドしたバイナリ**(`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`)を使ってください — グローバル版 `cdidx` は DB スキーマが古い、クエリ機能が欠けている、抽出ロジックが古くて誤った結果を返す恐れがあります。観測された Claude Code の挙動として、追跡された `deny` は `.claude/settings.local.json` の allow では上書きされません。これは公開仕様で裏を取った記述ではないため、絶対のルールではなく観測ベースの運用指針として扱い、各自の環境でも確認してください。deny されたコマンドを意図的に shell レベルで使う必要がある貢献者は、そのセッションに限りワークスペース上の `.claude/settings.json` を編集してコミットしない方式を使ってください(Cloud Bootstrap の Step 1.5 と同じ手順)。 ### メソッドシグネチャの変更 メソッドの戻り値やパラメータを変更した場合(例: `BuildRecord`を`(FileRecord, string)`から`(FileRecord, string, string?)`に変更)、**同じコミットで全ての呼び出し元を更新すること**: diff --git a/CLOUD_BOOTSTRAP_PROMPT.md b/CLOUD_BOOTSTRAP_PROMPT.md index 9b9f59b85a..3e0c6fcfd2 100644 --- a/CLOUD_BOOTSTRAP_PROMPT.md +++ b/CLOUD_BOOTSTRAP_PROMPT.md @@ -36,14 +36,19 @@ library is loaded via P/Invoke from the binary's directory, and ### Step 1.5 — Unblock `cdidx` in this session's permissions -The repo-tracked `.claude/settings.json` denies `Bash(cdidx:*)` and -`Bash(~/.local/bin/cdidx:*)` to keep local sessions from silently falling -back to a stale global binary. In this container those denies would block -every smoke-test command below. Claude Code treats `deny` as absolute — -`settings.local.json` allows cannot override it — so the only workable -escape is to remove those two entries from the **workspace copy** of -`.claude/settings.json` and **do not commit the change**. It is a -session-local unblock, not a repo edit. +The repo-tracked `.claude/settings.json` denies `Bash(cdidx:*)`, +`Bash(~/.local/bin/cdidx:*)`, and `Bash($HOME/.local/bin/cdidx:*)` to +keep local sessions from silently falling back to a stale global binary. +In this container those denies would block every smoke-test command +below. Observed Claude Code behavior is that tracked `deny` is not +overridden by `settings.local.json` allows (not confirmed against a +public spec — verify if your environment behaves differently). The +workaround that has been observed to work is to remove those `cdidx` +entries from the **workspace copy** of `.claude/settings.json` and +**do not commit the change**. It is a session-local unblock, not a +repo edit. If your Claude Code build honors `settings.local.json` +allow-overrides, an untracked `.claude/settings.local.json` with the +matching allow lines is an equivalent alternative. ### Step 2 — Smoke test the installed binary end-to-end @@ -155,13 +160,18 @@ export PATH="$HOME/.local/bin:$PATH" リポジトリ追跡の `.claude/settings.json` は、ローカルセッションが古い グローバルバイナリに黙ってフォールバックしないよう -`Bash(cdidx:*)` と `Bash(~/.local/bin/cdidx:*)` を deny しています。 -このコンテナではその deny が以降のスモークテストを全部ブロックします。 -Claude Code の `deny` は絶対で `settings.local.json` の allow では -上書きできないため、唯一の現実的な回避策は**ワークスペース上の** -`.claude/settings.json` からその2エントリを削除し、**その変更を -コミットしない**ことです。リポジトリへの修正ではなくセッション限定の -一時解除として扱ってください。 +`Bash(cdidx:*)`、`Bash(~/.local/bin/cdidx:*)`、 +`Bash($HOME/.local/bin/cdidx:*)` を deny しています。このコンテナでは +その deny が以降のスモークテストを全部ブロックします。観測された +Claude Code の挙動として、追跡された `deny` は `settings.local.json` +の allow では上書きされません(公開仕様で裏を取った記述ではないため、 +環境が異なる場合は各自で確認してください)。観測済みに機能する回避策は +**ワークスペース上の** `.claude/settings.json` から `cdidx` 系の +エントリを削除し、**その変更をコミットしない**ことです。リポジトリへの +修正ではなくセッション限定の一時解除として扱ってください。もし +お使いの Claude Code ビルドで `settings.local.json` の allow が +deny を上書きできるのであれば、追跡外の `.claude/settings.local.json` +に該当の allow を追加する方法も同等に使えます。 ### Step 2 — インストール済みバイナリをエンドツーエンドでスモーク From 09151861bb82a91bd5e7925db19dabc696e6161a Mon Sep 17 00:00:00 2001 From: Widthdom Date: Mon, 13 Apr 2026 20:31:33 +0900 Subject: [PATCH 4/8] Reframe cdidx deny as best-effort tripwire; sync README template Address Codex review #3. #1 (absolute-path bypass, high): wildcard absolute-path denies (/Users/*/.local/bin/cdidx:*) are not confirmed to be supported by Claude Code permission matching, so instead of claiming to close the loophole this commit reframes the deny list as a best-effort tripwire. CLAUDE.md, CHANGELOG, and the Cloud Bootstrap wording now state plainly that textual matching means fully expanded absolute paths, `command cdidx`, `env cdidx`, and similar alternate spellings remain uncovered, and that the authoritative rule is the written guidance (use Grep/Glob built-ins and the locally built dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll) rather than the settings file itself. #2 (README template contradiction, medium): the # Code Search Rules template in both English and Japanese previously told agents to fall back to `rg`, `grep`, `find`, `cat` when neither cdidx nor sqlite3 was available, which directly contradicts the new policy in Claude Code sessions. The last-resort fallback now points at the Claude Code built-in Grep / Glob tools (or the host harness's equivalent) and explicitly says not to reach for shell rg/grep/find or a global cdidx in a Claude Code session. Co-Authored-By: Claude Opus 4.6 (1M context) --- CHANGELOG.md | 4 ++-- CLAUDE.md | 4 ++-- README.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46011c5017..1ffd964f92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ### [Unreleased] #### Added -- **Tracked `.claude/settings.json` enforces cdidx-first code search for Claude Code agents** — Ship a repo-tracked Claude Code permissions file that denies the full set of code-search / file-discovery shell commands AI agents typically reach for: `Bash(rg:*)`, `Bash(grep:*)`, `Bash(egrep:*)`, `Bash(fgrep:*)`, `Bash(zgrep:*)`, `Bash(rgrep:*)`, `Bash(ripgrep:*)`, `Bash(ag:*)`, `Bash(ack:*)`, `Bash(ack-grep:*)`, `Bash(git grep:*)`, `Bash(find:*)`, `Bash(locate:*)`, `Bash(mlocate:*)`, `Bash(mdfind:*)`, and `Bash(cdidx:*)`. SELF_IMPROVEMENT.md already told contributors to use the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` instead of ripgrep / grep / the globally installed `cdidx`, but nothing enforced it at the harness level — agents could still silently fall back to whichever search tool happened to be installed, or to a stale global `cdidx` whose DB schema and extraction rules lag this branch. The new settings file turns that guidance into a hard gate so agents are forced to use the Grep / Glob built-ins or the freshly built local binary. Observed Claude Code behavior is that tracked `deny` is not overridden by `.claude/settings.local.json` allows (not confirmed against a public spec — treat as an observed workaround). Contributors who intentionally need shell-level access should edit the workspace copy of `.claude/settings.json` for that session only and not commit the change. The deny list also adds `Bash(~/.local/bin/cdidx:*)` and `Bash($HOME/.local/bin/cdidx:*)` to cover the tilde- and `$HOME`-spelled absolute paths used by `install.sh` on Linux / macOS; fully expanded absolute paths (e.g. `/Users/alice/.local/bin/cdidx`) are not covered because Claude Code permission matching is textual, and rely on contributor discipline plus CLAUDE.md guidance. `CLOUD_BOOTSTRAP_PROMPT.md` gains a Step 1.5 instructing cloud sessions to strip the `cdidx` deny entries from the workspace copy of `.claude/settings.json` (session-local, uncommitted) so the installed binary remains usable in SDK-less containers. Affected: `.claude/settings.json`, `CLOUD_BOOTSTRAP_PROMPT.md`, `CLAUDE.md`. +- **Tracked `.claude/settings.json` enforces cdidx-first code search for Claude Code agents** — Ship a repo-tracked Claude Code permissions file that denies the full set of code-search / file-discovery shell commands AI agents typically reach for: `Bash(rg:*)`, `Bash(grep:*)`, `Bash(egrep:*)`, `Bash(fgrep:*)`, `Bash(zgrep:*)`, `Bash(rgrep:*)`, `Bash(ripgrep:*)`, `Bash(ag:*)`, `Bash(ack:*)`, `Bash(ack-grep:*)`, `Bash(git grep:*)`, `Bash(find:*)`, `Bash(locate:*)`, `Bash(mlocate:*)`, `Bash(mdfind:*)`, and `Bash(cdidx:*)`. SELF_IMPROVEMENT.md already told contributors to use the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` instead of ripgrep / grep / the globally installed `cdidx`, but nothing enforced it at the harness level — agents could still silently fall back to whichever search tool happened to be installed, or to a stale global `cdidx` whose DB schema and extraction rules lag this branch. The new settings file turns that guidance into a hard gate so agents are forced to use the Grep / Glob built-ins or the freshly built local binary. Observed Claude Code behavior is that tracked `deny` is not overridden by `.claude/settings.local.json` allows (not confirmed against a public spec — treat as an observed workaround). Contributors who intentionally need shell-level access should edit the workspace copy of `.claude/settings.json` for that session only and not commit the change. The deny list adds `Bash(~/.local/bin/cdidx:*)` and `Bash($HOME/.local/bin/cdidx:*)` to cover the tilde- and `$HOME`-spelled absolute paths used by `install.sh` on Linux / macOS. CLAUDE.md, README, and this entry are reframed to describe the deny list as a **best-effort tripwire** rather than a hard guard: fully expanded absolute paths (e.g. `/Users/alice/.local/bin/cdidx`), `command cdidx`, `env cdidx`, and similar alternate spellings are not blocked because Claude Code permission matching is textual. The authoritative rule remains the written guidance (use Grep / Glob built-ins and the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`). README's `# Code Search Rules` template is updated in both languages so the last-resort fallback no longer tells Claude Code sessions to run shell `rg` / `grep` / `find` — it points at built-in Grep / Glob instead. `CLOUD_BOOTSTRAP_PROMPT.md` gains a Step 1.5 instructing cloud sessions to strip the `cdidx` deny entries from the workspace copy of `.claude/settings.json` (session-local, uncommitted) so the installed binary remains usable in SDK-less containers. Affected: `.claude/settings.json`, `CLOUD_BOOTSTRAP_PROMPT.md`, `CLAUDE.md`. - **`--exact` extended to `definition` / `references` / `callers` / `callees` / `inspect` (#83)** — The case-insensitive exact-match semantic introduced in #81 now also applies to `cdidx definition`, `cdidx references`, `cdidx callers`, `cdidx callees`, `cdidx inspect`, and their MCP tool counterparts (`analyze_symbol` included) via an `exact` boolean. `inspect` / `analyze_symbol` propagates `exact` into every bundled sub-query (definitions, references, callers, callees) so the one-round-trip AI workflow keeps the same precision contract as the leaf commands — `inspect Run --exact` no longer pulls `RunAsync` / `RunImpact` into the bundled response. Predicates use `s.name = @q COLLATE NOCASE` / `r.symbol_name = @q COLLATE NOCASE` / `r.container_name = @q COLLATE NOCASE`, backed by new `idx_symbol_refs_name_nocase` and `idx_symbol_refs_container_nocase` covering indexes on `symbol_references` so multi-exact lookups stay SARGable. Closes the round-trip gap where an AI client had `symbols --exact` for name resolution but still had to fall back to substring matching for the follow-up definition / reference / call graph calls. ASCII-only NOCASE limitation from #81 still applies (non-ASCII casing is not folded; Unicode folding tracked in #86). Affected: `src/CodeIndex/Database/DbReader.cs`, `src/CodeIndex/Database/DbSymbolReader.cs`, `src/CodeIndex/Database/DbContext.cs`, `src/CodeIndex/Cli/QueryCommandRunner.cs`, `src/CodeIndex/Cli/ConsoleUi.cs`, `src/CodeIndex/Mcp/McpToolDefinitions.cs`, `src/CodeIndex/Mcp/McpToolHandlers.cs`, `tests/CodeIndex.Tests/DbReaderTests.cs`, `README.md`, `CLAUDE.md`. Closes #83. - **`--exact` on `symbols` for precise name resolution (#81)** — `cdidx symbols` and MCP `symbols` now accept `--exact` / `exact: true` to match symbol names by case-insensitive equality instead of `LIKE %...%` substring. When AI clients pass a resolved candidate list from an earlier `map` / `inspect` / `search` call, querying `Run` no longer also returns `RunAsync`, `RunImpact`, etc., saving a client-side filter pass and reducing token output. Composes with repeated `--name` / positional names (OR-joined per-name equality), and with all existing filters (`--kind`, `--lang`, `--path`, `--exclude-path`, `--exclude-tests`, `--since`, `--limit`). Default behavior (substring) is unchanged. The exact-match predicate uses `s.name = @q COLLATE NOCASE` (not `lower(col) = lower(@q)`) backed by a new `idx_symbols_name_nocase` covering index so multi-name exact lookups stay O(log n) per name instead of a full-table scan. Case-insensitivity follows SQLite's `NOCASE` collation (ASCII only) — non-ASCII casing pairs such as `Ä` / `ä` are not folded; pass the exact casing for non-ASCII identifiers. Unicode folding is tracked in #86. Affected: `src/CodeIndex/Database/DbSymbolReader.cs`, `src/CodeIndex/Database/DbContext.cs`, `src/CodeIndex/Cli/QueryCommandRunner.cs`, `src/CodeIndex/Cli/ConsoleUi.cs`, `src/CodeIndex/Mcp/McpToolDefinitions.cs`, `src/CodeIndex/Mcp/McpToolHandlers.cs`, `tests/CodeIndex.Tests/DbReaderTests.cs`, `README.md`. Closes #81. - **Multi-name `symbols` query (#69)** — `symbols` now accepts multiple names in a single call so AI clients can resolve a candidate list without issuing one command per name. Supported forms: repeatable positional (`cdidx symbols A B C`) and repeatable `--name` flag (`--name A --name B`). Names are OR-joined server-side with per-name candidate fetch + round-robin merge under the user's `--limit` cap (so a popular name cannot starve others, and `--limit` still bounds total results). `|` is treated as a literal name character so operator symbols such as `operator |` remain searchable. All existing filters (`--kind`, `--lang`, `--path`, `--exclude-tests`, `--since`) still apply, and MCP `symbols` gains a parallel `names` array. Fully additive — single-name calls behave identically. Affected: `src/CodeIndex/Cli/QueryCommandRunner.cs`, `src/CodeIndex/Database/DbSymbolReader.cs`, `src/CodeIndex/Mcp/McpToolHandlers.cs`, `src/CodeIndex/Mcp/McpToolDefinitions.cs`, `tests/CodeIndex.Tests/DbReaderTests.cs`, `README.md`. Closes #69. @@ -601,7 +601,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ### [Unreleased] #### 追加 -- **リポジトリ追跡の `.claude/settings.json` で cdidx 最優先のコード検索を強制** — AI エージェントが代用しがちなコード検索/ファイル探索系のシェルコマンドを網羅的に deny するリポジトリ追跡版 Claude Code 権限ファイルを追加(`Bash(rg:*)`、`Bash(grep:*)`、`Bash(egrep:*)`、`Bash(fgrep:*)`、`Bash(zgrep:*)`、`Bash(rgrep:*)`、`Bash(ripgrep:*)`、`Bash(ag:*)`、`Bash(ack:*)`、`Bash(ack-grep:*)`、`Bash(git grep:*)`、`Bash(find:*)`、`Bash(locate:*)`、`Bash(mlocate:*)`、`Bash(mdfind:*)`、`Bash(cdidx:*)`)。SELF_IMPROVEMENT.md では「ripgrep / grep / グローバル `cdidx` ではなく、ローカルビルドした `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を使う」ルールを既に定義していたが、harness レベルで強制する仕組みが無く、エージェントが黙ってインストール済みの検索ツールや、ブランチ差分を反映しない古い DB スキーマ・抽出ルールのグローバル `cdidx` にフォールバックできてしまっていた。この設定ファイルで、そのガイドラインをハード gate に昇格し、Grep / Glob 組み込みツールか新しくビルドしたローカルバイナリの使用を強制する。観測された Claude Code の挙動として、追跡された `deny` は `.claude/settings.local.json` の allow では上書きされない(公開仕様で裏を取った記述ではないため、観測ベースの運用指針として扱う)。shell レベルで使いたい貢献者は、そのセッションに限りワークスペース上の `.claude/settings.json` を編集してコミットしない運用を取ること。deny リストには Linux / macOS の `install.sh` が配置する絶対パス系(チルダ形・`$HOME` 形)を塞ぐ `Bash(~/.local/bin/cdidx:*)` と `Bash($HOME/.local/bin/cdidx:*)` を追加する。Claude Code の permission matching はテキスト一致のため、完全展開した絶対パス(例: `/Users/alice/.local/bin/cdidx`)は塞げず、貢献者の運用と CLAUDE.md の指針に委ねる。`CLOUD_BOOTSTRAP_PROMPT.md` に Step 1.5 を追加し、Cloud セッションではワークスペース上の `.claude/settings.json` から `cdidx` 系 deny をセッション限定で削除(コミットしない)する運用を明記した。SDK のないコンテナでもインストール済みバイナリを使える状態を保つため。対象: `.claude/settings.json`、`CLOUD_BOOTSTRAP_PROMPT.md`、`CLAUDE.md`。 +- **リポジトリ追跡の `.claude/settings.json` で cdidx 最優先のコード検索を強制** — AI エージェントが代用しがちなコード検索/ファイル探索系のシェルコマンドを網羅的に deny するリポジトリ追跡版 Claude Code 権限ファイルを追加(`Bash(rg:*)`、`Bash(grep:*)`、`Bash(egrep:*)`、`Bash(fgrep:*)`、`Bash(zgrep:*)`、`Bash(rgrep:*)`、`Bash(ripgrep:*)`、`Bash(ag:*)`、`Bash(ack:*)`、`Bash(ack-grep:*)`、`Bash(git grep:*)`、`Bash(find:*)`、`Bash(locate:*)`、`Bash(mlocate:*)`、`Bash(mdfind:*)`、`Bash(cdidx:*)`)。SELF_IMPROVEMENT.md では「ripgrep / grep / グローバル `cdidx` ではなく、ローカルビルドした `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を使う」ルールを既に定義していたが、harness レベルで強制する仕組みが無く、エージェントが黙ってインストール済みの検索ツールや、ブランチ差分を反映しない古い DB スキーマ・抽出ルールのグローバル `cdidx` にフォールバックできてしまっていた。この設定ファイルで、そのガイドラインをハード gate に昇格し、Grep / Glob 組み込みツールか新しくビルドしたローカルバイナリの使用を強制する。観測された Claude Code の挙動として、追跡された `deny` は `.claude/settings.local.json` の allow では上書きされない(公開仕様で裏を取った記述ではないため、観測ベースの運用指針として扱う)。shell レベルで使いたい貢献者は、そのセッションに限りワークスペース上の `.claude/settings.json` を編集してコミットしない運用を取ること。deny リストには Linux / macOS の `install.sh` が配置する絶対パス系(チルダ形・`$HOME` 形)を塞ぐ `Bash(~/.local/bin/cdidx:*)` と `Bash($HOME/.local/bin/cdidx:*)` を追加する。CLAUDE.md、README、および本エントリを再構成し、deny リストはハードな gate ではなく**ベストエフォートのトリップワイヤ**として位置づけ直した: Claude Code の permission matching はテキスト一致のため、完全展開絶対パス(例: `/Users/alice/.local/bin/cdidx`)、`command cdidx`、`env cdidx` などの別スペルは塞げない。強制ルールの本体は文面そのもの(組み込み Grep / Glob とローカルビルドの `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を使う)。README の `# コードベース検索ルール` テンプレートも英日両方で更新し、最終手段のフォールバックが Claude Code セッションで shell `rg` / `grep` / `find` を使うよう促さないようにした(代わりに組み込み Grep / Glob を案内)。`CLOUD_BOOTSTRAP_PROMPT.md` に Step 1.5 を追加し、Cloud セッションではワークスペース上の `.claude/settings.json` から `cdidx` 系 deny をセッション限定で削除(コミットしない)する運用を明記した。SDK のないコンテナでもインストール済みバイナリを使える状態を保つため。対象: `.claude/settings.json`、`CLOUD_BOOTSTRAP_PROMPT.md`、`CLAUDE.md`。 - **`--exact` を `definition` / `references` / `callers` / `callees` / `inspect` にも拡張 (#83)** — #81 で symbols に入れた大文字小文字無視の完全一致セマンティクスを、`cdidx definition`、`cdidx references`、`cdidx callers`、`cdidx callees`、`cdidx inspect` と対応する MCP ツール(`analyze_symbol` を含む)にも `exact` boolean として展開。`inspect` / `analyze_symbol` は bundle 内の全 sub-query(定義、参照、caller、callee)に `exact` を伝播するため、一発解決の AI ワークフローも leaf コマンドと同じ precision contract を維持する — `inspect Run --exact` が `RunAsync` / `RunImpact` を含んだ bundle を返すことは無い。述語は `s.name = @q COLLATE NOCASE` / `r.symbol_name = @q COLLATE NOCASE` / `r.container_name = @q COLLATE NOCASE` を使い、新規の `idx_symbol_refs_name_nocase` / `idx_symbol_refs_container_nocase` covering index を貼ることで multi-exact 検索も SARGable に保つ。AI クライアントが `symbols --exact` で名前を解決した後、definition / reference / call graph の追撃で substring に戻らざるを得なかった往復ロスを解消する。#81 の ASCII NOCASE 限定は引き続き適用される(非 ASCII の casing は畳み込まれず、Unicode fold は #86 で追跡)。対象: `src/CodeIndex/Database/DbReader.cs`、`src/CodeIndex/Database/DbSymbolReader.cs`、`src/CodeIndex/Database/DbContext.cs`、`src/CodeIndex/Cli/QueryCommandRunner.cs`、`src/CodeIndex/Cli/ConsoleUi.cs`、`src/CodeIndex/Mcp/McpToolDefinitions.cs`、`src/CodeIndex/Mcp/McpToolHandlers.cs`、`tests/CodeIndex.Tests/DbReaderTests.cs`、`README.md`、`CLAUDE.md`。Closes #83. - **`symbols` に `--exact` を追加し名前の正確な解決を可能に (#81)** — `cdidx symbols` と MCP の `symbols` が `--exact` / `exact: true` を受け付け、`LIKE %...%` の部分一致ではなく大文字小文字を無視した名前の完全一致で検索するようになった。AI クライアントが先行の `map` / `inspect` / `search` 結果から解決済みの候補リストを渡す場合、`Run` を指定しても `RunAsync` / `RunImpact` 等に広がらないため、クライアント側での後段フィルタが不要になりトークン出力も減る。繰り返しの `--name` や positional 名と組み合わせれば名前ごとの完全一致を OR 結合でき、既存フィルタ(`--kind`、`--lang`、`--path`、`--exclude-path`、`--exclude-tests`、`--since`、`--limit`)もそのまま適用される。既定挙動(部分一致)は変わらない。完全一致述語は `lower(col) = lower(@q)` ではなく `s.name = @q COLLATE NOCASE` を使い、新規の `idx_symbols_name_nocase` covering index を貼ることで multi-name exact 時にもフルスキャンにならず O(log n) × 名前数で解決する。大文字小文字無視は SQLite の `NOCASE`(ASCII 限定)に従うため、`Ä` / `ä` のような非 ASCII の casing 差分は畳み込まれない — 非 ASCII 識別子はインデックス時と同じ casing を渡すこと。Unicode fold の対応は #86 で追跡。対象: `src/CodeIndex/Database/DbSymbolReader.cs`、`src/CodeIndex/Database/DbContext.cs`、`src/CodeIndex/Cli/QueryCommandRunner.cs`、`src/CodeIndex/Cli/ConsoleUi.cs`、`src/CodeIndex/Mcp/McpToolDefinitions.cs`、`src/CodeIndex/Mcp/McpToolHandlers.cs`、`tests/CodeIndex.Tests/DbReaderTests.cs`、`README.md`。Closes #81. - **`symbols` の複数名クエリ (#69)** — `symbols` が 1 回の呼び出しで複数のシンボル名を解決できるようになり、AI クライアントが候補リストをコマンドごとに分けて問い合わせる必要がなくなった。対応形式: 繰り返しの positional(`cdidx symbols A B C`)、繰り返しの `--name` フラグ(`--name A --name B`)。名前はサーバー側で OR 結合され、名前ごとの候補取得 + round-robin マージを `--limit` の範囲内で行うため、人気名が他を押し出すことなく `--limit` は従来どおり合計の上限として働く。`|` はシンボル名の文字として扱うので `operator |` のような演算子シンボルも検索可能。既存フィルタ(`--kind`、`--lang`、`--path`、`--exclude-tests`、`--since`)はそのまま適用される。MCP の `symbols` にも `names` 配列を追加。単一名呼び出しは従来どおり動作する完全な追加変更。対象: `src/CodeIndex/Cli/QueryCommandRunner.cs`、`src/CodeIndex/Database/DbSymbolReader.cs`、`src/CodeIndex/Mcp/McpToolHandlers.cs`、`src/CodeIndex/Mcp/McpToolDefinitions.cs`、`tests/CodeIndex.Tests/DbReaderTests.cs`、`README.md`。Closes #69. diff --git a/CLAUDE.md b/CLAUDE.md index e287121a3e..00a0efe6a5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -175,7 +175,7 @@ The only production dependency is **Microsoft.Data.Sqlite** — keep it that way Code review uses the **locally built binary** from the current commit (`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`) to search and verify the codebase. This means the reviewer sees exactly what the code actually does — not what tests claim it does, not what documentation says it does, but what the running binary produces. **It is strictly forbidden to intentionally implement incomplete, hollow, or deceptive code that passes tests or review on paper but fails in practice.** Every feature must work correctly when exercised by the binary itself. Cutting corners to "pass review" defeats the purpose of the self-improvement loop and will be caught by dogfooding. ### Code search tools (Claude Code / AI harnesses) -Repo-tracked `.claude/settings.json` denies the full set of shell code-search and file-discovery commands (`rg`, `grep`, `egrep`, `fgrep`, `zgrep`, `rgrep`, `ripgrep`, `ag`, `ack`, `ack-grep`, `git grep`, `find`, `locate`, `mlocate`, `mdfind`, `cdidx`, `~/.local/bin/cdidx`, `$HOME/.local/bin/cdidx`) so Claude Code agents cannot silently fall back to any of them. The `~/.local/bin/cdidx` and `$HOME/.local/bin/cdidx` entries cover the tilde- and `$HOME`-spelled absolute paths used by `install.sh` on Linux / macOS. Claude Code permission matching is textual, so fully expanded absolute paths (e.g. `/Users/alice/.local/bin/cdidx`) are not covered — those forms rely on contributor discipline plus the general guidance in this section. Cloud Claude Code sessions rely on that installed binary, so `CLOUD_BOOTSTRAP_PROMPT.md` instructs those sessions to strip the `cdidx` deny entries from the workspace copy of `.claude/settings.json` (session-local, uncommitted). Use the built-in Grep / Glob tools and the **locally built binary** (`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`) for searches — the global `cdidx` may have an older DB schema, missing query features, or stale extraction logic that silently returns wrong results. Observed Claude Code behavior: tracked `deny` entries are not overridden by `.claude/settings.local.json` allows. This is not cited from a public spec, so treat it as an observed workaround rather than a guaranteed rule — verify in your own environment before relying on it. Contributors who intentionally need shell-level access to a denied command should edit the workspace copy of `.claude/settings.json` for that session only and not commit the change (same mechanism as the Cloud Bootstrap Step 1.5). +Repo-tracked `.claude/settings.json` provides **best-effort** denial of shell code-search and file-discovery commands (`rg`, `grep`, `egrep`, `fgrep`, `zgrep`, `rgrep`, `ripgrep`, `ag`, `ack`, `ack-grep`, `git grep`, `find`, `locate`, `mlocate`, `mdfind`, `cdidx`, `~/.local/bin/cdidx`, `$HOME/.local/bin/cdidx`). This is not a hard guard: Claude Code permission matching appears to be textual, so fully expanded absolute paths (e.g. `/Users/alice/.local/bin/cdidx`), `command cdidx`, `env cdidx`, and similar alternate spellings are not blocked by this file. The authoritative rule is the written guidance in this section — use the built-in Grep / Glob tools and the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`; the deny list is a tripwire that catches the common spellings, not a sandbox. Cloud Claude Code sessions rely on that installed binary, so `CLOUD_BOOTSTRAP_PROMPT.md` instructs those sessions to strip the `cdidx` deny entries from the workspace copy of `.claude/settings.json` (session-local, uncommitted). Use the built-in Grep / Glob tools and the **locally built binary** (`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`) for searches — the global `cdidx` may have an older DB schema, missing query features, or stale extraction logic that silently returns wrong results. Observed Claude Code behavior: tracked `deny` entries are not overridden by `.claude/settings.local.json` allows. This is not cited from a public spec, so treat it as an observed workaround rather than a guaranteed rule — verify in your own environment before relying on it. Contributors who intentionally need shell-level access to a denied command should edit the workspace copy of `.claude/settings.json` for that session only and not commit the change (same mechanism as the Cloud Bootstrap Step 1.5). ### Method signature changes When changing a method's return type or parameters (e.g. `BuildRecord` from `(FileRecord, string)` to `(FileRecord, string, string?)`), **update ALL callers** in the same commit: @@ -417,7 +417,7 @@ tests/CodeIndex.Tests/ コードレビューは現在のコミットから**ローカルビルドしたバイナリ**(`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`)を使ってコードベースを検索・検証します。つまりレビュアーは、テストが主張する動作でもドキュメントが述べる動作でもなく、実行中のバイナリが実際に出す結果を見ます。**テストやレビューを表面上パスするが実際には動作しない、不完全・中身のない・欺瞞的なコードを意図的に実装することは厳禁です。** すべての機能はバイナリ自身で実行したときに正しく動作しなければなりません。「レビューを通す」ための手抜きは自己改善ループの目的を損ない、ドッグフーディングで必ず発覚します。 ### コード検索ツール(Claude Code / AI ハーネス) -リポジトリ追跡の `.claude/settings.json` で、shell のコード検索・ファイル探索系コマンドを網羅的に deny しています(`rg`、`grep`、`egrep`、`fgrep`、`zgrep`、`rgrep`、`ripgrep`、`ag`、`ack`、`ack-grep`、`git grep`、`find`、`locate`、`mlocate`、`mdfind`、`cdidx`、`~/.local/bin/cdidx`、`$HOME/.local/bin/cdidx`)。これにより Claude Code エージェントは、これらのいずれにも黙ってフォールバックできません。`~/.local/bin/cdidx` と `$HOME/.local/bin/cdidx` は Linux / macOS の `install.sh` が配置する絶対パス系の書き方(チルダ形・`$HOME` 形)を塞ぐためのエントリです。Claude Code の permission matching はテキスト一致なので、完全展開した絶対パス(例: `/Users/alice/.local/bin/cdidx`)は本設定では塞げません — その形は貢献者の運用ルールと本セクションの指針に委ねています。Cloud の Claude Code セッションはそのインストール済みバイナリに依存するため、`CLOUD_BOOTSTRAP_PROMPT.md` では該当セッションに対してワークスペース上の `.claude/settings.json` から `cdidx` 系 deny をセッション限定で削除(コミットしない)するよう案内しています。検索には組み込みの Grep / Glob ツール、または**ローカルビルドしたバイナリ**(`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`)を使ってください — グローバル版 `cdidx` は DB スキーマが古い、クエリ機能が欠けている、抽出ロジックが古くて誤った結果を返す恐れがあります。観測された Claude Code の挙動として、追跡された `deny` は `.claude/settings.local.json` の allow では上書きされません。これは公開仕様で裏を取った記述ではないため、絶対のルールではなく観測ベースの運用指針として扱い、各自の環境でも確認してください。deny されたコマンドを意図的に shell レベルで使う必要がある貢献者は、そのセッションに限りワークスペース上の `.claude/settings.json` を編集してコミットしない方式を使ってください(Cloud Bootstrap の Step 1.5 と同じ手順)。 +リポジトリ追跡の `.claude/settings.json` は、shell のコード検索・ファイル探索系コマンドに対する**ベストエフォートな deny** を提供します(`rg`、`grep`、`egrep`、`fgrep`、`zgrep`、`rgrep`、`ripgrep`、`ag`、`ack`、`ack-grep`、`git grep`、`find`、`locate`、`mlocate`、`mdfind`、`cdidx`、`~/.local/bin/cdidx`、`$HOME/.local/bin/cdidx`)。ハードな gate ではありません: Claude Code の permission matching はテキスト一致と見られるため、完全展開した絶対パス(例: `/Users/alice/.local/bin/cdidx`)や `command cdidx`、`env cdidx` など別スペルで起動する形は本ファイルでは塞げません。実際の強制ルールは本セクションの文面そのもので、検索には組み込みの Grep / Glob ツールと、ローカルビルドした `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を使ってください。deny リストは sandbox ではなく、典型的なスペルを引っ掛けるトリップワイヤとして扱います。Cloud の Claude Code セッションはそのインストール済みバイナリに依存するため、`CLOUD_BOOTSTRAP_PROMPT.md` では該当セッションに対してワークスペース上の `.claude/settings.json` から `cdidx` 系 deny をセッション限定で削除(コミットしない)するよう案内しています。検索には組み込みの Grep / Glob ツール、または**ローカルビルドしたバイナリ**(`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`)を使ってください — グローバル版 `cdidx` は DB スキーマが古い、クエリ機能が欠けている、抽出ロジックが古くて誤った結果を返す恐れがあります。観測された Claude Code の挙動として、追跡された `deny` は `.claude/settings.local.json` の allow では上書きされません。これは公開仕様で裏を取った記述ではないため、絶対のルールではなく観測ベースの運用指針として扱い、各自の環境でも確認してください。deny されたコマンドを意図的に shell レベルで使う必要がある貢献者は、そのセッションに限りワークスペース上の `.claude/settings.json` を編集してコミットしない方式を使ってください(Cloud Bootstrap の Step 1.5 と同じ手順)。 ### メソッドシグネチャの変更 メソッドの戻り値やパラメータを変更した場合(例: `BuildRecord`を`(FileRecord, string)`から`(FileRecord, string, string?)`に変更)、**同じコミットで全ての呼び出し元を更新すること**: diff --git a/README.md b/README.md index 427d06c16f..a8f0d90a0f 100644 --- a/README.md +++ b/README.md @@ -546,7 +546,7 @@ dotnet tool install -g cdidx curl -fsSL https://raw.githubusercontent.com/Widthdom/CodeIndex/main/install.sh | bash ``` -If install fails (no network, unsupported platform), skip to the **"Direct SQL queries"** section below — you can query `.cdidx/codeindex.db` directly with `sqlite3`, provided the database was already built. If neither `cdidx` nor `sqlite3` is available, fall back to `rg` (ripgrep), `grep`, `find`, and `cat` for code search. +If install fails (no network, unsupported platform), skip to the **"Direct SQL queries"** section below — you can query `.cdidx/codeindex.db` directly with `sqlite3`, provided the database was already built. If neither `cdidx` nor `sqlite3` is available, use the Claude Code built-in `Grep` / `Glob` tools (or your harness's equivalent) — do not fall back to shell `rg` / `grep` / `find` or a global `cdidx` in a Claude Code session, since those may be blocked by a repo-tracked deny list and bypassing them can hide stale-binary bugs. Before searching, update the index so results are accurate: @@ -1406,7 +1406,7 @@ dotnet tool install -g cdidx curl -fsSL https://raw.githubusercontent.com/Widthdom/CodeIndex/main/install.sh | bash ``` -インストールに失敗した場合(ネットワーク不通、未対応プラットフォーム等)は、データベースが構築済みであれば下記の **「直接SQLクエリ」** セクションで `sqlite3` から `.cdidx/codeindex.db` を直接検索できます。`cdidx` も `sqlite3` も利用できない場合は、`rg`(ripgrep)、`grep`、`find`、`cat` でコードを検索してください。 +インストールに失敗した場合(ネットワーク不通、未対応プラットフォーム等)は、データベースが構築済みであれば下記の **「直接SQLクエリ」** セクションで `sqlite3` から `.cdidx/codeindex.db` を直接検索できます。`cdidx` も `sqlite3` も利用できない場合は、Claude Code の組み込み `Grep` / `Glob` ツール(もしくは使用ハーネスの同等機能)を使ってください — Claude Code セッション内では shell の `rg` / `grep` / `find` やグローバル `cdidx` にフォールバックしないでください。これらはリポジトリ追跡の deny リストで塞がれている可能性があり、迂回すると古いバイナリ由来のバグを隠してしまうためです。 検索を始める前に、インデックスを最新化してください: From c629e99b4365cc4cdbe706b1a82eac67dbf73837 Mon Sep 17 00:00:00 2001 From: Widthdom Date: Mon, 13 Apr 2026 20:42:51 +0900 Subject: [PATCH 5/8] Cloud bootstrap: use expanded absolute path, do not dirty worktree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address Codex review #4: the previous Step 1.5 told cloud sessions to remove cdidx deny entries from the tracked .claude/settings.json for the duration of the session. That dirtied the worktree from the first step — breaking git_is_dirty as a trust signal that this repo's own README / MCP responses promote for deciding whether indexed results can be trusted — and created an obvious accidental commit path that would weaken the tripwire for every other contributor. Replace Step 1.5 with a non-mutating unblock that matches the best-effort tripwire framing: resolve the installed binary to its fully expanded absolute path once via `readlink -f "$HOME/.local/bin/cdidx"` (falling back to `realpath`), stash it in $CDIDX, and invoke every smoke-test command as "$CDIDX" .... Claude Code permission matching is textual, so the three denied spellings (cdidx, ~/.local/bin/cdidx, $HOME/.local/bin/cdidx) do not match the expanded form. Explicitly flag editing the tracked settings file as a non-recommended path and spell out the consequences. Mirror the same guidance in CLAUDE.md and the Unreleased CHANGELOG entry in both English and Japanese. Co-Authored-By: Claude Opus 4.6 (1M context) --- CHANGELOG.md | 4 +- CLAUDE.md | 4 +- CLOUD_BOOTSTRAP_PROMPT.md | 89 +++++++++++++++++++++++---------------- 3 files changed, 56 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ffd964f92..4fc7dfbe71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ### [Unreleased] #### Added -- **Tracked `.claude/settings.json` enforces cdidx-first code search for Claude Code agents** — Ship a repo-tracked Claude Code permissions file that denies the full set of code-search / file-discovery shell commands AI agents typically reach for: `Bash(rg:*)`, `Bash(grep:*)`, `Bash(egrep:*)`, `Bash(fgrep:*)`, `Bash(zgrep:*)`, `Bash(rgrep:*)`, `Bash(ripgrep:*)`, `Bash(ag:*)`, `Bash(ack:*)`, `Bash(ack-grep:*)`, `Bash(git grep:*)`, `Bash(find:*)`, `Bash(locate:*)`, `Bash(mlocate:*)`, `Bash(mdfind:*)`, and `Bash(cdidx:*)`. SELF_IMPROVEMENT.md already told contributors to use the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` instead of ripgrep / grep / the globally installed `cdidx`, but nothing enforced it at the harness level — agents could still silently fall back to whichever search tool happened to be installed, or to a stale global `cdidx` whose DB schema and extraction rules lag this branch. The new settings file turns that guidance into a hard gate so agents are forced to use the Grep / Glob built-ins or the freshly built local binary. Observed Claude Code behavior is that tracked `deny` is not overridden by `.claude/settings.local.json` allows (not confirmed against a public spec — treat as an observed workaround). Contributors who intentionally need shell-level access should edit the workspace copy of `.claude/settings.json` for that session only and not commit the change. The deny list adds `Bash(~/.local/bin/cdidx:*)` and `Bash($HOME/.local/bin/cdidx:*)` to cover the tilde- and `$HOME`-spelled absolute paths used by `install.sh` on Linux / macOS. CLAUDE.md, README, and this entry are reframed to describe the deny list as a **best-effort tripwire** rather than a hard guard: fully expanded absolute paths (e.g. `/Users/alice/.local/bin/cdidx`), `command cdidx`, `env cdidx`, and similar alternate spellings are not blocked because Claude Code permission matching is textual. The authoritative rule remains the written guidance (use Grep / Glob built-ins and the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`). README's `# Code Search Rules` template is updated in both languages so the last-resort fallback no longer tells Claude Code sessions to run shell `rg` / `grep` / `find` — it points at built-in Grep / Glob instead. `CLOUD_BOOTSTRAP_PROMPT.md` gains a Step 1.5 instructing cloud sessions to strip the `cdidx` deny entries from the workspace copy of `.claude/settings.json` (session-local, uncommitted) so the installed binary remains usable in SDK-less containers. Affected: `.claude/settings.json`, `CLOUD_BOOTSTRAP_PROMPT.md`, `CLAUDE.md`. +- **Tracked `.claude/settings.json` enforces cdidx-first code search for Claude Code agents** — Ship a repo-tracked Claude Code permissions file that denies the full set of code-search / file-discovery shell commands AI agents typically reach for: `Bash(rg:*)`, `Bash(grep:*)`, `Bash(egrep:*)`, `Bash(fgrep:*)`, `Bash(zgrep:*)`, `Bash(rgrep:*)`, `Bash(ripgrep:*)`, `Bash(ag:*)`, `Bash(ack:*)`, `Bash(ack-grep:*)`, `Bash(git grep:*)`, `Bash(find:*)`, `Bash(locate:*)`, `Bash(mlocate:*)`, `Bash(mdfind:*)`, and `Bash(cdidx:*)`. SELF_IMPROVEMENT.md already told contributors to use the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` instead of ripgrep / grep / the globally installed `cdidx`, but nothing enforced it at the harness level — agents could still silently fall back to whichever search tool happened to be installed, or to a stale global `cdidx` whose DB schema and extraction rules lag this branch. The new settings file turns that guidance into a hard gate so agents are forced to use the Grep / Glob built-ins or the freshly built local binary. Observed Claude Code behavior is that tracked `deny` is not overridden by `.claude/settings.local.json` allows (not confirmed against a public spec — treat as an observed workaround). Contributors who intentionally need shell-level access should edit the workspace copy of `.claude/settings.json` for that session only and not commit the change. The deny list adds `Bash(~/.local/bin/cdidx:*)` and `Bash($HOME/.local/bin/cdidx:*)` to cover the tilde- and `$HOME`-spelled absolute paths used by `install.sh` on Linux / macOS. CLAUDE.md, README, and this entry are reframed to describe the deny list as a **best-effort tripwire** rather than a hard guard: fully expanded absolute paths (e.g. `/Users/alice/.local/bin/cdidx`), `command cdidx`, `env cdidx`, and similar alternate spellings are not blocked because Claude Code permission matching is textual. The authoritative rule remains the written guidance (use Grep / Glob built-ins and the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`). README's `# Code Search Rules` template is updated in both languages so the last-resort fallback no longer tells Claude Code sessions to run shell `rg` / `grep` / `find` — it points at built-in Grep / Glob instead. `CLOUD_BOOTSTRAP_PROMPT.md` gains a Step 1.5 instructing cloud sessions to invoke the installed binary via its fully expanded absolute path (`readlink -f "$HOME/.local/bin/cdidx"`), which the tripwire's textual matching does not catch. Editing the tracked `.claude/settings.json` is explicitly rejected in that step because it would dirty the worktree (breaking `git_is_dirty` as a trust signal) and risk an accidental commit that weakens the tripwire for every other contributor. Affected: `.claude/settings.json`, `CLOUD_BOOTSTRAP_PROMPT.md`, `CLAUDE.md`. - **`--exact` extended to `definition` / `references` / `callers` / `callees` / `inspect` (#83)** — The case-insensitive exact-match semantic introduced in #81 now also applies to `cdidx definition`, `cdidx references`, `cdidx callers`, `cdidx callees`, `cdidx inspect`, and their MCP tool counterparts (`analyze_symbol` included) via an `exact` boolean. `inspect` / `analyze_symbol` propagates `exact` into every bundled sub-query (definitions, references, callers, callees) so the one-round-trip AI workflow keeps the same precision contract as the leaf commands — `inspect Run --exact` no longer pulls `RunAsync` / `RunImpact` into the bundled response. Predicates use `s.name = @q COLLATE NOCASE` / `r.symbol_name = @q COLLATE NOCASE` / `r.container_name = @q COLLATE NOCASE`, backed by new `idx_symbol_refs_name_nocase` and `idx_symbol_refs_container_nocase` covering indexes on `symbol_references` so multi-exact lookups stay SARGable. Closes the round-trip gap where an AI client had `symbols --exact` for name resolution but still had to fall back to substring matching for the follow-up definition / reference / call graph calls. ASCII-only NOCASE limitation from #81 still applies (non-ASCII casing is not folded; Unicode folding tracked in #86). Affected: `src/CodeIndex/Database/DbReader.cs`, `src/CodeIndex/Database/DbSymbolReader.cs`, `src/CodeIndex/Database/DbContext.cs`, `src/CodeIndex/Cli/QueryCommandRunner.cs`, `src/CodeIndex/Cli/ConsoleUi.cs`, `src/CodeIndex/Mcp/McpToolDefinitions.cs`, `src/CodeIndex/Mcp/McpToolHandlers.cs`, `tests/CodeIndex.Tests/DbReaderTests.cs`, `README.md`, `CLAUDE.md`. Closes #83. - **`--exact` on `symbols` for precise name resolution (#81)** — `cdidx symbols` and MCP `symbols` now accept `--exact` / `exact: true` to match symbol names by case-insensitive equality instead of `LIKE %...%` substring. When AI clients pass a resolved candidate list from an earlier `map` / `inspect` / `search` call, querying `Run` no longer also returns `RunAsync`, `RunImpact`, etc., saving a client-side filter pass and reducing token output. Composes with repeated `--name` / positional names (OR-joined per-name equality), and with all existing filters (`--kind`, `--lang`, `--path`, `--exclude-path`, `--exclude-tests`, `--since`, `--limit`). Default behavior (substring) is unchanged. The exact-match predicate uses `s.name = @q COLLATE NOCASE` (not `lower(col) = lower(@q)`) backed by a new `idx_symbols_name_nocase` covering index so multi-name exact lookups stay O(log n) per name instead of a full-table scan. Case-insensitivity follows SQLite's `NOCASE` collation (ASCII only) — non-ASCII casing pairs such as `Ä` / `ä` are not folded; pass the exact casing for non-ASCII identifiers. Unicode folding is tracked in #86. Affected: `src/CodeIndex/Database/DbSymbolReader.cs`, `src/CodeIndex/Database/DbContext.cs`, `src/CodeIndex/Cli/QueryCommandRunner.cs`, `src/CodeIndex/Cli/ConsoleUi.cs`, `src/CodeIndex/Mcp/McpToolDefinitions.cs`, `src/CodeIndex/Mcp/McpToolHandlers.cs`, `tests/CodeIndex.Tests/DbReaderTests.cs`, `README.md`. Closes #81. - **Multi-name `symbols` query (#69)** — `symbols` now accepts multiple names in a single call so AI clients can resolve a candidate list without issuing one command per name. Supported forms: repeatable positional (`cdidx symbols A B C`) and repeatable `--name` flag (`--name A --name B`). Names are OR-joined server-side with per-name candidate fetch + round-robin merge under the user's `--limit` cap (so a popular name cannot starve others, and `--limit` still bounds total results). `|` is treated as a literal name character so operator symbols such as `operator |` remain searchable. All existing filters (`--kind`, `--lang`, `--path`, `--exclude-tests`, `--since`) still apply, and MCP `symbols` gains a parallel `names` array. Fully additive — single-name calls behave identically. Affected: `src/CodeIndex/Cli/QueryCommandRunner.cs`, `src/CodeIndex/Database/DbSymbolReader.cs`, `src/CodeIndex/Mcp/McpToolHandlers.cs`, `src/CodeIndex/Mcp/McpToolDefinitions.cs`, `tests/CodeIndex.Tests/DbReaderTests.cs`, `README.md`. Closes #69. @@ -601,7 +601,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ### [Unreleased] #### 追加 -- **リポジトリ追跡の `.claude/settings.json` で cdidx 最優先のコード検索を強制** — AI エージェントが代用しがちなコード検索/ファイル探索系のシェルコマンドを網羅的に deny するリポジトリ追跡版 Claude Code 権限ファイルを追加(`Bash(rg:*)`、`Bash(grep:*)`、`Bash(egrep:*)`、`Bash(fgrep:*)`、`Bash(zgrep:*)`、`Bash(rgrep:*)`、`Bash(ripgrep:*)`、`Bash(ag:*)`、`Bash(ack:*)`、`Bash(ack-grep:*)`、`Bash(git grep:*)`、`Bash(find:*)`、`Bash(locate:*)`、`Bash(mlocate:*)`、`Bash(mdfind:*)`、`Bash(cdidx:*)`)。SELF_IMPROVEMENT.md では「ripgrep / grep / グローバル `cdidx` ではなく、ローカルビルドした `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を使う」ルールを既に定義していたが、harness レベルで強制する仕組みが無く、エージェントが黙ってインストール済みの検索ツールや、ブランチ差分を反映しない古い DB スキーマ・抽出ルールのグローバル `cdidx` にフォールバックできてしまっていた。この設定ファイルで、そのガイドラインをハード gate に昇格し、Grep / Glob 組み込みツールか新しくビルドしたローカルバイナリの使用を強制する。観測された Claude Code の挙動として、追跡された `deny` は `.claude/settings.local.json` の allow では上書きされない(公開仕様で裏を取った記述ではないため、観測ベースの運用指針として扱う)。shell レベルで使いたい貢献者は、そのセッションに限りワークスペース上の `.claude/settings.json` を編集してコミットしない運用を取ること。deny リストには Linux / macOS の `install.sh` が配置する絶対パス系(チルダ形・`$HOME` 形)を塞ぐ `Bash(~/.local/bin/cdidx:*)` と `Bash($HOME/.local/bin/cdidx:*)` を追加する。CLAUDE.md、README、および本エントリを再構成し、deny リストはハードな gate ではなく**ベストエフォートのトリップワイヤ**として位置づけ直した: Claude Code の permission matching はテキスト一致のため、完全展開絶対パス(例: `/Users/alice/.local/bin/cdidx`)、`command cdidx`、`env cdidx` などの別スペルは塞げない。強制ルールの本体は文面そのもの(組み込み Grep / Glob とローカルビルドの `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を使う)。README の `# コードベース検索ルール` テンプレートも英日両方で更新し、最終手段のフォールバックが Claude Code セッションで shell `rg` / `grep` / `find` を使うよう促さないようにした(代わりに組み込み Grep / Glob を案内)。`CLOUD_BOOTSTRAP_PROMPT.md` に Step 1.5 を追加し、Cloud セッションではワークスペース上の `.claude/settings.json` から `cdidx` 系 deny をセッション限定で削除(コミットしない)する運用を明記した。SDK のないコンテナでもインストール済みバイナリを使える状態を保つため。対象: `.claude/settings.json`、`CLOUD_BOOTSTRAP_PROMPT.md`、`CLAUDE.md`。 +- **リポジトリ追跡の `.claude/settings.json` で cdidx 最優先のコード検索を強制** — AI エージェントが代用しがちなコード検索/ファイル探索系のシェルコマンドを網羅的に deny するリポジトリ追跡版 Claude Code 権限ファイルを追加(`Bash(rg:*)`、`Bash(grep:*)`、`Bash(egrep:*)`、`Bash(fgrep:*)`、`Bash(zgrep:*)`、`Bash(rgrep:*)`、`Bash(ripgrep:*)`、`Bash(ag:*)`、`Bash(ack:*)`、`Bash(ack-grep:*)`、`Bash(git grep:*)`、`Bash(find:*)`、`Bash(locate:*)`、`Bash(mlocate:*)`、`Bash(mdfind:*)`、`Bash(cdidx:*)`)。SELF_IMPROVEMENT.md では「ripgrep / grep / グローバル `cdidx` ではなく、ローカルビルドした `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を使う」ルールを既に定義していたが、harness レベルで強制する仕組みが無く、エージェントが黙ってインストール済みの検索ツールや、ブランチ差分を反映しない古い DB スキーマ・抽出ルールのグローバル `cdidx` にフォールバックできてしまっていた。この設定ファイルで、そのガイドラインをハード gate に昇格し、Grep / Glob 組み込みツールか新しくビルドしたローカルバイナリの使用を強制する。観測された Claude Code の挙動として、追跡された `deny` は `.claude/settings.local.json` の allow では上書きされない(公開仕様で裏を取った記述ではないため、観測ベースの運用指針として扱う)。shell レベルで使いたい貢献者は、そのセッションに限りワークスペース上の `.claude/settings.json` を編集してコミットしない運用を取ること。deny リストには Linux / macOS の `install.sh` が配置する絶対パス系(チルダ形・`$HOME` 形)を塞ぐ `Bash(~/.local/bin/cdidx:*)` と `Bash($HOME/.local/bin/cdidx:*)` を追加する。CLAUDE.md、README、および本エントリを再構成し、deny リストはハードな gate ではなく**ベストエフォートのトリップワイヤ**として位置づけ直した: Claude Code の permission matching はテキスト一致のため、完全展開絶対パス(例: `/Users/alice/.local/bin/cdidx`)、`command cdidx`、`env cdidx` などの別スペルは塞げない。強制ルールの本体は文面そのもの(組み込み Grep / Glob とローカルビルドの `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を使う)。README の `# コードベース検索ルール` テンプレートも英日両方で更新し、最終手段のフォールバックが Claude Code セッションで shell `rg` / `grep` / `find` を使うよう促さないようにした(代わりに組み込み Grep / Glob を案内)。`CLOUD_BOOTSTRAP_PROMPT.md` に Step 1.5 を追加し、Cloud セッションはインストール済みバイナリを完全展開した絶対パス(`readlink -f "$HOME/.local/bin/cdidx"`)経由で呼び出す運用を明記した — tripwire のテキスト一致はその形を塞げない。追跡対象の `.claude/settings.json` を編集する案は同じ Step で明示的に非推奨とした: worktree が dirty になり `git_is_dirty` の信頼指標性が失われ、誤コミットで全貢献者向けの tripwire を弱めるリスクがあるため。対象: `.claude/settings.json`、`CLOUD_BOOTSTRAP_PROMPT.md`、`CLAUDE.md`。 - **`--exact` を `definition` / `references` / `callers` / `callees` / `inspect` にも拡張 (#83)** — #81 で symbols に入れた大文字小文字無視の完全一致セマンティクスを、`cdidx definition`、`cdidx references`、`cdidx callers`、`cdidx callees`、`cdidx inspect` と対応する MCP ツール(`analyze_symbol` を含む)にも `exact` boolean として展開。`inspect` / `analyze_symbol` は bundle 内の全 sub-query(定義、参照、caller、callee)に `exact` を伝播するため、一発解決の AI ワークフローも leaf コマンドと同じ precision contract を維持する — `inspect Run --exact` が `RunAsync` / `RunImpact` を含んだ bundle を返すことは無い。述語は `s.name = @q COLLATE NOCASE` / `r.symbol_name = @q COLLATE NOCASE` / `r.container_name = @q COLLATE NOCASE` を使い、新規の `idx_symbol_refs_name_nocase` / `idx_symbol_refs_container_nocase` covering index を貼ることで multi-exact 検索も SARGable に保つ。AI クライアントが `symbols --exact` で名前を解決した後、definition / reference / call graph の追撃で substring に戻らざるを得なかった往復ロスを解消する。#81 の ASCII NOCASE 限定は引き続き適用される(非 ASCII の casing は畳み込まれず、Unicode fold は #86 で追跡)。対象: `src/CodeIndex/Database/DbReader.cs`、`src/CodeIndex/Database/DbSymbolReader.cs`、`src/CodeIndex/Database/DbContext.cs`、`src/CodeIndex/Cli/QueryCommandRunner.cs`、`src/CodeIndex/Cli/ConsoleUi.cs`、`src/CodeIndex/Mcp/McpToolDefinitions.cs`、`src/CodeIndex/Mcp/McpToolHandlers.cs`、`tests/CodeIndex.Tests/DbReaderTests.cs`、`README.md`、`CLAUDE.md`。Closes #83. - **`symbols` に `--exact` を追加し名前の正確な解決を可能に (#81)** — `cdidx symbols` と MCP の `symbols` が `--exact` / `exact: true` を受け付け、`LIKE %...%` の部分一致ではなく大文字小文字を無視した名前の完全一致で検索するようになった。AI クライアントが先行の `map` / `inspect` / `search` 結果から解決済みの候補リストを渡す場合、`Run` を指定しても `RunAsync` / `RunImpact` 等に広がらないため、クライアント側での後段フィルタが不要になりトークン出力も減る。繰り返しの `--name` や positional 名と組み合わせれば名前ごとの完全一致を OR 結合でき、既存フィルタ(`--kind`、`--lang`、`--path`、`--exclude-path`、`--exclude-tests`、`--since`、`--limit`)もそのまま適用される。既定挙動(部分一致)は変わらない。完全一致述語は `lower(col) = lower(@q)` ではなく `s.name = @q COLLATE NOCASE` を使い、新規の `idx_symbols_name_nocase` covering index を貼ることで multi-name exact 時にもフルスキャンにならず O(log n) × 名前数で解決する。大文字小文字無視は SQLite の `NOCASE`(ASCII 限定)に従うため、`Ä` / `ä` のような非 ASCII の casing 差分は畳み込まれない — 非 ASCII 識別子はインデックス時と同じ casing を渡すこと。Unicode fold の対応は #86 で追跡。対象: `src/CodeIndex/Database/DbSymbolReader.cs`、`src/CodeIndex/Database/DbContext.cs`、`src/CodeIndex/Cli/QueryCommandRunner.cs`、`src/CodeIndex/Cli/ConsoleUi.cs`、`src/CodeIndex/Mcp/McpToolDefinitions.cs`、`src/CodeIndex/Mcp/McpToolHandlers.cs`、`tests/CodeIndex.Tests/DbReaderTests.cs`、`README.md`。Closes #81. - **`symbols` の複数名クエリ (#69)** — `symbols` が 1 回の呼び出しで複数のシンボル名を解決できるようになり、AI クライアントが候補リストをコマンドごとに分けて問い合わせる必要がなくなった。対応形式: 繰り返しの positional(`cdidx symbols A B C`)、繰り返しの `--name` フラグ(`--name A --name B`)。名前はサーバー側で OR 結合され、名前ごとの候補取得 + round-robin マージを `--limit` の範囲内で行うため、人気名が他を押し出すことなく `--limit` は従来どおり合計の上限として働く。`|` はシンボル名の文字として扱うので `operator |` のような演算子シンボルも検索可能。既存フィルタ(`--kind`、`--lang`、`--path`、`--exclude-tests`、`--since`)はそのまま適用される。MCP の `symbols` にも `names` 配列を追加。単一名呼び出しは従来どおり動作する完全な追加変更。対象: `src/CodeIndex/Cli/QueryCommandRunner.cs`、`src/CodeIndex/Database/DbSymbolReader.cs`、`src/CodeIndex/Mcp/McpToolHandlers.cs`、`src/CodeIndex/Mcp/McpToolDefinitions.cs`、`tests/CodeIndex.Tests/DbReaderTests.cs`、`README.md`。Closes #69. diff --git a/CLAUDE.md b/CLAUDE.md index 00a0efe6a5..cf7402173c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -175,7 +175,7 @@ The only production dependency is **Microsoft.Data.Sqlite** — keep it that way Code review uses the **locally built binary** from the current commit (`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`) to search and verify the codebase. This means the reviewer sees exactly what the code actually does — not what tests claim it does, not what documentation says it does, but what the running binary produces. **It is strictly forbidden to intentionally implement incomplete, hollow, or deceptive code that passes tests or review on paper but fails in practice.** Every feature must work correctly when exercised by the binary itself. Cutting corners to "pass review" defeats the purpose of the self-improvement loop and will be caught by dogfooding. ### Code search tools (Claude Code / AI harnesses) -Repo-tracked `.claude/settings.json` provides **best-effort** denial of shell code-search and file-discovery commands (`rg`, `grep`, `egrep`, `fgrep`, `zgrep`, `rgrep`, `ripgrep`, `ag`, `ack`, `ack-grep`, `git grep`, `find`, `locate`, `mlocate`, `mdfind`, `cdidx`, `~/.local/bin/cdidx`, `$HOME/.local/bin/cdidx`). This is not a hard guard: Claude Code permission matching appears to be textual, so fully expanded absolute paths (e.g. `/Users/alice/.local/bin/cdidx`), `command cdidx`, `env cdidx`, and similar alternate spellings are not blocked by this file. The authoritative rule is the written guidance in this section — use the built-in Grep / Glob tools and the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`; the deny list is a tripwire that catches the common spellings, not a sandbox. Cloud Claude Code sessions rely on that installed binary, so `CLOUD_BOOTSTRAP_PROMPT.md` instructs those sessions to strip the `cdidx` deny entries from the workspace copy of `.claude/settings.json` (session-local, uncommitted). Use the built-in Grep / Glob tools and the **locally built binary** (`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`) for searches — the global `cdidx` may have an older DB schema, missing query features, or stale extraction logic that silently returns wrong results. Observed Claude Code behavior: tracked `deny` entries are not overridden by `.claude/settings.local.json` allows. This is not cited from a public spec, so treat it as an observed workaround rather than a guaranteed rule — verify in your own environment before relying on it. Contributors who intentionally need shell-level access to a denied command should edit the workspace copy of `.claude/settings.json` for that session only and not commit the change (same mechanism as the Cloud Bootstrap Step 1.5). +Repo-tracked `.claude/settings.json` provides **best-effort** denial of shell code-search and file-discovery commands (`rg`, `grep`, `egrep`, `fgrep`, `zgrep`, `rgrep`, `ripgrep`, `ag`, `ack`, `ack-grep`, `git grep`, `find`, `locate`, `mlocate`, `mdfind`, `cdidx`, `~/.local/bin/cdidx`, `$HOME/.local/bin/cdidx`). This is not a hard guard: Claude Code permission matching appears to be textual, so fully expanded absolute paths (e.g. `/Users/alice/.local/bin/cdidx`), `command cdidx`, `env cdidx`, and similar alternate spellings are not blocked by this file. The authoritative rule is the written guidance in this section — use the built-in Grep / Glob tools and the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`; the deny list is a tripwire that catches the common spellings, not a sandbox. Cloud Claude Code sessions rely on that installed binary, so `CLOUD_BOOTSTRAP_PROMPT.md` instructs those sessions to invoke it via the fully expanded absolute path (`readlink -f "$HOME/.local/bin/cdidx"`) — the tripwire's textual matching does not catch that form. Editing the tracked `.claude/settings.json` is explicitly not the recommended path, since it dirties the worktree and risks an accidental commit that weakens the tripwire for everyone else. Use the built-in Grep / Glob tools and the **locally built binary** (`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`) for searches — the global `cdidx` may have an older DB schema, missing query features, or stale extraction logic that silently returns wrong results. Observed Claude Code behavior: tracked `deny` entries are not overridden by `.claude/settings.local.json` allows. This is not cited from a public spec, so treat it as an observed workaround rather than a guaranteed rule — verify in your own environment before relying on it. Contributors who intentionally need shell-level access to a denied command should edit the workspace copy of `.claude/settings.json` for that session only and not commit the change (same mechanism as the Cloud Bootstrap Step 1.5). ### Method signature changes When changing a method's return type or parameters (e.g. `BuildRecord` from `(FileRecord, string)` to `(FileRecord, string, string?)`), **update ALL callers** in the same commit: @@ -417,7 +417,7 @@ tests/CodeIndex.Tests/ コードレビューは現在のコミットから**ローカルビルドしたバイナリ**(`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`)を使ってコードベースを検索・検証します。つまりレビュアーは、テストが主張する動作でもドキュメントが述べる動作でもなく、実行中のバイナリが実際に出す結果を見ます。**テストやレビューを表面上パスするが実際には動作しない、不完全・中身のない・欺瞞的なコードを意図的に実装することは厳禁です。** すべての機能はバイナリ自身で実行したときに正しく動作しなければなりません。「レビューを通す」ための手抜きは自己改善ループの目的を損ない、ドッグフーディングで必ず発覚します。 ### コード検索ツール(Claude Code / AI ハーネス) -リポジトリ追跡の `.claude/settings.json` は、shell のコード検索・ファイル探索系コマンドに対する**ベストエフォートな deny** を提供します(`rg`、`grep`、`egrep`、`fgrep`、`zgrep`、`rgrep`、`ripgrep`、`ag`、`ack`、`ack-grep`、`git grep`、`find`、`locate`、`mlocate`、`mdfind`、`cdidx`、`~/.local/bin/cdidx`、`$HOME/.local/bin/cdidx`)。ハードな gate ではありません: Claude Code の permission matching はテキスト一致と見られるため、完全展開した絶対パス(例: `/Users/alice/.local/bin/cdidx`)や `command cdidx`、`env cdidx` など別スペルで起動する形は本ファイルでは塞げません。実際の強制ルールは本セクションの文面そのもので、検索には組み込みの Grep / Glob ツールと、ローカルビルドした `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を使ってください。deny リストは sandbox ではなく、典型的なスペルを引っ掛けるトリップワイヤとして扱います。Cloud の Claude Code セッションはそのインストール済みバイナリに依存するため、`CLOUD_BOOTSTRAP_PROMPT.md` では該当セッションに対してワークスペース上の `.claude/settings.json` から `cdidx` 系 deny をセッション限定で削除(コミットしない)するよう案内しています。検索には組み込みの Grep / Glob ツール、または**ローカルビルドしたバイナリ**(`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`)を使ってください — グローバル版 `cdidx` は DB スキーマが古い、クエリ機能が欠けている、抽出ロジックが古くて誤った結果を返す恐れがあります。観測された Claude Code の挙動として、追跡された `deny` は `.claude/settings.local.json` の allow では上書きされません。これは公開仕様で裏を取った記述ではないため、絶対のルールではなく観測ベースの運用指針として扱い、各自の環境でも確認してください。deny されたコマンドを意図的に shell レベルで使う必要がある貢献者は、そのセッションに限りワークスペース上の `.claude/settings.json` を編集してコミットしない方式を使ってください(Cloud Bootstrap の Step 1.5 と同じ手順)。 +リポジトリ追跡の `.claude/settings.json` は、shell のコード検索・ファイル探索系コマンドに対する**ベストエフォートな deny** を提供します(`rg`、`grep`、`egrep`、`fgrep`、`zgrep`、`rgrep`、`ripgrep`、`ag`、`ack`、`ack-grep`、`git grep`、`find`、`locate`、`mlocate`、`mdfind`、`cdidx`、`~/.local/bin/cdidx`、`$HOME/.local/bin/cdidx`)。ハードな gate ではありません: Claude Code の permission matching はテキスト一致と見られるため、完全展開した絶対パス(例: `/Users/alice/.local/bin/cdidx`)や `command cdidx`、`env cdidx` など別スペルで起動する形は本ファイルでは塞げません。実際の強制ルールは本セクションの文面そのもので、検索には組み込みの Grep / Glob ツールと、ローカルビルドした `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を使ってください。deny リストは sandbox ではなく、典型的なスペルを引っ掛けるトリップワイヤとして扱います。Cloud の Claude Code セッションはそのインストール済みバイナリに依存するため、`CLOUD_BOOTSTRAP_PROMPT.md` では完全展開した絶対パス(`readlink -f "$HOME/.local/bin/cdidx"`)経由での呼び出しを案内しています — tripwire のテキスト一致はその形を塞げないためパーミッション編集が不要です。追跡対象の `.claude/settings.json` を編集する手順は推奨しません: worktree が dirty になり誤コミットで全貢献者向けの tripwire を弱めてしまうからです。検索には組み込みの Grep / Glob ツール、または**ローカルビルドしたバイナリ**(`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`)を使ってください — グローバル版 `cdidx` は DB スキーマが古い、クエリ機能が欠けている、抽出ロジックが古くて誤った結果を返す恐れがあります。観測された Claude Code の挙動として、追跡された `deny` は `.claude/settings.local.json` の allow では上書きされません。これは公開仕様で裏を取った記述ではないため、絶対のルールではなく観測ベースの運用指針として扱い、各自の環境でも確認してください。deny されたコマンドを意図的に shell レベルで使う必要がある貢献者は、そのセッションに限りワークスペース上の `.claude/settings.json` を編集してコミットしない方式を使ってください(Cloud Bootstrap の Step 1.5 と同じ手順)。 ### メソッドシグネチャの変更 メソッドの戻り値やパラメータを変更した場合(例: `BuildRecord`を`(FileRecord, string)`から`(FileRecord, string, string?)`に変更)、**同じコミットで全ての呼び出し元を更新すること**: diff --git a/CLOUD_BOOTSTRAP_PROMPT.md b/CLOUD_BOOTSTRAP_PROMPT.md index 3e0c6fcfd2..f40941f188 100644 --- a/CLOUD_BOOTSTRAP_PROMPT.md +++ b/CLOUD_BOOTSTRAP_PROMPT.md @@ -34,21 +34,28 @@ copies the binary **plus the adjacent runtime assets** (`version.json` and library is loaded via P/Invoke from the binary's directory, and `version.json` is what `cdidx --version` reads. -### Step 1.5 — Unblock `cdidx` in this session's permissions +### Step 1.5 — Invoke `cdidx` via its fully expanded absolute path The repo-tracked `.claude/settings.json` denies `Bash(cdidx:*)`, -`Bash(~/.local/bin/cdidx:*)`, and `Bash($HOME/.local/bin/cdidx:*)` to -keep local sessions from silently falling back to a stale global binary. -In this container those denies would block every smoke-test command -below. Observed Claude Code behavior is that tracked `deny` is not -overridden by `settings.local.json` allows (not confirmed against a -public spec — verify if your environment behaves differently). The -workaround that has been observed to work is to remove those `cdidx` -entries from the **workspace copy** of `.claude/settings.json` and -**do not commit the change**. It is a session-local unblock, not a -repo edit. If your Claude Code build honors `settings.local.json` -allow-overrides, an untracked `.claude/settings.local.json` with the -matching allow lines is an equivalent alternative. +`Bash(~/.local/bin/cdidx:*)`, and `Bash($HOME/.local/bin/cdidx:*)` as a +**best-effort tripwire** (see `CLAUDE.md`) against local sessions that +would silently fall back to a stale global binary. Claude Code +permission matching is textual, so invoking the installed binary via +its fully expanded absolute path is not matched by any of those three +entries and is therefore allowed without any permission edit. Resolve +the path once and reuse it for every step below: + +```bash +CDIDX="$(readlink -f "$HOME/.local/bin/cdidx" 2>/dev/null || realpath "$HOME/.local/bin/cdidx")" +# Sanity check: must print an expanded absolute path (e.g. /root/.local/bin/cdidx). +echo "$CDIDX" +``` + +Do **not** edit the tracked `.claude/settings.json` to bypass the +tripwire. Doing so dirties the worktree (breaking `git_is_dirty` as a +trust signal for `status`/`inspect`) and risks an accidental commit +that weakens the tripwire for every other contributor. The expanded +absolute path is the intended, non-mutating unblock. ### Step 2 — Smoke test the installed binary end-to-end @@ -57,11 +64,11 @@ failure is your highest-priority improvement target — every new user is hitting the same wall. ```bash -cdidx --version # must print a real version, v0.0.0 is NG -cdidx . --db /tmp/smoke.db # SQLite write path (human output) -cdidx status --db /tmp/smoke.db # SQLite read path -cdidx search "install" --path install.sh --snippet-lines 4 --db /tmp/smoke.db -echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | cdidx mcp +"$CDIDX" --version # must print a real version, v0.0.0 is NG +"$CDIDX" . --db /tmp/smoke.db # SQLite write path (human output) +"$CDIDX" status --db /tmp/smoke.db # SQLite read path +"$CDIDX" search "install" --path install.sh --snippet-lines 4 --db /tmp/smoke.db +echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | "$CDIDX" mcp ``` If `cdidx --version` reports `v0.0.0`, `version.json` is missing next to the @@ -156,22 +163,30 @@ export PATH="$HOME/.local/bin:$PATH" ライブラリはバイナリのディレクトリから P/Invoke でロードされ、 `version.json` は `cdidx --version` が読むファイルです。 -### Step 1.5 — このセッションの permissions で `cdidx` を通す +### Step 1.5 — `cdidx` は完全展開した絶対パスで呼び出す -リポジトリ追跡の `.claude/settings.json` は、ローカルセッションが古い -グローバルバイナリに黙ってフォールバックしないよう +リポジトリ追跡の `.claude/settings.json` は、ローカルセッションが +古いグローバルバイナリに黙ってフォールバックしないよう `Bash(cdidx:*)`、`Bash(~/.local/bin/cdidx:*)`、 -`Bash($HOME/.local/bin/cdidx:*)` を deny しています。このコンテナでは -その deny が以降のスモークテストを全部ブロックします。観測された -Claude Code の挙動として、追跡された `deny` は `settings.local.json` -の allow では上書きされません(公開仕様で裏を取った記述ではないため、 -環境が異なる場合は各自で確認してください)。観測済みに機能する回避策は -**ワークスペース上の** `.claude/settings.json` から `cdidx` 系の -エントリを削除し、**その変更をコミットしない**ことです。リポジトリへの -修正ではなくセッション限定の一時解除として扱ってください。もし -お使いの Claude Code ビルドで `settings.local.json` の allow が -deny を上書きできるのであれば、追跡外の `.claude/settings.local.json` -に該当の allow を追加する方法も同等に使えます。 +`Bash($HOME/.local/bin/cdidx:*)` を **best-effort tripwire** として +deny しています(詳細は `CLAUDE.md`)。Claude Code の permission +matching はテキスト一致なので、インストール済みバイナリを**完全展開した +絶対パス**で起動すればこの 3 エントリとは一致せず、パーミッション編集 +なしに通ります。以下のように 1 回だけパスを解決し、以降の手順で +使い回してください: + +```bash +CDIDX="$(readlink -f "$HOME/.local/bin/cdidx" 2>/dev/null || realpath "$HOME/.local/bin/cdidx")" +# 念のため確認: 展開された絶対パス(例: /root/.local/bin/cdidx)が出るはず +echo "$CDIDX" +``` + +追跡対象の `.claude/settings.json` を編集して tripwire を外す +運用は**取らないでください**。worktree が dirty になり +`status` / `inspect` の信頼指標である `git_is_dirty` が +意味を失い、さらに誤ってコミットすれば全貢献者向けの +tripwire を弱めてしまいます。完全展開絶対パスでの呼び出しが、 +編集を伴わない正規の回避手順です。 ### Step 2 — インストール済みバイナリをエンドツーエンドでスモーク @@ -180,11 +195,11 @@ deny を上書きできるのであれば、追跡外の `.claude/settings.local いる証拠です。 ```bash -cdidx --version # 実バージョンが出ること。v0.0.0 は NG -cdidx . --db /tmp/smoke.db # SQLite 書き込み経路(人間向け出力) -cdidx status --db /tmp/smoke.db # SQLite 読み取り経路 -cdidx search "install" --path install.sh --snippet-lines 4 --db /tmp/smoke.db -echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | cdidx mcp +"$CDIDX" --version # 実バージョンが出ること。v0.0.0 は NG +"$CDIDX" . --db /tmp/smoke.db # SQLite 書き込み経路(人間向け出力) +"$CDIDX" status --db /tmp/smoke.db # SQLite 読み取り経路 +"$CDIDX" search "install" --path install.sh --snippet-lines 4 --db /tmp/smoke.db +echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | "$CDIDX" mcp ``` `cdidx --version` が `v0.0.0` を返すなら、バイナリの隣に `version.json` が From 5eb1bcb105985f6ebb5017902952a1d72ab40502 Mon Sep 17 00:00:00 2001 From: Widthdom Date: Mon, 13 Apr 2026 20:48:40 +0900 Subject: [PATCH 6/8] Cloud bootstrap Step 3: use \$CDIDX for incremental reindex too The previous commit routed Step 2 through the fully expanded absolute path via \$CDIDX but left the Step 3 incremental-reindex examples as raw 'cdidx . --files ...' / 'cdidx . --commits HEAD' in both the English and Japanese sections. Those raw spellings are matched by the tracked Bash(cdidx:*) deny, so a cloud session following the bootstrap would pass Step 2 and then dead-end on the first reindex. Route the Step 3 examples through \$CDIDX so the non-mutating unblock is end-to-end usable. Co-Authored-By: Claude Opus 4.6 (1M context) --- CLOUD_BOOTSTRAP_PROMPT.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CLOUD_BOOTSTRAP_PROMPT.md b/CLOUD_BOOTSTRAP_PROMPT.md index f40941f188..0bcf54c6bf 100644 --- a/CLOUD_BOOTSTRAP_PROMPT.md +++ b/CLOUD_BOOTSTRAP_PROMPT.md @@ -103,8 +103,8 @@ structured responses. repo, never to "verify" an unreleased source edit. - Incremental reindex after edits: ```bash - cdidx . --files [ ...] # or - cdidx . --commits HEAD + "$CDIDX" . --files [ ...] # or + "$CDIDX" . --commits HEAD ``` - Read `SELF_IMPROVEMENT.md` and follow its loop, but substitute the rebuild / reindex steps above for anything that assumes a local SDK. @@ -234,8 +234,8 @@ source-gen JSON 問題が解決するまでは、デフォルトの人間向け 使えますが、未リリースのソース変更の「検証」には使えません。 - 編集後のインクリメンタル再インデックス: ```bash - cdidx . --files <変更ファイル> [<変更ファイル> ...] # または - cdidx . --commits HEAD + "$CDIDX" . --files <変更ファイル> [<変更ファイル> ...] # または + "$CDIDX" . --commits HEAD ``` - `SELF_IMPROVEMENT.md` を読み、そのループに従う。ただし、ローカル SDK を 前提としている再ビルド / 再インデックス手順は上記で読み替える。 From 5c3c7d500649cc4c260d6548c86af4be8afefd99 Mon Sep 17 00:00:00 2001 From: Widthdom Date: Mon, 13 Apr 2026 20:56:08 +0900 Subject: [PATCH 7/8] Cloud bootstrap: fix stale-reindex guidance; CLAUDE.md: drop edit-settings escape hatch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address Codex review #6. #1 (stale reindex, high): Step 3 presented 'cdidx . --files' and 'cdidx . --commits HEAD' as interchangeable 'after edits' options, but --commits HEAD only refreshes paths in the last committed diff and silently skips uncommitted work-tree edits. For a cloud session that just edited a file, following the previous instructions would leave the index stale and re-introduce the exact false-negative failure mode this prompt is supposed to prevent. Split the reindex block in both English and Japanese sections: --files (or a full '"$CDIDX" .') is the default after local edits; --commits HEAD is explicitly scoped to AFTER a commit. Add a short note explaining the distinction so the trap is visible on review. #2 (settings.json policy contradiction, medium): the Code search tools paragraph in CLAUDE.md said editing tracked .claude/settings.json was 'explicitly not the recommended path' in one sentence and then told contributors to do exactly that as a session-local escape hatch in the next sentence, citing Cloud Bootstrap Step 1.5 — which itself now forbids that edit. Resolve the contradiction in both languages: remove the edit-settings escape hatch, keep the non-mutating rule (absolute path / built-in Grep-Glob / locally built binary), and require stopping to ask the user when no non-mutating path exists. Co-Authored-By: Claude Opus 4.6 (1M context) --- CLAUDE.md | 4 ++-- CLOUD_BOOTSTRAP_PROMPT.md | 24 ++++++++++++++++++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index cf7402173c..4509ec6a74 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -175,7 +175,7 @@ The only production dependency is **Microsoft.Data.Sqlite** — keep it that way Code review uses the **locally built binary** from the current commit (`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`) to search and verify the codebase. This means the reviewer sees exactly what the code actually does — not what tests claim it does, not what documentation says it does, but what the running binary produces. **It is strictly forbidden to intentionally implement incomplete, hollow, or deceptive code that passes tests or review on paper but fails in practice.** Every feature must work correctly when exercised by the binary itself. Cutting corners to "pass review" defeats the purpose of the self-improvement loop and will be caught by dogfooding. ### Code search tools (Claude Code / AI harnesses) -Repo-tracked `.claude/settings.json` provides **best-effort** denial of shell code-search and file-discovery commands (`rg`, `grep`, `egrep`, `fgrep`, `zgrep`, `rgrep`, `ripgrep`, `ag`, `ack`, `ack-grep`, `git grep`, `find`, `locate`, `mlocate`, `mdfind`, `cdidx`, `~/.local/bin/cdidx`, `$HOME/.local/bin/cdidx`). This is not a hard guard: Claude Code permission matching appears to be textual, so fully expanded absolute paths (e.g. `/Users/alice/.local/bin/cdidx`), `command cdidx`, `env cdidx`, and similar alternate spellings are not blocked by this file. The authoritative rule is the written guidance in this section — use the built-in Grep / Glob tools and the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`; the deny list is a tripwire that catches the common spellings, not a sandbox. Cloud Claude Code sessions rely on that installed binary, so `CLOUD_BOOTSTRAP_PROMPT.md` instructs those sessions to invoke it via the fully expanded absolute path (`readlink -f "$HOME/.local/bin/cdidx"`) — the tripwire's textual matching does not catch that form. Editing the tracked `.claude/settings.json` is explicitly not the recommended path, since it dirties the worktree and risks an accidental commit that weakens the tripwire for everyone else. Use the built-in Grep / Glob tools and the **locally built binary** (`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`) for searches — the global `cdidx` may have an older DB schema, missing query features, or stale extraction logic that silently returns wrong results. Observed Claude Code behavior: tracked `deny` entries are not overridden by `.claude/settings.local.json` allows. This is not cited from a public spec, so treat it as an observed workaround rather than a guaranteed rule — verify in your own environment before relying on it. Contributors who intentionally need shell-level access to a denied command should edit the workspace copy of `.claude/settings.json` for that session only and not commit the change (same mechanism as the Cloud Bootstrap Step 1.5). +Repo-tracked `.claude/settings.json` provides **best-effort** denial of shell code-search and file-discovery commands (`rg`, `grep`, `egrep`, `fgrep`, `zgrep`, `rgrep`, `ripgrep`, `ag`, `ack`, `ack-grep`, `git grep`, `find`, `locate`, `mlocate`, `mdfind`, `cdidx`, `~/.local/bin/cdidx`, `$HOME/.local/bin/cdidx`). This is not a hard guard: Claude Code permission matching appears to be textual, so fully expanded absolute paths (e.g. `/Users/alice/.local/bin/cdidx`), `command cdidx`, `env cdidx`, and similar alternate spellings are not blocked by this file. The authoritative rule is the written guidance in this section — use the built-in Grep / Glob tools and the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`; the deny list is a tripwire that catches the common spellings, not a sandbox. Cloud Claude Code sessions rely on that installed binary, so `CLOUD_BOOTSTRAP_PROMPT.md` instructs those sessions to invoke it via the fully expanded absolute path (`readlink -f "$HOME/.local/bin/cdidx"`) — the tripwire's textual matching does not catch that form. Editing the tracked `.claude/settings.json` is explicitly not the recommended path, since it dirties the worktree and risks an accidental commit that weakens the tripwire for everyone else. Use the built-in Grep / Glob tools and the **locally built binary** (`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`) for searches — the global `cdidx` may have an older DB schema, missing query features, or stale extraction logic that silently returns wrong results. Observed Claude Code behavior: tracked `deny` entries are not overridden by `.claude/settings.local.json` allows. This is not cited from a public spec, so treat it as an observed workaround rather than a guaranteed rule — verify in your own environment before relying on it. If you need a denied command and no non-mutating path exists (fully expanded absolute path, built-in Grep / Glob, locally built binary), stop and ask the user before proceeding. Do not edit the tracked `.claude/settings.json` as part of normal workflow. ### Method signature changes When changing a method's return type or parameters (e.g. `BuildRecord` from `(FileRecord, string)` to `(FileRecord, string, string?)`), **update ALL callers** in the same commit: @@ -417,7 +417,7 @@ tests/CodeIndex.Tests/ コードレビューは現在のコミットから**ローカルビルドしたバイナリ**(`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`)を使ってコードベースを検索・検証します。つまりレビュアーは、テストが主張する動作でもドキュメントが述べる動作でもなく、実行中のバイナリが実際に出す結果を見ます。**テストやレビューを表面上パスするが実際には動作しない、不完全・中身のない・欺瞞的なコードを意図的に実装することは厳禁です。** すべての機能はバイナリ自身で実行したときに正しく動作しなければなりません。「レビューを通す」ための手抜きは自己改善ループの目的を損ない、ドッグフーディングで必ず発覚します。 ### コード検索ツール(Claude Code / AI ハーネス) -リポジトリ追跡の `.claude/settings.json` は、shell のコード検索・ファイル探索系コマンドに対する**ベストエフォートな deny** を提供します(`rg`、`grep`、`egrep`、`fgrep`、`zgrep`、`rgrep`、`ripgrep`、`ag`、`ack`、`ack-grep`、`git grep`、`find`、`locate`、`mlocate`、`mdfind`、`cdidx`、`~/.local/bin/cdidx`、`$HOME/.local/bin/cdidx`)。ハードな gate ではありません: Claude Code の permission matching はテキスト一致と見られるため、完全展開した絶対パス(例: `/Users/alice/.local/bin/cdidx`)や `command cdidx`、`env cdidx` など別スペルで起動する形は本ファイルでは塞げません。実際の強制ルールは本セクションの文面そのもので、検索には組み込みの Grep / Glob ツールと、ローカルビルドした `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を使ってください。deny リストは sandbox ではなく、典型的なスペルを引っ掛けるトリップワイヤとして扱います。Cloud の Claude Code セッションはそのインストール済みバイナリに依存するため、`CLOUD_BOOTSTRAP_PROMPT.md` では完全展開した絶対パス(`readlink -f "$HOME/.local/bin/cdidx"`)経由での呼び出しを案内しています — tripwire のテキスト一致はその形を塞げないためパーミッション編集が不要です。追跡対象の `.claude/settings.json` を編集する手順は推奨しません: worktree が dirty になり誤コミットで全貢献者向けの tripwire を弱めてしまうからです。検索には組み込みの Grep / Glob ツール、または**ローカルビルドしたバイナリ**(`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`)を使ってください — グローバル版 `cdidx` は DB スキーマが古い、クエリ機能が欠けている、抽出ロジックが古くて誤った結果を返す恐れがあります。観測された Claude Code の挙動として、追跡された `deny` は `.claude/settings.local.json` の allow では上書きされません。これは公開仕様で裏を取った記述ではないため、絶対のルールではなく観測ベースの運用指針として扱い、各自の環境でも確認してください。deny されたコマンドを意図的に shell レベルで使う必要がある貢献者は、そのセッションに限りワークスペース上の `.claude/settings.json` を編集してコミットしない方式を使ってください(Cloud Bootstrap の Step 1.5 と同じ手順)。 +リポジトリ追跡の `.claude/settings.json` は、shell のコード検索・ファイル探索系コマンドに対する**ベストエフォートな deny** を提供します(`rg`、`grep`、`egrep`、`fgrep`、`zgrep`、`rgrep`、`ripgrep`、`ag`、`ack`、`ack-grep`、`git grep`、`find`、`locate`、`mlocate`、`mdfind`、`cdidx`、`~/.local/bin/cdidx`、`$HOME/.local/bin/cdidx`)。ハードな gate ではありません: Claude Code の permission matching はテキスト一致と見られるため、完全展開した絶対パス(例: `/Users/alice/.local/bin/cdidx`)や `command cdidx`、`env cdidx` など別スペルで起動する形は本ファイルでは塞げません。実際の強制ルールは本セクションの文面そのもので、検索には組み込みの Grep / Glob ツールと、ローカルビルドした `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を使ってください。deny リストは sandbox ではなく、典型的なスペルを引っ掛けるトリップワイヤとして扱います。Cloud の Claude Code セッションはそのインストール済みバイナリに依存するため、`CLOUD_BOOTSTRAP_PROMPT.md` では完全展開した絶対パス(`readlink -f "$HOME/.local/bin/cdidx"`)経由での呼び出しを案内しています — tripwire のテキスト一致はその形を塞げないためパーミッション編集が不要です。追跡対象の `.claude/settings.json` を編集する手順は推奨しません: worktree が dirty になり誤コミットで全貢献者向けの tripwire を弱めてしまうからです。検索には組み込みの Grep / Glob ツール、または**ローカルビルドしたバイナリ**(`dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`)を使ってください — グローバル版 `cdidx` は DB スキーマが古い、クエリ機能が欠けている、抽出ロジックが古くて誤った結果を返す恐れがあります。観測された Claude Code の挙動として、追跡された `deny` は `.claude/settings.local.json` の allow では上書きされません。これは公開仕様で裏を取った記述ではないため、絶対のルールではなく観測ベースの運用指針として扱い、各自の環境でも確認してください。deny されたコマンドが必要で、かつ非変更の経路(完全展開絶対パス・組み込み Grep/Glob・ローカルビルド版)も取れない場合は、先に進めずユーザーに確認してください。追跡対象の `.claude/settings.json` を通常運用で編集することはしません。 ### メソッドシグネチャの変更 メソッドの戻り値やパラメータを変更した場合(例: `BuildRecord`を`(FileRecord, string)`から`(FileRecord, string, string?)`に変更)、**同じコミットで全ての呼び出し元を更新すること**: diff --git a/CLOUD_BOOTSTRAP_PROMPT.md b/CLOUD_BOOTSTRAP_PROMPT.md index 0bcf54c6bf..6c82318bcc 100644 --- a/CLOUD_BOOTSTRAP_PROMPT.md +++ b/CLOUD_BOOTSTRAP_PROMPT.md @@ -101,11 +101,19 @@ structured responses. - The installed binary is whatever the latest published release ships. It is **not** this branch's unreleased C# changes. Use it to explore the repo, never to "verify" an unreleased source edit. -- Incremental reindex after edits: +- Incremental reindex: ```bash - "$CDIDX" . --files [ ...] # or + # After editing tracked files locally (uncommitted edits) — use --files + "$CDIDX" . --files [ ...] + # Or refresh the entire workspace + "$CDIDX" . + # ONLY after a commit — refresh paths from the last commit's diff "$CDIDX" . --commits HEAD ``` + `--commits HEAD` only covers paths in the last committed diff; it will + not pick up uncommitted edits made in the current session. Default to + `--files` (or a full `"$CDIDX" .`) after local edits to avoid searching + a stale index. - Read `SELF_IMPROVEMENT.md` and follow its loop, but substitute the rebuild / reindex steps above for anything that assumes a local SDK. @@ -232,11 +240,19 @@ source-gen JSON 問題が解決するまでは、デフォルトの人間向け - インストール済みバイナリは「公開済み最新リリース」であって、 「このブランチの未リリース C# 変更」ではありません。リポジトリ探索には 使えますが、未リリースのソース変更の「検証」には使えません。 -- 編集後のインクリメンタル再インデックス: +- インクリメンタル再インデックス: ```bash - "$CDIDX" . --files <変更ファイル> [<変更ファイル> ...] # または + # ローカルで編集した直後(未コミット)は --files を使う + "$CDIDX" . --files <変更ファイル> [<変更ファイル> ...] + # もしくはワークスペース全体をリフレッシュ + "$CDIDX" . + # コミット**後**のみ: 直近コミットの差分に含まれるファイルを更新 "$CDIDX" . --commits HEAD ``` + `--commits HEAD` は直近コミットに含まれるパスしか対象にしません。 + 現在のセッションで未コミットの編集は拾わないので、ローカル編集後は + `--files` またはフル `"$CDIDX" .` を既定として使い、古いインデックスを + 検索してしまわないようにしてください。 - `SELF_IMPROVEMENT.md` を読み、そのループに従う。ただし、ローカル SDK を 前提としている再ビルド / 再インデックス手順は上記で読み替える。 From a5c0d17c7ff211b1328f8e31d6fa8ffe7078449e Mon Sep 17 00:00:00 2001 From: Widthdom Date: Mon, 13 Apr 2026 21:27:33 +0900 Subject: [PATCH 8/8] README: signpost downstream template vs cdidx-repo contributor path Address Codex review #7 with the minimal fix discussed: leave the # Code Search Rules template as-is (it is a template for downstream projects that adopt cdidx, and downstream projects do not inherit this repo's deny list), but add a one-line note above the template in both the English and Japanese sections pointing cdidx-repo contributors to CLAUDE.md, which routes execution through the locally built dotnet .../cdidx.dll instead of a bare cdidx command. This closes the only real papercut (a new contributor copying the template verbatim in a Claude Code session on this repo) without forcing a \$CDIDX_CMD indirection on every downstream consumer. Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a8f0d90a0f..436048258e 100644 --- a/README.md +++ b/README.md @@ -510,7 +510,7 @@ cdidx is designed as an AI-friendly code search tool. All query commands support ### Setup: Add to CLAUDE.md -To let AI agents use the generated index, place a `CLAUDE.md` in your project root: +To let AI agents use the generated index, place a `CLAUDE.md` in your project root (the template below is for **downstream projects** that adopt cdidx — contributors working on the cdidx repo itself should follow [CLAUDE.md](CLAUDE.md) in this repo, which routes execution through the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` instead of a bare `cdidx` command): ````markdown # Code Search Rules @@ -1370,7 +1370,7 @@ cdidxはAI対応のコード検索ツールとして設計されています。 ### セットアップ: CLAUDE.mdに追加 -AIエージェントにインデックスを活用させるには、プロジェクトルートに `CLAUDE.md` を配置してください: +AIエージェントにインデックスを活用させるには、プロジェクトルートに `CLAUDE.md` を配置してください(以下のテンプレートは **cdidx を導入する下流プロジェクト向け**です。cdidx 本体のリポジトリに貢献する場合は当 repo の [CLAUDE.md](CLAUDE.md) を参照してください。素の `cdidx` コマンドではなくローカルビルドの `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を経由する運用になっています): ````markdown # コードベース検索ルール