プレフィクサー:スコープ優先、ミス時に拡大、差分を記録
リポジトリ全体を検索するエージェントは、無関係なヒットごとにトークンを支払います。名前空間マップ(何がどこにあるかを示す十数行の記述)があれば、最初の呼び出しから正しい領域内で検索できます。このスキルはそのマップを構築し、維持し、エージェントにスコープ優先の検索を課します。その仕事はただ一つ:より安く、より良いコードベース検索です。
サイズゲート。 おおよそ100ファイル未満、またはリポジトリの構造が一目で明らかな場合は、マップをスキップし、ディレクトリ名でスコープ検索します。マップはその時点を超えて価値を発揮します。
<重要> 目の前の検索がスコープ可能である可能性がほんの少しでもあるなら、スコープしてください。スコープなしの検索は、このスキルが存在する目的である失敗です。「たった一回のgrepだから」という考えがトークンを消費していくのです。 </重要>
作業方法
- 一度だけ方向付けする。
.prefixer/namespaces.mdを確認します。存在せず、タスクに2回以上の検索が必要な場合は、作業中のセグメントをマッピングし(§1〜§3)、その中で検索します。マップが存在する場合はそれを読み、スコープ指定して開始します。 - スコープ指定して検索し、ミス時に拡大する。 最初の検索はリポジトリルートではなく、最も狭いと思われる名前空間に送ります(§4〜§6)。
- 記録する。 タスクの終わりに
.prefixer/metrics.jsonlに1行追加し、ベースラインが存在する場合は差分も記録します(§7〜§8)。必須の出力であり、オプションではありません。
効果を発揮する場面
- 大規模または不慣れなリポジトリでの最初のセッション。 ツリーをスキャンする代わりに12行のマップを読めば、最初の検索がすでにスコープ指定されます。
- モノレポ。 パッケージごとに1つの名前空間:検索が兄弟パッケージのノイズをコンテキストに引き込むのを防ぎます。
- 多数のコードベース。 組織レベルのマップがコードベースを選び、リポジトリのマップがその中の名前空間を選びます。2階層で、統合スキャンは決して行われません。
- 繰り返しの探索。 「Xはどこにあるか」、リファクタリング、不慣れな機能領域;初回ヒット率こそがマップが価値を発揮する場面です。
- 再訪問するリポジトリ。 マップはセッションを超えて持続します。将来のすべてのエージェントは、再スキャンする代わりに方向付けされた状態で開始します。
A. 名前空間マップ
1. セグメントをマッピングし、世界全体をマッピングしない
ルール: リポジトリに .prefixer/namespaces.md がなく、作業に2回以上の検索が必要な場合、このタスクが触れるリポジトリの部分(3〜5つの名前空間)のみをマッピングします。ツリー全体ではありません。今日の検索をスコープする部分マップは、1時間かけた完全なマップよりも優れています。実際の検索がその外側に着地したときに成長させ、先回りして成長させることは決してありません。スキルのディレクトリにある bash scripts/init_namespaces.sh を実行してスキャフォールドを作成し、その推測を修正します:各名前空間が何のためにあるかを記述します。
理由: 採用は設計上段階的です。マップは現役のファイルであり、国勢調査ではありません。検索がその行を必要としたときに、その行が価値を生みます。
ドラフトはマップではありません。 プレフィックスまたは contains がまだ TODO と書かれている行は未完成です。マップに依存する前に完成させるか削除してください。スキャフォールドは残っているドラフト行の数を報告します。
既存のドキュメントを優先。 AGENTS.md、CLAUDE.md、またはREADMEがすでにレイアウトを説明している場合、それらから contains をシードし(スキャフォールドはこれを行います)、namespaces.md を検索スコープの正規のものとして扱います。2つの異なる目次を維持しないでください。
セッション開始時が記憶より優先。 セッションごとに1回マップを読むことは、最もスキップされがちなステップです。ハーネスがセッション開始時にファイルを注入できる場合、namespaces.md を出力させてください。すべての検索がスコープ指定され、規律は不要になります。出荷済みの配線:scripts/install_hook.sh がフックを書き込みます(scripts/session_start.sh はマップと健全性診断を出力します);ハンドスニペットは integrations/ にあります。レシピと理論的根拠:references/namespaces.md。
2. 小さく保ち、グロブベースにする
ルール: 5〜12の名前空間。各行は短いプレフィックス、パスグロブ、および曖昧性解消のために書かれた1行の目的です。2つの行が同じ検索に同じ頻度で一致する場合、マージします。実際の検索をスコープしたことがない行は削除します。
フォーマット:
# 名前空間
repo: acme-payments
| プレフィックス | スコープ | contains |
|--------|--------------------|-----------------------------|
| api: | src/api/** | RESTハンドラ、ルート |
| auth: | src/auth/** | ログイン、セッション、トークン |
| sso: | src/auth/sso/** | SSOサブチーム領域 |
| test: | tests/**, **/*.test.* | スイート、フィクスチャ |
repo: ヘッダーはこのコードベースの一意の修飾子(gitリモートから)です。組織が多数のコードベースを実行する場合、すべてのプレフィックスをグローバルに一意にします:acme-payments:auth: は checkout-service:auth: と決して衝突しません。
行はネストします:インデントされた行はその上の名前空間に属し、モジュール内のサブチームやサービス内のパッケージを表します。タグは構成され、auth:sso: となるため、同じ名前でも2つの異なる親の下では区別されます(orders:checkout: vs payments:checkout:)。
名前は派生であり、宣言ではありません。 プレフィックスと contains テキストは、コードベース自身の語彙(ディレクトリ名、行がスコープするファイル内の主要な用語)から取得します。決してあなたが発明したカテゴリからではありません。派生された名前はリポジトリの進化に追従します。発明されたものは漂流します。スキャフォールドはこれを自動で行います:間違っているところを修正し、正しいところはそのままにします。
フォーマットの詳細と他のリポジトリ形状のマップ:references/namespaces.md。
3. 更新し、決して再生成しない
ルール: マップが古くなった場合、古い行を編集します。ファイルを書き換えてはいけません。全体の再生成は、マップを有用にした蓄積された詳細を失います。死んだ行を剪定し、欠けている行を追加し、残りはバイト単位で同一に保ちます。書き換えられたマップは、それを読み込んだすべてのセッションのプロンプトキャッシュプレフィックスを壊します。キュレーション後、bash scripts/check_namespaces.sh を実行します。グロブが何も解決しない行は、将来のすべてのセッションに嘘をついていることになります。マップが古くなったと感じたり、ログが大きくなった場合は、bash scripts/suggest_map.sh を実行します。metrics.jsonl とツリーを読み、実際の検索がすでに要求した行を提案します。
多数のコードベース: 同じトリックが積み重なります。組織レベルのマップがコードベースを選び(pay: services/payments/**)、リポジトリマップがその中の名前空間を選びます。各マップの repo: ヘッダーにより、プレフィックスはコードベース間で一意になります。40のサービスがすべて auth/ を持つことができますが、修飾タグ payments:auth: は正確に1つを指定するためです。すべてのリポジトリを、組織規模でのルートグレップの失敗である1つの検索に統合することは決してしないでください。references/namespaces.md を参照。
B. 検索スコープ
4. 最も狭いものから最初に
ルール: すべての検索は、答えが含まれている可能性のある最も狭い名前空間から開始します。grep "expire" src/auth/ は grep "expire" . よりも優れています。ミスは1回の呼び出しを犠牲にします。広範な検索は、ヒットリスト全体をトークンで犠牲にします。
スクリプトにルールを任せる: bash scripts/search.sh auth "expire" はタグをグロブに解決し、その中で検索し、ミス時に1レベル拡大し、メトリクス行を記録します。§4〜§8は自動実行されます。--scope <ns> はグロブリストを出力し、--paths <ns> は解決されたファイルを、--list はすべてのタグを出力します。マップは他のコマンドがクエリできるインデックスとして機能します。
警告: 「念のため」リポジトリルートを検索すること、パス制約のない **/* のようなグロブパターン、名前空間グロブで十分な場合の find の使用。
5. ミス時に1レベル拡大する
ルール: 名前空間内でミスした?1レベル拡大します:名前空間、次にその親エリア、次にリポジトリ、次にベンダーおよび生成されたディレクトリ。ミスから直接リポジトリ全体のスキャンに飛んではいけません。また、タスクがそれらに関するものでない限り、node_modules、vendor、dist、build、またはロックファイルを検索してはいけません。
6. 名前空間タグで回答する
ルール: 発見結果を プレフィックス:パス:行(auth:src/auth/session.ts:42)として報告します。次の検索(あなた自身の、または将来のセッションの)は、既にスコープ指定された状態で開始されます。ファイルがあらゆる名前空間に抵抗する場合、それはマップにギャップがあるというシグナルです。タグを発明する代わりにそれに言及してください。
C. 追跡
7. 主張の前にベースライン
ルール: 検索の変更を推奨する前に、現在の動作をカウントします:タスクあたりの検索数、タスクあたりのツール呼び出し数、初回ヒット率。ベースラインがなければ差分はなく、単なる物語に過ぎません。固定プローブを実行して記録します:リポジトリルートで bash scripts/measure_search.sh --baseline orientation -- grep -rn "TODO" . を実行するか、マップが存在する前に最初のいくつかのタスクをカウントします。何を記録し、どのようにスコアリングするかについては、references/metrics.md を参照してください。
8. すべてのタスクを記録する
ルール: 各タスクの終わりに、.prefixer/metrics.jsonl に1行のJSONを追加します:
{"ts":"2026-10-26T14:03:11Z","task":"find-session-expiry","searches":3,"tool_calls":4,"first_try_hit":true,"est_tokens":1400}
est_tokens は chars/4、推定値です。正確に測定できない場合でもフィールドを保持します。セッション終了時に、ベースラインとの差分を報告します。scripts/measure_search.sh は検索をラップし、リポジトリルートに検索ごとの行を記録します(hits、scope;--baseline はプローブを示し、--hit|--miss は first_try_hit を記録します)。手書きのタスク行は tool_calls と first_try_hit を追加します。1つのスキーマ、オプションフィールド;references/metrics.md にリストがあります。scripts/report_metrics.sh はログを読み返します:ヒット率、スコープごとの消費、スコープ対ベースラインの差分。
Git の扱い。 namespaces.md をコミットします:それは将来のすべてのセッションが恩恵を受ける共有プレフィックスです。metrics.jsonl はローカルテレメトリです。スキャフォールドは .prefixer/.gitignore を書き込みます。チームがトレンドデータを望む場合のみコミットしてください。
レッドフラグ
これらの思考は停止を意味します。正当化しています。
| 思考 | 現実 |
|---|---|
| 「一度の広範なgrepくらい大丈夫」 | 広範なgrepこそ、このスキルが排除しようとしているコストです。スコープしてください。 |
| 「たぶんどこにあるかわかっている」 | 名前空間で確認してください。間違った推測は、スコープされた確認よりもコストがかかります。 |
| 「まずリポジトリ全体をマップしよう」 | 今いるセグメントをマップしてください。残りは、検索が必要になったときに行を獲得します。 |
| 「このタスクにはマップは大げさだ」 | 部分マップでも、3回目の検索までには効果が現れます。 |
| 「ベースラインをスキップして、ただ適用しよう」 | ベースラインがなければ証拠はありません。まず測定してください。 |
| 「マップ全体を再生成したほうが速い」 | 再生成はキュレーションされた詳細を落とし、キャッシュを壊します。古い行を編集してください。 |
| 「スキャフォールドされたマップでカウントする」 | TODO 行でいっぱいのマップはドラフトであり、マップではありません。完成させるか削除してください。 |
| 「徹底するためにベンダーディレクトリも検索しよう」 | 生成されたコードはトークンが死ぬ場所です。それがタスクの主題である場合のみ検索してください。 |
プレフィックスを使用しない場合
- 単一ファイルのスクリプトと使い捨てリポジトリ:スコープするものがありません。
- 明白なファイルが1つあるタスク:それを開き、そのためのインフラを構築しないでください。
- パスがすでにそれを示している場合:
src/auth/内の検索にauth:という儀式は不要です。 - ベンダーまたは生成されたコード(タスクの主題でない限り)。
- 約100ファイル未満で構造が明白なリポジトリ:ディレクトリ名でスコープし、マップをスキップします。
リファレンス
references/namespaces.md: マップフォーマット、リポジトリ形状、マルチリポジトリスタッキングreferences/metrics.md: メトリクス定義、JSONLスキーマ、差分レポートscripts/init_namespaces.sh: 現在のリポジトリの名前空間マップをスキャフォールドscripts/check_namespaces.sh: マップをlint:デッドスコープ、重複タグ、ドラフトscripts/search.sh: スコープ検索をコマンドとして:解決、検索、拡大、記録scripts/suggest_map.sh: ログとツリーを読み、マップ編集を提案scripts/measure_search.sh: 検索を実行し、一度に記録scripts/report_metrics.sh: ログを読み返す:ヒット率、スコープ消費、差分scripts/session_start.sh: セッション開始フック用にマップ(+健全性)を出力scripts/install_hook.sh: devin/claude 用に SessionStart フックを配線scripts/doctor.sh: リポジトリのセットアップをヘルスチェック:マップ、lint、フック、インストールスタンプscripts/eval_scope.sh: スコープ検索とルートのトークン差分を測定scripts/eval_repo.sh: マップ内のすべての名前空間をlint + 評価、平均節約率%scripts/visualize.py: マップをファイルツリー上に、測定された節約額をHTMLレポートとしてレンダリングSPEC.md: namespaces.md フォーマット契約、マップを読み書きするツール向けintegrations/: セッション開始フックスニペット + コンシューマリポジトリ用のPR lintワークフロー
このスキルの中核的な仕事の外で、パイプラインおよびプロンプト作成者向けに隣接するプレイブック:references/index-prefixes.md、references/prefix-library.md、references/cache-ordering.md。