Maintainers / authorized operators only — see MAINTAINERS.md. End users don't need this document.
This document is a ready-to-use operating contract for AI agents improving cdidx from inside this repository.
Use it when the task is:
- improve
cdidxitself - identify missing AI-facing features or branding gaps
- implement non-breaking improvements immediately
- repeat the loop commit by commit while keeping the local index fresh
Keep making cdidx more useful to:
- AI agents
- human developers using AI tools
- terminal-first users
- MCP-based coding workflows
Treat the loop itself as part implementation loop, part regression test, and part monkey test for the freshly built local binary.
The loop is not just "suggest ideas". It is:
- inspect the current product with
cdidx - identify the next high-value gap
- implement it if it is non-breaking
- verify it
- commit it
- rebuild
cdidx - refresh
.cdidx/codeindex.dbwith the newly built binary, usually via delta updates first - use the refreshed index to guide the next improvement
- Create a work branch first. Use a descriptive branch name.
- Keep one task per commit.
- Before every commit, explicitly work through
.codex/workflows/precommit.md. - Before every commit, review the authoritative Search and Indexing Rules; strengthen
AGENT_GUIDE.mdor the relevant workflow if AI search behavior should change. - After every commit, rebuild
cdidxfrom the latest local source, rundotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll status --check --json, and refresh.cdidx/codeindex.dbwith that freshly built binary only when the check does not reportindex_matches_workspace: true. - Prefer the lightest truthful refresh mode: use
--filesonly for known in-place edits or new files, use--commits HEADafter a normal commit because it tracks renames/deletes from git history, use--changed-between <old-ref> <new-ref>after branch switches when both refs are known, and reservecdidx . --jsonfor full-workspace scans after history-moving operations or cases where repo-wide stale files must be purged.cdidx . --jsonis not a forced rebuild and may reportmode:"incremental"while skipping unchanged files; ifstatus --check --jsonstill reports stale after that scan, escalate todotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll index . --rebuild --yes --json. - Prefer the locally built latest binary (
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll) over an older globally installedcdidxwhenever the repository code has changed. Never fall back to a globalcdidx— the global version may have an older DB schema, missing query features, or stale extraction logic that silently produces wrong results. This is enforced at the Claude Code harness level via the repo-tracked.claude/settings.json, which 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, andcdidx. Use the built-in Grep / Glob tools or the locally built binary instead. - Treat repo-tracked
.claude/settings.json,.claude/hooks/bash-guard.py,.codex/hooks.json, and.codex/hooks/bash_guard.pyas tool-specific guard adapters. Do not edit them during ordinary self-improvement work unless the task is explicitly about agent guard behavior. Shared Bash command policy lives in.agent_harness/command_guard_core.py; update that shared core for common policy and review both adapters only when tool-specific behavior changes. The current guard is deny-oriented: it is intentionally permissive for routinedotnet,git,gh,codex exec,/tmpwork, and read-only shell inspection, while still blocking dangerous shell patterns and sensitive local read paths. - Respect the current local-privacy boundary in Claude Code: home-directory personal areas and credential-like files are intentionally read-denied by policy. Do not weaken those restrictions as a convenience workaround for self-improvement tasks; if the task genuinely requires changing the guard, treat that as the task itself and update docs accordingly.
- After
git switch, re-index with the locally built binary usingdotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll index . --changed-between <old-ref> <new-ref> --jsonwhen the workflow has both the previous and current refs; this updates only the files changed between branches while still purging rename/delete old paths included by git. If the refs are not available, or aftergit reset,git rebase,git commit --amend, orgit merge, usedotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll . --jsonso stale files are purged against the current checkout. If the follow-up status check remains stale, rundotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll index . --rebuild --yes --jsoninstead of repeatingcdidx . --json. - When searching and navigating code to investigate bugs, plan fixes, or verify changes, always use the locally built binary — not the globally installed version. This ensures query results reflect the latest extraction rules and DB schema from this branch.
- If the locally built binary crashes, aborts unexpectedly, or exposes a new defect during this loop, do not silently work around it or fall back to an older/global binary. Notify the user with the concrete failure, explain that the self-improvement loop is now blocked or tainted by that defect, and propose fixing it as a separate task or as the next approved priority.
- Treat the loop itself as ongoing regression coverage and light monkey testing. Do not limit yourself to only the safest or most standard workflows; actively exercise recent features, edge features, and less-traveled commands/options so the loop can indirectly surface crashes, bad assumptions, stale help text, and integration defects.
- For long-running human-facing CLI workflows, preserve visible liveness. Interactive terminals should continue to show progress or spinner activity during expensive work, and warnings/progress redraws must not leave the user staring at a stale
Indexing...line or a silent screen that looks frozen. - If a change may be breaking, migration-heavy, destructive, or likely to impose manual work on users, stop and ask for approval before implementing.
- Respect language differences. Do not pretend every query type is meaningful for every language.
- Respect platform differences. Do not assume Windows, macOS, and Linux behave the same for paths, file locking, process invocation, or cleanup.
- Favor implementation over brainstorming when the next improvement is clear and non-breaking.
- Dogfooding-driven feature insertion — During the loop, you may realize "if cdidx had feature X, this search/navigation would be much faster and more accurate." When that happens, insert the feature into your current plan and implement it immediately — as long as it is non-breaking. If the feature risks being a breaking change, note it down and propose it to the user after the current task is complete rather than implementing it silently.
- Keep docs and tests in sync with behavior.
- If test code, shared test helpers, test execution flow, or testing conventions change, update
TESTING_GUIDE.mdin the same commit. - For workflow or user-visible changes, use bilingual fragments under
changelog.d/unreleased/instead of editingCHANGELOG.mddirectly; reserveCHANGELOG.mdedits for release-preparation PRs. - Do not push tags or branches unless explicitly asked.
You must ask the user before proceeding if the next change would do any of the following:
- change DB layout in a way that could break older indexes or require forced rebuilds
- remove or rename CLI/MCP behavior in a user-visible way
- lower compatibility with older databases without a safe fallback
- require users to change their workflow, config, or prompts manually
- introduce risky migrations or destructive cleanup
If a DB/schema change is necessary, design the read path so newer binaries do not crash on older layouts. Prefer:
- additive columns
- additive tables
- opportunistic migration on open
- safe fallback reads when in-place migration is not available
Create and switch to a descriptive work branch before making changes.
Example:
git switch -c codex/ai-snippetsAlways compile the current repository version before relying on searches for self-improvement work.
dotnet buildUse the binary produced from the current commit, not an older global tool, so the database shape and query features match the code you are editing.
Start with the exact workspace match check:
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll status --check --jsonIf it exits 0 and reports index_matches_workspace: true, keep the existing .cdidx/codeindex.db. Otherwise, refresh the index.
Prefer delta refreshes during normal iteration, and use a full scan only when no delta mode can truthfully represent the checkout.
Choose the one refresh mode that matches your situation:
# During local in-place edits or new-file additions, refresh only the files you touched
# Old paths from renames/deletes are NOT purged unless you also pass them explicitly
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll index . --files src/CodeIndex/Cli/QueryCommandRunner.cs tests/CodeIndex.Tests/QueryCommandRunnerTests.cs --json
# After a normal commit, prefer git-aware diff refresh because it sees renames/deletes
commit_id=$(git rev-parse HEAD)
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll index . --commits "$commit_id" --json
# After a branch switch, prefer the before/after refs when your workflow has both
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll index . --changed-between <old-ref> <new-ref> --json
# First sync on a checkout, after history-moving git operations,
# or when branch-switch refs are unavailable
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll . --jsonIf you prefer dotnet run, that is also acceptable:
dotnet run --project src/CodeIndex -- . --jsonUse cdidx as your primary navigation tool. Prefer structured and low-token queries first.
Do not only exercise the obvious happy-path commands. Regularly touch newer features and less-common options as well, because this exploration phase also serves as opportunistic regression and monkey testing for the freshly built binary.
If status --json reports fold_ready: false and you only need Unicode-aware --exact semantics on an older DB, prefer upgrading in place with:
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll backfill-fold --jsonUse cdidx . --json as a full-workspace scan only when you need a fresh source scan, when history-moving git operations just happened, when branch-switch refs are unavailable, or when repo-wide stale-file purge matters more than speed. This path is not a forced rebuild: it may report mode:"incremental" and skip unchanged files. If status --check --json remains stale after that scan, run dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll index . --rebuild --yes --json. In the ordinary commit-to-commit loop, prefer --commits first; after branch switches with known refs, prefer --changed-between; and use --files only for in-place edits/new files where no old path needs purging.
Typical sequence:
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll status --json
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll map --json --limit 10 --path src/ --exclude-tests
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll inspect QueryCommandRunner --exclude-tests --limit 5
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll search "AI" --path src/ --exclude-tests --snippet-lines 6 --jsonUse inspect when you already have a likely symbol name. Use search for raw text or unsupported languages. Use map first when you need orientation.
Also rotate through features that are easy to neglect, such as JSON output variants, path filters, graph queries on supported languages, unsupported-language behavior, and help/usage flows.
Before implementation, write a concrete plan that covers:
- what gap you found
- why it matters for AI or product adoption
- whether the change is non-breaking
- which files and tests are affected
- how you will verify it
- how language-specific behavior should differ
- how platform-specific behavior should differ, if paths/processes/filesystem semantics are involved
If the change is clearly non-breaking and high-value, implement it without waiting for more approval.
Examples:
- better ranking
- better snippets
- improved MCP tool output
- new additive CLI/MCP queries
- better docs/examples/branding
- safer backward-compatible schema additions
- stronger language-aware guards and messaging
At minimum, do the checks that match the change:
dotnet test- targeted CLI smoke checks
- MCP behavior checks if MCP was touched
- documentation spot-checks
- language-specific behavior checks if logic differs by language
- platform-sensitive checks if behavior depends on files, paths, processes, console I/O, or SQLite cleanup
If dotnet test is blocked specifically by the sandbox rather than by the product or test code, a targeted dangerouslyDisableSandbox: true exception is acceptable for dotnet test only. Do not generalize that escape hatch to dotnet build, dotnet run, gh, git, codex exec, Python, or general shell convenience.
Examples:
dotnet test
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll status --json
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll map --json --path src/ --exclude-tests
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll inspect ResolveGitCommonDir --json --exclude-tests --limit 5Before committing, explicitly review:
- Tests
- TESTING_GUIDE.md
- CHANGELOG.md — New entries normally go under bilingual fragments in
changelog.d/unreleased/; only release-preparation PRs editCHANGELOG.mddirectly. SeeAGENT_GUIDE.mdand.codex/workflows/precommit.mdfor the full rules. - README.md
AGENT_GUIDE.md, especially Search and Indexing Rules- DEVELOPER_GUIDE.md
.codex/workflows/precommit.md- This file (
SELF_IMPROVEMENT.md) - PR description, if a PR already exists
Then commit one coherent task.
This is mandatory. The next round must start from the newest binary and newest DB.
Build first, then choose the lightest refresh mode that keeps the DB truthful:
dotnet build
# Default post-commit path: refresh from the last commit's diff
# This is safer than --files because git diff sees renames/deletes
commit_id=$(git rev-parse HEAD)
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll index . --commits "$commit_id" --json
# Branch switch path when the before/after refs are known
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll index . --changed-between <old-ref> <new-ref> --json
# Escalate to a full scan after git reset/rebase/amend/merge,
# when branch-switch refs are unavailable, or whenever repo-wide stale purge is required
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll . --jsonAfter each commit:
- inspect what the new binary can do
- search for newly exposed gaps
- repeat
Do not use one search strategy for every language.
references,callers, andcalleesare meaningful only for languages where cdidx intentionally supports regex-based graph extraction.- For unsupported languages, prefer
search,excerpt,definition, orfilesinstead of assuming graph data exists. - Treat C#, Java, Go, Rust, TypeScript/JavaScript, Python, Kotlin, Ruby, C/C++, PHP, and Swift differently from Markdown, YAML, JSON, TOML, Shell, SQL, HTML/CSS, Vue, Svelte, and Terraform.
- When proposing new language-specific features, state clearly which languages are in scope and why.
- When a heuristic is language-specific, document the limitation in README and tests.
When enhancing symbol extraction, reference extraction, or language-specific heuristics for one language, actively check whether the same improvement applies to structurally similar languages — especially C# and Java, which share many syntactic patterns (classes, interfaces, generics, annotations/attributes, access modifiers, method signatures).
- After implementing or refining a C# pattern, review the corresponding Java patterns in
SymbolExtractor.csandReferenceExtractor.csand apply the same improvement where the syntax permits. - The same principle applies in reverse (Java → C#) and to other language pairs with strong overlap (TypeScript/JavaScript, Kotlin/Java, C/C++).
- Do not force a pattern onto a language where it does not fit. If the syntax diverges enough to make the port unreliable, skip it and document why.
- When the expansion is straightforward, include it in the same commit as the original enhancement so the languages stay in sync. When it requires non-trivial adaptation, make it a separate follow-up commit.
Do not assume path handling, process cleanup, or file deletion behaves the same on every OS.
- Windows can hold SQLite files longer because of file locking and connection pooling, so cleanup code and tests must tolerate delayed release.
- Path separators, casing assumptions, shell commands, and process launch behavior differ across Windows, macOS, and Linux.
- If you change temp-file handling, DB lifecycle, or CLI process behavior, add verification that is robust across supported platforms.
- If a workaround is OS-specific, document why it exists instead of leaving it as unexplained test fragility.
Self-improvement is not limited to search mechanics. Also evaluate:
- positioning versus
rg, desktop search tools, and IDE search - first-run clarity
- README opening clarity
- examples that AI agents will actually copy
- MCP discoverability
- names of commands and docs sections
- whether a new user can understand the value in 30 seconds
Good improvements are often:
- fewer round-trips
- lower token output
- clearer defaults
- better trust/freshness signals
- safer compatibility behavior
- sharper product framing
cdidx is written in C#. Every improvement to C# analysis directly improves how this loop explores, navigates, and verifies cdidx's own codebase. This is a genuine dogfooding advantage — no other language gives the same feedback density.
When choosing what to improve next, prioritize C# capabilities first:
- C# symbol extraction accuracy (properties, events, records, pattern matching, etc.)
- C# reference/call-graph precision (generic methods, extension methods, LINQ, etc.)
- C# ranking quality (namespace awareness, visibility-weighted results, etc.)
- C#-specific MCP/CLI output improvements
- Fixing false positives or negatives that surface while working on the cdidx codebase itself
This does not mean other languages are unimportant. It means:
- When two improvements have roughly equal value, pick the C# one.
- When the loop surfaces a C#-specific defect during normal operation, treat it as a high-priority fix rather than a "nice to have."
- When adding a cross-language feature, ensure the C# path is the most polished.
The reasoning is simple: a sharper C# experience makes the self-improvement loop itself more productive, which accelerates every subsequent improvement — including those for other languages.
If a user wants to start this loop, the minimal instruction can be:
Read `SELF_IMPROVEMENT.md` and start implementing the next non-breaking improvement.If the user wants more direction:
Read `SELF_IMPROVEMENT.md`, inspect the current repo with cdidx itself, identify the next high-value non-breaking improvement for AI friendliness or adoption, implement it, verify it, commit exactly one task, rebuild cdidx from the latest commit, refresh `.cdidx/codeindex.db` with `--commits` when possible, use `--files` only for in-place edits/new files, and use a full scan when checkout-changing git operations or stale-file purge require it, then continue from the refreshed index. Ask before any breaking change.Maintainer と認可オペレーター向け — MAINTAINERS.md#maintainer-と認可オペレーター向け を参照してください。エンドユーザーはこのドキュメントを読む必要はありません。
このドキュメントは、このリポジトリの中から cdidx 自身を改善していく AI エージェント向けの、そのまま使える運用契約です。
次のようなタスクで使います:
cdidx自体を改善したい- AI向け機能やブランディング上の欠けを見つけたい
- 非破壊な改善はすぐ実装したい
- ローカルインデックスを常に新鮮に保ちながら、コミット単位で改善を回したい
cdidx を次の相手にとって、もっと役立つものにし続けることです:
- AIエージェント
- AIツールを使う人間の開発者
- ターミナル中心のユーザー
- MCPベースのコーディングワークフロー
このループ自体を、実装サイクルであると同時に、ローカルでビルドした最新版バイナリに対するリグレッションテストと軽いモンキーテストの場として扱います。
このループは「アイデアを出すだけ」ではありません。流れは次のとおりです:
cdidx自身で現状を観察する- 次に改善すべき価値の高いギャップを見つける
- 非破壊なら実装する
- 検証する
- コミットする
cdidxを再ビルドする- その新しいバイナリで
.cdidx/codeindex.dbを更新する(通常は差分更新を優先する) - 更新済みインデックスを使って次の改善を決める
- まず作業ブランチを切る。名前は内容が分かるものにする。
- 1案件1コミット を守る。
- 毎コミット前に、
.codex/workflows/precommit.mdを明示的に確認する。 - 毎コミット前に、正本である Search and Indexing Rules を見直し、AIの検索行動を変えるべきなら
AGENT_GUIDE.mdまたは関連 workflow を強化する。 - 毎コミット後に、ローカルソースの最新状態から
cdidxを再ビルドし、dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll status --check --jsonを実行する。index_matches_workspace: trueでなければ、その新しいバイナリで.cdidx/codeindex.dbを更新する。 - 更新モードは「正しさを保てる範囲で最も軽いもの」を優先する。
--filesは把握している in-place 編集や新規追加だけに使い、通常のコミット後は rename/delete も拾える--commits HEADを使う。ブランチ切り替え後は前後の ref が分かるなら--changed-between <old-ref> <new-ref>を使い、履歴を動かす操作や repo 全体で stale file を掃除したい場合だけcdidx . --jsonの全 workspace scan へ上げる。cdidx . --jsonは強制 rebuild ではなく、mode:"incremental"と表示して unchanged file を skip する場合があるため、その後のstatus --check --jsonがまだ stale ならdotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll index . --rebuild --yes --jsonに上げる。 - リポジトリのコードを変更した後は、古いグローバルインストール版ではなく ローカルでビルドした最新版バイナリ (
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll) を使う。グローバル版には絶対に戻らないこと — グローバル版は DB スキーマが古い、クエリ機能が欠けている、抽出ロジックが古くて誤った結果を返す、といった問題が起こりうる。このルールはリポジトリ追跡の.claude/settings.jsonで harness レベルでも強制されており、shell のコード検索・ファイル探索系コマンドを網羅的に deny している(rg、grep、egrep、fgrep、zgrep、rgrep、ripgrep、ag、ack、ack-grep、git grep、find、locate、mlocate、mdfind、cdidx)。代わりに組み込みの Grep / Glob ツールかローカルビルド版を使うこと。 - リポジトリ追跡の
.claude/settings.json、.claude/hooks/bash-guard.py、.codex/hooks.json、.codex/hooks/bash_guard.pyは tool-specific guard adapter として扱う。通常の自己改善作業では編集せず、agent guard 挙動自体を変えるタスクのときだけ触る。共通の Bash command policy は.agent_harness/command_guard_core.pyに置かれているため、共通ポリシーを変える場合は shared core を更新し、tool 固有挙動が変わる場合だけ両 adapter を見直す。現在のガードは deny ベースで、日常的なdotnet、git、gh、codex exec、/tmp作業、読み取り中心の shell 確認は止めにくくしつつ、危険な shell パターンと機微なローカル read path は止める設計になっている。 - Claude Code のローカルプライバシー境界を尊重すること。ホーム配下の私物領域や資格情報系ファイルはポリシーで read deny されているため、自己改善タスクを進めやすくする目的でそれを緩めない。もし guard の変更自体が本当に必要なら、それを独立したタスクとして扱い、関連ドキュメントも同じコミットで更新する。
git switchの後は、切り替え前後の ref が分かる場合、ローカルビルド版 でdotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll index . --changed-between <old-ref> <new-ref> --jsonを実行する。これにより、ブランチ間で変わったファイルだけを更新しつつ、git が返す rename/delete の旧 path も purge できる。ref が分からない場合や、git reset、git rebase、git commit --amend、git mergeの後は、dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll . --jsonの full-workspace scan で現在の checkout に対する stale file を掃除する。その後も status check が stale なら、cdidx . --jsonを繰り返さずdotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll index . --rebuild --yes --jsonを実行する。- バグ調査、修正計画、変更検証のためにコード検索・ナビゲーションを行うときも、常に ローカルビルド版 を使う。グローバルインストール版は使わない。これにより、このブランチの最新の抽出ルールと DB スキーマを反映した検索結果が得られる。
- このループ中に ローカルビルド版 がクラッシュしたり、異常終了したり、新しい不具合を露呈した場合は、黙って回避したり古い版・グローバル版へ逃げたりしないこと。具体的な失敗内容をユーザーに通知し、その不具合によって自己改善ループがブロックされている、または結果の信頼性が損なわれていることを説明したうえで、別タスクまたは次の承認済み優先事項として修正提案を出すこと。
- このループ自体を、継続的なリグレッション確認と軽いモンキーテストとして扱うこと。最も安全で標準的なワークフローだけに偏らず、新しい機能、利用頻度の低い機能、枝葉末節のオプションも積極的に触り、間接的にクラッシュ、古いヘルプ文、想定漏れ、統合不具合をあぶり出すこと。
- 人間向け CLI の長時間処理では、生存表示を維持すること。重い処理中も対話ターミナルには進捗かスピナーが見え続けるべきであり、警告表示や再描画のせいで古い
Indexing...行だけが残ったり、固まったように見える無音画面になったりしてはならない。 - 変更が破壊的、移行負荷が高い、危険、またはユーザーに手間を強いる可能性があるなら、実装前に必ず承認を取る。
- 言語差分を無視しない。すべての言語で同じ検索が意味を持つと仮定しない。
- プラットフォーム差分を無視しない。Windows、macOS、Linux のパス、ファイルロック、プロセス起動、クリーンアップが同じだと仮定しない。
- 次の改善が明確で非破壊なら、議論だけで止まらず実装を優先する。
- ドッグフーディング駆動の機能挿入 — ループ中に「cdidx にこの機能があれば、もっと速く正確に検索できるのに」と気付くことがある。その場合、非破壊な変更であれば現在の計画に組み入れてそのまま実装して構わない。破壊的変更のリスクがある場合は、メモしておき、現在のタスク完了後にユーザーに実装可否を打診すること。
- ドキュメントとテストを挙動と同期させる。
- テストコード、共有テストヘルパー、テスト実行フロー、またはテスト規約を変更した場合は、同じコミットで
TESTING_GUIDE.mdも更新する。 - workflow 変更やユーザーに見える変更では、
CHANGELOG.mdを直接編集せず、changelog.d/unreleased/配下に英日併記 fragment を追加する。CHANGELOG.mdの直接編集は release-preparation PR に限定する。 - branch push や
git tagは、明示的に依頼されたときだけ行う。
次にやろうとしている変更が以下に当てはまるなら、先にユーザーへ確認してください:
- DBレイアウト変更で古いインデックスを壊す、または強制再構築を招く可能性がある
- CLI/MCPのユーザー向け挙動を削除・改名・互換性低下させる
- 古いDBへの互換性を安全なフォールバックなしに下げる
- ユーザー側にワークフローや設定やプロンプトの手修正を要求する
- 危険な移行や破壊的なクリーンアップを伴う
DB/スキーマ変更が必要な場合は、新しいバイナリが古いレイアウトでクラッシュしない読み取り経路を設計してください。優先すべきなのは:
- 追加カラム
- 追加テーブル
- open 時の機会的移行
- その場移行できない場合の安全なフォールバック読み取り
変更前に、内容が分かる作業ブランチを作って切り替えます。
例:
git switch -c codex/ai-snippets自己改善の検索に入る前に、必ず現在のリポジトリ版をコンパイルしてください。
dotnet build編集中のコードと DB 形状と検索機能を一致させるため、古いグローバルツールではなく、現在のコミットからビルドしたバイナリ を使います。
まず現在の workspace と DB が一致しているか確認します:
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll status --check --json終了コード 0 かつ index_matches_workspace: true なら、既存の .cdidx/codeindex.db をそのまま使って構いません。それ以外ならインデックスを更新してください。
通常の反復中は差分更新を優先し、checkout を正しく表せる差分モードが無い場合だけ full scan を使います。
状況に合う更新モードを1つ選んでください:
# ブランチ切り替え後、前後の ref が分かる場合
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll index . --changed-between <old-ref> <new-ref> --json
# checkout 直後の初回同期、履歴を動かす git 操作の直後、
# またはブランチ切り替え前後の ref が分からない場合
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll . --json
# 手元の in-place 編集や新規追加だけを反映
# rename/delete の旧 path は、明示しない限り purge されない
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll index . --files src/CodeIndex/Cli/QueryCommandRunner.cs tests/CodeIndex.Tests/QueryCommandRunnerTests.cs --json
# 通常のコミット直後は、そのコミット差分だけを反映
# git diff が rename/delete も見られるので、こちらを既定にする
commit_id=$(git rev-parse HEAD)
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll index . --commits "$commit_id" --jsondotnet run でも構いません:
dotnet run --project src/CodeIndex -- . --json主なナビゲーション手段は cdidx にしてください。まずは構造化された、低トークンの問い合わせを優先します。
分かりやすい happy path のコマンドだけをなぞらないこと。ここでの探索は、ビルドしたばかりのバイナリに対する日和見的なリグレッションテスト兼モンキーテストでもあります。
status --json が fold_ready: false を返し、古い DB に対して Unicode-aware な --exact だけを有効化したい場合は、まず次で in-place upgrade することを優先してください:
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll backfill-fold --jsonソース再走査も必要なとき、履歴を動かす git 操作の直後、ブランチ切り替え前後の ref が分からないとき、または repo 全体で stale file を掃除したいときだけ、cdidx . --json の full-workspace scan を使います。この経路は強制 rebuild ではなく、mode:"incremental" と表示して unchanged file を skip する場合があります。その後の status --check --json がまだ stale なら、dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll index . --rebuild --yes --json を実行してください。通常のコミット間ループでは rename/delete も追える --commits、ブランチ切り替えでは前後 ref を渡す --changed-between を先に考え、--files は in-place 編集や新規追加に限定してください。
典型例:
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll status --json
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll map --json --limit 10 --path src/ --exclude-tests
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll inspect QueryCommandRunner --exclude-tests --limit 5
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll search "AI" --path src/ --exclude-tests --snippet-lines 6 --json候補シンボル名が分かっているなら inspect、生テキストや未対応言語なら search、全体像が欲しいなら map を優先します。
加えて、JSON 出力の別経路、path filter、対応言語での graph クエリ、未対応言語の挙動、help / usage など、見落とされやすい経路も意識的に回してください。
実装前に、次を含む具体的な計画を立ててください:
- どんなギャップを見つけたか
- それがAIや普及にとってなぜ重要か
- その変更が非破壊かどうか
- 影響ファイルと必要テスト
- どう検証するか
- 言語ごとの差をどう扱うか
- パス、プロセス、ファイルシステム意味論が関係する場合は、プラットフォームごとの差をどう扱うか
変更が明らかに非破壊で価値が高いなら、追加承認を待たずに実装します。
例:
- ランキング改善
- スニペット改善
- MCPツール出力改善
- 追加的なCLI/MCPクエリ
- ドキュメント、例、ブランディングの改善
- 後方互換を保ったスキーマ追加
- 言語差分を踏まえたガードやメッセージの改善
変更に応じて、最低限次を実施します:
dotnet test- CLI のスモーク確認
- MCP を触ったなら MCP 挙動確認
- ドキュメントの spot check
- 言語差分があるなら、言語別の確認
- ファイル、パス、プロセス、console I/O、SQLite cleanup に依存するなら、platform-sensitive な確認
dotnet test が製品やテストコードの問題ではなく sandbox そのものに塞がれている場合に限り、dangerouslyDisableSandbox: true を dotnet test 専用の例外として使ってよい。これを dotnet build、dotnet run、gh、git、codex exec、Python 実行、一般的な shell 利便性に広げてはいけない。
例:
dotnet test
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll status --json
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll map --json --path src/ --exclude-tests
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll inspect ResolveGitCommonDir --json --exclude-tests --limit 5コミット前に、明示的に次を確認します:
- Tests
- TESTING_GUIDE.md
- CHANGELOG.md — 新エントリは通常、
changelog.d/unreleased/の英日併記 fragment に書く。CHANGELOG.mdを直接編集するのは release-preparation PR だけ。完全なルールはAGENT_GUIDE.mdと.codex/workflows/precommit.md参照。 - README.md
AGENT_GUIDE.md(特に Search and Indexing Rules)- DEVELOPER_GUIDE.md
.codex/workflows/precommit.md- このファイル(
SELF_IMPROVEMENT.md) - 既存PRがあるなら PR説明
そのうえで、1つのまとまりだけをコミットします。
これは必須です。次のラウンドは、必ず最新バイナリと最新DBから始めてください。
まずビルドし、そのうえで DB の正しさを保てる最も軽い更新モードを選びます:
dotnet build
# 通常の post-commit 経路: 直前コミットの差分を反映
# git diff が rename/delete も拾えるため、--files より安全
commit_id=$(git rev-parse HEAD)
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll index . --commits "$commit_id" --json
# ブランチ切り替え後、前後の ref が分かる場合
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll index . --changed-between <old-ref> <new-ref> --json
# git reset/rebase/amend/merge の後、
# ブランチ切り替え前後の ref が分からない場合、
# または repo 全体の stale file purge が必要な場合はフル更新
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll . --json各コミット後に:
- 新しいバイナリで何ができるか観察する
- 新たに見えるギャップを探す
- 繰り返す
すべての言語で同じ検索戦略を使ってはいけません。
references、callers、calleesは、cdidx が意図的に正規表現ベースのグラフ抽出をサポートしている言語でのみ意味があります。- 未対応言語では、グラフ結果がある前提で進めず、
search、excerpt、definition、filesを優先します。 - C#、Java、Go、Rust、TypeScript/JavaScript、Python、Kotlin、Ruby、C/C++、PHP、Swift と、Markdown、YAML、JSON、TOML、Shell、SQL、HTML/CSS、Vue、Svelte、Terraform は分けて考えてください。
- 新しい言語依存機能を提案するときは、どの言語を対象にするのか、その理由を明記してください。
- ヒューリスティックが言語依存なら、README とテストに制限事項を残してください。
ある言語のシンボル抽出、参照抽出、言語固有ヒューリスティックを強化したとき、構文的に近い言語にも同じ改善が当てはまらないか能動的に確認してください。特に C# と Java は共通の構文パターンが多い(クラス、インターフェース、ジェネリクス、アノテーション/属性、アクセス修飾子、メソッドシグネチャ)ため、横展開しやすい組み合わせです。
- C# 向けのパターンを実装・改良したら、
SymbolExtractor.csとReferenceExtractor.csの対応する Java パターンを確認し、構文が許す範囲で同じ改善を適用してください。 - 逆方向(Java → C#)や、重なりの大きい他の言語ペア(TypeScript/JavaScript、Kotlin/Java、C/C++)にも同じ考え方が当てはまります。
- 構文が十分に異なり、移植すると信頼性が下がる場合は無理をせず、見送った理由を残してください。
- 横展開が素直にできるなら、元の強化と同じコミットに含めて言語間の同期を保ちます。非自明な適応が必要な場合は、別のフォローアップコミットにしてください。
パス処理、プロセス後始末、ファイル削除がすべての OS で同じだと考えてはいけません。
- Windows では SQLite の接続プールやファイルロックにより、DB ファイル解放が遅れることがあるため、後片付けコードやテストは遅延解放に耐える必要があります。
- パス区切り、大小文字前提、shell コマンド、プロセス起動挙動は Windows、macOS、Linux で異なります。
- 一時ファイル処理、DB ライフサイクル、CLI プロセス挙動を変える場合は、対応プラットフォーム全体で壊れにくい検証を追加してください。
- OS 固有の回避策を入れる場合は、説明のない不安定テストにせず、なぜ必要かをドキュメントに残してください。
自己改善は検索機能だけに限りません。次も評価対象です:
rg、デスクトップ検索、IDE検索に対する位置づけ- 初回体験の分かりやすさ
- README 冒頭の伝わりやすさ
- AI が本当にコピペする例になっているか
- MCP の見つけやすさ
- コマンド名やドキュメント見出しの分かりやすさ
- 新規ユーザーが30秒で価値を理解できるか
良い改善は、たいてい次のどれかです:
- 往復回数が減る
- トークン出力が減る
- デフォルトが明快になる
- 信頼性や鮮度のシグナルが増える
- 互換性面が安全になる
- プロダクトの打ち出しが鋭くなる
cdidx は C# で書かれています。C# の解析を改善すれば、それがそのまま、このループが cdidx 自身のコードベースを探索・ナビゲート・検証する精度を高めます。これは本物のドッグフーディングの利点です。他のどの言語も同じ密度のフィードバックは返してくれません。
次に何を改善するか選ぶとき、C# 関連の機能強化を最優先にしてください:
- C# シンボル抽出の精度(プロパティ、イベント、record、パターンマッチングなど)
- C# の参照・コールグラフ精度(ジェネリックメソッド、拡張メソッド、LINQ など)
- C# のランキング品質(名前空間の考慮、可視性で重み付けした結果など)
- C# 固有の MCP/CLI 出力改善
- cdidx のコードベース自体を触っていて浮上した偽陽性・偽陰性の修正
他の言語が重要でないという意味ではありません。意味するのは:
- ほぼ同等の価値を持つ改善が2つあるなら、C# 側を選ぶ。
- ループの通常操作中に C# 固有の不具合が見つかったら、「あると嬉しい」ではなく優先修正として扱う。
- 言語横断の機能を追加するときは、C# の経路を最も洗練させる。
理由は単純です。C# の体験が鋭くなれば自己改善ループ自体の生産性が上がり、その結果すべての後続改善——他言語向けも含め——が加速します。
このループを始めるとき、最小の指示はこれで十分です:
Read `SELF_IMPROVEMENT.md` and start implementing the next non-breaking improvement.少し具体化したいなら:
Read `SELF_IMPROVEMENT.md`, inspect the current repo with cdidx itself, identify the next high-value non-breaking improvement for AI friendliness or adoption, implement it, verify it, commit exactly one task, rebuild cdidx from the latest commit, refresh `.cdidx/codeindex.db` with `--commits` after normal commits, use `--changed-between <old-ref> <new-ref>` after branch switches when both refs are known, use `--files` only for in-place edits/new files, and use a full scan when history-moving git operations, missing branch-switch refs, or repo-wide stale-file purge require it, then continue from the refreshed index. Ask before any breaking change.