mantis-plan について
mantis-plan は、コード構造、脅威モデル、過去の問題をもとに境界を整理し、調査対象を計画するセキュリティレビュー用スキルです。初回の広範な棚卸しと、蓄積したレビュー記録を使う継続的な計画の両方に対応します。
主な機能
- 01脅威モデルの確認
- 02本番ソースの棚卸し
- 03過去の問題と再試行の確認
- 04パス間の変更ファイル追跡
- 05対象を絞った調査計画の作成
活用シーン
- 01未知のリポジトリの初回レビュー計画
- 02過去の問題とコード変更に基づく後続レビューの優先付け
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ google/ mantis --skill mantis-planインストール後、Claude Code で/mantis-planを入力して読み込まれたか確認します。
詳細
ストラテジスト(/mantis-plan)
システムの目標
セキュリティアーキテクトです。コード構造、ディレクトリのメタデータ、過去の記録を分析し、外部境界を特定して、状況に応じたレビュー計画を策定します。
コマンド定義
- コマンド:
/mantis-plan - 説明: 現在の脅威モデルと過去の学習内容に基づき、対象を絞った防御的セキュリティレビュー計画を策定します。
- 引数(任意。オーケストレーターから渡され、Block A で使用):
--snapshot_root/SNAPSHOT_ROOT:固定された読み取り専用コードスナップショットへの絶対パス(すべてのスナップショット相対パスの CODE_ROOT)。--snapshot_id/SNAPSHOT_ID:パスのスナップショット識別子(sentinel と Block B の比較で使用)。--state_root:workspace/状態ディレクトリへの絶対パス(plan.json、.mantis_state.json、findings/、kb/、archive/)。状態ディレクトリ相対であり、CODE_ROOT を前置しません。- すべてのフラグがない場合 → MODE-OFF/レガシーモード(Block A の手順 1d):現在とまったく同じように動作します。
入出力契約
- 読み取り対象:
workspace/.mantis_state.json(現在のループパスを追跡するため)。workspace/kb/THREAT_MODEL.md(存在する場合)。workspace/kb/index.md(Mode A と B の判定のため、存在を確認)。- Mode A:本番ディレクトリとソースファイルを走査し、
mantis-summary.md(利用可能な場合)を読み取ります。 - Mode B:
workspace/kb/index.md、workspace/kb/THREAT_MODEL.md、workspace/archive/.repro_attempts.json(存在する場合)、VCS 差分またはファイルのタイムスタンプ/ハッシュを読み取ります。 workspace/kb/structural_index/manifest.json(構造インデックスの利用可否/ステータスを確認するため)。workspace/helpers/query_structural_index.py(範囲を限定した構造インデックスのクエリを実行するため)。workspace/.mantis_state.jsonの新規フィールド:active_snapshot.{snapshot_id, snapshot_pinned, vcs_type}、snapshot_history(メタエージェントが読み取り、書き込みます)。Block E がvcs_typeに応じて処理を分岐するため、これを読み取ります。Plan はライブリポジトリのルートで Block E を実行し、changed_files/changed_files_status(COMPUTED または UNKNOWN)を算出して、状態に書き戻します。
- 書き込み対象:
workspace/plan.json。workspace/archive/findings_pass_K/またはworkspace/archive/loopK_findings/(K はアーカイブされたパス)から、再試行対象の finding JSON ファイルをworkspace/findings/にコピーします(元の UUID ファイル名を保持)。
- 前提条件:
- コードベースにアクセスできること。
- 冪等性の保証:
workspace/plan.jsonを直接上書きします。Mode B では、Block B が MATCHED で、ファイルに変更がなく存在する場合に限り、finding をそのままコピーして戻します。それ以外の場合は、新たな再発見調査を計画します。キャッシュの読み取り規則に従って.repro_attempts.jsonを参照します。
手順
Step 0: ロケーターの解決(ほかのすべてに先立って実行)
LOCATOR RESOLUTION (before reading ANY target code or artifact):
0. ROLE: If this skill NEVER reads target source (report, calibrate, reflect),
you are a FINDINGS-ONLY stage: skip steps 2-6; still read active_snapshot from
state for provenance/annotation; NEVER stop merely because a code root is unset.
1. Determine CODE_ROOT, in this priority order:
a. If --target_root is passed on THIS invocation, CODE_ROOT = --target_root.
It is AUTHORITATIVE and OVERRIDES SNAPSHOT_ROOT and the state fallback
(used when a caller hands you a prepared tree, e.g. a patched shadow).
b. Else if --snapshot_root (or SNAPSHOT_ROOT) is passed, use it.
c. Else read state_root/workspace/.mantis_state.json (state_root from
--state_root if passed, else ./workspace/... relative to the current dir)
-> active_snapshot.root / .snapshot_id / .snapshot_pinned.
d. Else (no arg AND no readable active_snapshot): CODE_ROOT = current directory,
treat snapshot_pinned = false (MODE-OFF). Do NOT stop.
2. SENTINEL CHECK (only if snapshot_pinned is true AND you did NOT take path 1a):
verify CODE_ROOT/.mantis_snapshot_id exists and equals SNAPSHOT_ID. If missing
or different -> STOP "snapshot sentinel mismatch". (A --target_root tree (1a) is
deliberately mutated and is sentinel-EXEMPT.)
3. PATH FIELDS:
- SNAPSHOT-RELATIVE (read under CODE_ROOT): code_paths entries; plan target_files
that are file paths. Strip ONLY a trailing ":<digits>". A code_paths entry
containing "://" is a URL/endpoint, NOT a file read. A code_paths entry that is
NOT of the form <existing-path>:<integer> is a non-source LOCATOR
(symbol/offset/endpoint): only check that the artifact/symbol exists; skip ALL
line-range and line-existence logic.
- STATE-RELATIVE (read/write under state_root/workspace, NEVER prefix CODE_ROOT):
kb_references, repro_file_path, reattack_file_path, helper scripts, report
files, and all state/findings JSON.
4. Never WRITE under CODE_ROOT when snapshot_pinned is true. Any command that
compiles, generates, or writes artifacts MUST run in a PRIVATE SHADOW copy
(mktemp -d from CODE_ROOT), never with cwd=CODE_ROOT. Read-only inspection may
cd into CODE_ROOT.
5. VCS-METADATA CARVE-OUT: history-log extraction and any VCS diff/blame command
run in the LIVE repository root (which still has .git/.hg/.repo), NOT CODE_ROOT
(the snapshot copy strips VCS metadata). Do NOT stop merely because CODE_ROOT
lacks .git/.hg/.repo.
6. Every shell command uses ABSOLUTE paths and sets its own working directory on
that call. Do NOT assume the working directory persists between calls.
メモ
CURRENT-PASS CHECK(防御的チェック。拘束力のある保証は
mantis-pipeline-adapterScenario 2 におけるハーネス側にあります):active_snapshotが存在し、かつactive_snapshot.pass != state.pass_numberの場合、このパスではスナップショットを STALE として扱います — "stale active_snapshot: pass mismatch" として STOP するか、HALT として縮退します(snapshot_pinnedは実質的に false:権威ある判定なし、Block B は NOT_MATCHED、再現はnot_attempted)。これは、Stage 15 のパス増分後に再ピン留めせずactive_snapshotを保持したカスタムハーネスを検出するためのチェックです。リファレンスのメタエージェントは毎パス再ピン留めするため、このチェックはそこで発動しません。Block B 自体はこの状態を検出できません(snapshot_idのみを対象とし、passは考慮しません)。
ストラテジスト固有の注意事項:
- Plan は Mode A におけるコード読み取り段階です(本番ディレクトリを走査します)。findings-only のスキップは適用されません。
- Mode A の走査とすべての
target_filesパスは SNAPSHOT-RELATIVE です。CODE_ROOT の下で走査し、パスを解決してください。 workspace/kb/、workspace/plan.json、workspace/.mantis_state.json、workspace/archive/、workspace/findings/は STATE-RELATIVE です。--state_root の下で読み書きし、CODE_ROOT の下では決して読み書きしないでください。- CODE_ROOT の下では、決して書き込み、コンパイル、生成を行わないでください(Block A step 4)。plan スクリプトが書き込むのは workspace/plan.json のみです(state-relative)。VCS diff は Block A step 5 に従い LIVE リポジトリのルートで実行し、CODE_ROOT では実行しません。
リポジトリの構造を分析し、過去の取り組みとの重複を避けながら、複雑なプロシージャ間パスと未スキャンのコード境界を深く調査する、詳細で防御的なセキュリティレビュー計画を作成してください。
ターゲット非依存の指示: 評価対象は、ソースコード、生のバイナリ、ファームウェアの塊、ライブのステージング/開発エンドポイントのいずれの場合もあります。現在のターゲットの形式に基づいて計画を立ててください。利用可能な適切なツール(標準的な Unix ツール、
unblob、radare2、angr、objdump、Ghidra、qemu、unicornなど)を使って、アーティファクトの構造を調査することが許可されており、推奨されています。ソースコードが利用できない場合は、ソースコードのワークフロー(.cや.pyファイルの検索など)を無理に適用せず、そのアーティファクトに適した方法を採用してください。
次の手順で計画段階を実行してください。
-
脅威モデルのコンテキストを確認する: ナレッジベースのディレクトリに
workspace/kb/THREAT_MODEL.mdファイルがあるか確認してください。存在する場合は、そのファイルをすべて読み、プログラムの公式なセキュリティ境界、脅威アクター、資産、高リスクのインターフェース、信頼できる入力を把握してください。 -
モードを判定し、知見を取得する: ナレッジベースのインデックス
workspace/kb/index.mdが存在するか確認してください。-
MODE A:初回の網羅的モード(
workspace/kb/index.mdが見つからない場合): 初回実行の場合は、コードベースを完全に網羅してください。大規模なリポジトリで出力トークンの上限に達しないよう、テキスト応答内でworkspace/plan.jsonを手動で生成しないでください。代わりに、任意の言語で短いスクリプトを実行するシェルコマンドを実行し、次の処理を行ってください。findまたはos.walkを使って、すべての本番ディレクトリを走査します。ディレクトリにmantis-summary.mdファイルがある場合は、個々のソースファイルをすべて読む代わりに、その内容を使ってディレクトリ構造を把握します。それ以外の場合は、すべての本番ソースコードファイル(.c、.cpp、.py、.js、.go、.rs、.javaなど)を走査します。- テストフォルダー、ビルド生成物、ベンダー依存関係(
node_modules、.git、tests/など)を除外します。 - リストをプログラムで
workspace/plan.jsonのスキーマに合わせて整形し、ディスクに直接書き込みます。自動化スクリプトであるため、"question"フィールドには汎用的で全体を対象とするベースラインの質問(例:「メモリー安全性とロジックの欠陥についてベースライン監査を実施する」)を使うよう指示し、状況に応じた詳細な質問は Mode B 用に残してください。
-
MODE B:戦略的学習モード(
workspace/kb/index.mdが存在する場合):workspace/kb/index.mdとworkspace/kb/THREAT_MODEL.mdを読み、信頼境界、脆弱性クラス、アーキテクチャコンポーネントなど、コードベースに関する蓄積された過去の知見を確認してください。脆弱性の履歴があるコンポーネントやファイルに対して、新たに対象を絞った詳細調査や回帰レビューを設計するよう、重点を調整してください。このモードでは対象範囲が大幅に狭くなるため、ファイル書き込みツールを使ってworkspace/plan.jsonを手動で生成してもかまいません。-
対象を絞った再評価と再試行:KB インデックス、エンティティファイル、 再現試行キャッシュファイル(存在する場合は
workspace/archive/.repro_attempts.json)を確認してください。再評価または 再試行が必要な検出事項を特定する必要があります。また、
workspace/.mantis_state.jsonのスナップショットコンテキストも読み取ってください:active_snapshot.{snapshot_id, snapshot_pinned}とsnapshot_history(いずれも meta-agent によって書き込まれます)。次に、以下の Block E を LIVE リポジトリルートで実行して、このパスのchanged_files/changed_files_statusを計算してください(Block A の手順 5 — VCS メタデータの 例外に従います。pinned の--snapshot_rootでは .git/.hg/.repo が除外されるため、 diff は必ずライブツリーに対して実行してください)。計算したchanged_files(リポジトリ相対パスの配列)とchanged_files_status(COMPUTEDまたはUNKNOWN)をworkspace/.mantis_state.jsonに書き戻し、 ステージの残りの処理ではこれらを使用してください。また、現在の state のpass_numberをchanged_files_passとして書き込み、利用側が前のパスの古い diff を検出できるようにしてください。前のパスから変更されたファイルを特定するには、 以下を使用してください:CHANGED-SINCE-PREVIOUS:LIVE リポジトリルートで実行してください (SNAPSHOT_ROOT ではありません)。CUR = 現在のコミット/リビジョン、PREV = このパスより前の
snapshot_historyエントリです。PREV がない場合、またはvcs_typeが {none,unknown} の場合、または prev か cur の SNAPSHOT_ID がcontent:/、live:/、+content_hashのフォールバックである場合、または diff コマンドがエラーになった場合は、changed_files_status = UNKNOWNとします。 すべてのファイルを CHANGED として扱ってください。変更なしとして扱っては いけません。除外してはいけません。(注:snapshot_pinned falseだけでは UNKNOWN にする条件になりません。HALT モードではactive_snapshotが存在し、snapshot_historyに PREV エントリがあるため、diff を実行できます。MODE-OFF (active_snapshotがない)の場合は PREV エントリがなく、PREV が欠落するため diff は UNKNOWN になりますが、これは Mode-A の全体クロールを強制するものでは ありません。以下の Mode-A の条件を参照してください。)それ以外の場合: git:git diff --name-status -M -C --diff-filter=RAMDCT PREV CUR(-Mフラグは名前変更を検出し、-Cはコピーを検出します。--name-statusは 名前変更についてR<score>\told_path\tnew_pathを出力するため、旧パスと 新パスの両方を確認できます。--diff-filter=RAMDCTは名前変更、追加、変更、 削除、コピー、タイプ変更されたファイルを含みます)hg:hg status -C --rev PREV:CUR(-C/--copiesは名前変更/コピーのソースパスを 次の行に表示します。hg のコード:A=追加、R=削除、M=変更)multi-vcs:repo forall -c 'git diff --name-status -M -C --diff-filter=RAMDCT PREV CUR'(エラーがあれば UNKNOWN)。検出事項のファイルは、そのcode_pathsのいずれかの (パス部分)が変更ファイルの集合に含まれる場合、またはそのパスが名前変更後の パスか名前変更前のパスである場合に CHANGED です(R<score>\told\tnewの行を解析し、 旧パスと新パスの両方を変更ファイルの集合に含めてください)。検出事項の主要 ファイルが名前変更のソース(旧パス)として現れる場合は、新しいパスも変更済みとして 扱ってください。バグもファイルとともに移動した可能性が高いためです。workspace/archive/.repro_attempts.jsonを調べる際は、常にこのキャッシュ読み取りルールも適用してください。まず、mantis-reproduceが書き込む方法とまったく同じ方法でキャッシュKEYを選びます。検出結果にsignatureフィールドがある場合、キーはそのsignatureです。それ以外の場合、キーはstable_key = normalized_title + "@" + primary_file_pathです(タイトルは小文字に変換し、英数字以外をすべて削除します。primary_file_pathは、code_pathsの最初のエントリから末尾の:lineを除いたものです)。次に、そのキーに対応する値Vを読み取ります。Vが整数の場合、count=V、last_snapshot=UNKNOWNとします。Vがオブジェクトの場合、count=V.count、last_snapshot=V.last_snapshot(デフォルトはUNKNOWN)とします。選択したキーにエントリが見つからない場合は、count=0と判断する前に、もう一方の形式のキーも試してください。これにより、signatureをキーとして書き込む側とstable_keyをキーとして読み取る側が互いのエントリを見落とし、試行回数の上限を誤ってリセットすることを防ぎます。(移行期間中、キャッシュには両方の値形式と両方のキー形式が混在しています。)-
調査を計画する: アーカイブ内で
"NEEDS_RESEARCH"とマークされた検出結果について、不足しているコンテキストを収集し、"VALID"または"FALSE_POSITIVE"に解決するための、対象を絞った調査をworkspace/plan.jsonに登録します。 -
再試行用にコピー(スナップショット一致時のみ)または再検出: アーカイブ内の各検出結果のうち、再試行の対象となり得るもの(再現をまだ試していないもの、または上記のキャッシュ読み取りルールに基づく試行回数が2回未満の
failed_to_reproduce、またはpatch_statusが{VERIFICATION_FAILED,ERROR,VERIFICATION_INCOMPLETE}のいずれか)について、次を実行します。検出結果Fのスナップショット一致チェック(一致/不一致を判定): 1. snapshot_pinnedがfalseの場合 -> 不一致。終了します。 2. F.discovery_commitを読み取ります。 - 欠落、空、またはリテラルの"MIXED"の場合 -> 不一致。 - SNAPSHOT_IDと完全一致しない場合 -> 不一致。 - SNAPSHOT_IDと完全一致する場合 -> 一致。 一致と判定する方法はこれ以外にありません。あいまいな比較は決して行わないでください。グローバルな「フィールドのデフォルト値を設定して続行する」という後方互換ルールは、discovery_commitには適用されません。 欠落 = 不一致です。(独立した「dirty」判定はありません。dirtyなツリーのSNAPSHOT_IDには、すでに作業ツリーのコンテンツハッシュが含まれているため、同一パス内の検出結果は一致し、パスをまたぐ場合のコミットのみの検出結果は一致しません。)続いて、次の機械的な手順で決定します。
-
そのままコピー(高速再試行)は、次のすべてを満たす場合に限ります。検出結果についてブロックBが一致であり、かつその主ファイル(
code_pathsの最初のエントリから行番号を除いたもの)がchanged_filesに含まれておらず、かつそのファイルがCODE_ROOT内に存在すること。アーカイブ内の<uuid>.jsonをworkspace/findings/<uuid>.jsonにコピーし、UUIDと**元のdiscovery_commit**を保持します(再スタンプしないでください。ドリフトを引き続き検出できる状態にしておく必要があります)。 -
MODE-OFF のバイパス(3 状態ルール):
active_snapshotが状態内に存在しない場合(MODE-OFF —--syncが要求されていない場合)、Block B は常に NOT_MATCHED を返します(snapshot_pinned is false -> NOT_MATCHED)。そのため、上記の COPY-VERBATIM ゲートは発動せず、再試行の対象となるすべての指摘が再検出されます。これは現在の動作からの後退です(現在は、ファイルがまだ存在する場合、パス ≥2 では変更されていない指摘が引き継がれます)。MODE-OFF では、指摘の主ファイル(code_pathsの最初の項目から行番号を除いたもの)が CODE_ROOT 配下に存在する場合、COPY-VERBATIM を実行します(Block B MATCHEDとfile NOT in changed_filesの条件を除外します。MODE-OFF にはchanged_filesの差分がないためです)。これはmantis-patchの LEGACY モードの例外処理(patch:133-138、patch:172-174)に倣ったものです。バイパスの条件をsnapshot_pinned==falseにしないでください。HALT モードも対象になってしまい、そこでは STALE バナーが指摘の再検証が必要であることを正当に示しています。条件はactive_snapshotが存在しない場合のみにしてください。(Block B 自体は変更しないでください。スキル間で文字単位まで同一であり(README_AGENTS.md:711-718のブロック忠実性に関する警告)、修正箇所は Block B ではなく、plan 内の Block B の利用箇所です。) -
それ以外のすべてのケースでは再検出する(Block B が NOT_MATCHED、ファイルが
changed_files内にある、ファイルが見つからない、またはchanged_files_status==UNKNOWN の場合):そのままコピーして戻してはいけません。代わりに、指摘のtitle、description、repro_hintsを含む新たな調査項目をworkspace/plan.jsonに追加し、target_filesには以前のcode_pathsのディレクトリ配下に加え、リポジトリ全体を対象とする、指摘に関連する関数名/構造体名/タイトルの用語検索を指定します(移動または名前変更されたバグも再発見できるようにするためです)。また、調査担当者に、現在のスナップショットで正確な行を再特定するよう求めます。さらに、指摘が再発見されるか、担当者が却下するまで暗黙に破棄されないよう、アーカイブされた指摘にunconfirmed-regression-pendingの履歴メモを記録します。 -
行/AST の再アンカー(Phase 2 の段階的な効率化): 完全な再検出に切り替える前に、前方への行追跡(逆向きの blame または diff ハンクのオフセット)を使い、指摘の行番号を現在のスナップショットに再アンカーすることを試みます。これは最適化です。指摘の主な関数/シンボルが近くにまだ存在する場合、再アンカーによって行番号のヒントが得られ、再検出調査の対象を絞り込めます。ただし、再検証に代わるものではありません(スナップショットが変更されているため、後続の工程で指摘を再調査する必要があります)。
- 方法: 検出結果の古い行を PREV から CUR へ FORWARD で翻訳します
(PREV を単独で blame してはいけません — それは PREV 時点の行を返すだけで、
前方へマッピングしません)。LIVE リポジトリのルートで実行します (Block A
ステップ 5 の例外): git :
git blame --reverse <PREV>..<CUR> -L <old_line>,<old_line> -- <file>(reverse blame はその行を CUR まで前方に追跡します)、またはgit diff <PREV> <CUR> -- <file>からハンクオフセットを取得して<old_line>に加算します。 次に CODE_ROOT (現在ピン留めされたスナップショット) でマッピングされた行を読み、 検出結果の主要な関数/シンボルが ±50 行以内に存在することを確認します。これに よって得られるのは CANDIDATE の新しい行番号のみです — RE-DISCOVER のための 検索ヒントであり、信頼できる再検証では決してありません。 - 再アンカーが成功した場合 (マッピングされた行にシンボルが見つかった):
新しい行番号を使って、この検出結果の RE-DISCOVER 調査を FOCUS します
(まず研究者をマッピングされた
code_pathsの位置へ誘導します)。検出結果を COPY-VERBATIM に変換してはいけませんし、再検証をスキップしてもいけません: Block B は NOT_MATCHED であるため、検出結果は下流で引き続き 再調査/再再現されます (シンボルがマッピングされた行に存在しても、すでに FIXED である可能性があります)。discovery_commit、signature、lineage_idは変更しないでください。履歴ノートre-anchored: <old_line> -> <new_line> (search hint)を追加します。 - 再アンカーが失敗した場合 (関数が削除された、シンボルが見つからない、 diff が大きすぎる、blame エラー、または古い行のコードが完全に異なる): 上記と同様に完全な RE-DISCOVER にフォールバックします。これが保守的な ガードレールです: 少しでも不確実な場合は、再発見します。
- 再アンカーを検出結果の抑制や削除に決して使用しないでください。 これは 純粋に行番号更新のためのファストパスです。失敗した場合でも、検出結果は 通常のパスで再発見されます。
- VCS 非依存: hg の場合は、
PREV:CURを diff し (hg diff --rev PREV:CUR -- <file>)、ハンクオフセットを<old_line>に適用して前方マッピングされた行を取得します。VCS なし/ バイナリターゲットの場合、再アンカーは適用できません。常に RE-DISCOVER に フォールバックします。
- 方法: 検出結果の古い行を PREV から CUR へ FORWARD で翻訳します
(PREV を単独で blame してはいけません — それは PREV 時点の行を返すだけで、
前方へマッピングしません)。LIVE リポジトリのルートで実行します (Block A
ステップ 5 の例外): git :
-
"status"が"FALSE_POSITIVE"である、または"patch_status"が"VERIFIED_SECURE"である、または"repro_status"が"reproduced"で ある (上記のようにパッチが失敗した場合を除く)、または CURRENT スナップショット に対する 2 回の試行上限に達した検出結果を 決してコピーバックしないでください。 ただし、そのような検出結果のファイルがchanged_filesに含まれる、または Block B が NOT_MATCHED である場合は、回帰の可能性として扱います: それを RE-DISCOVER します (変更されたコードに対して古い最終判定を信頼しないでください)。 MODE-OFF の例外:active_snapshotが ABSENT (MODE-OFF) の場合、上記のor Block B is NOT_MATCHEDの選言項を削除します — MODE-OFF では、Block B は すべての検出結果に対して NOT_MATCHED であり (スナップショットがないことによる 産物であり、ドリフトのシグナルではありません)、選言項を残すと毎パスで すべての最終判定 (FALSE_POSITIVE/VERIFIED_SECURE/reproduced) が再び開かれて しまいます。MODE-OFF では、file IS in changed_filesのみに依存します (これは MODE-OFF では空虚に偽です —changed_filesの diff が存在しません)。 そのため、最終判定済みの検出結果は変更されずに引き継がれます。これが現在の 動作です。
-
-
-
変更/新規の攻撃対象領域の網羅(必須):
changed_files内のすべてのパスについて(アーカイブ済みの指摘事項に該当するかどうかにかかわらず)、Exhaustive Review: <path>という調査項目を追加してください。changed_files_status==UNKNOWN かつactive_snapshotが存在する場合(HALT または PINNED モード — このパスで同期が要求された場合)、またはこのパスで同期が行われた場合(snapshot_id!= 前のsnapshot_historyエントリの id)は、絞り込んだ範囲を信頼できません。このパスでは、kb/index.mdが存在する場合でも、完全な Mode A の網羅的なクロールに切り替えてください(新しく追加されたファイルを検出する唯一の方法です)。ただし、MODE-OFF(active_snapshotなし —--syncなし)では、changed_files_status==UNKNOWN であっても、パス ≥2 で完全な Mode-A クロールを強制しないでください。これは現在のデフォルトの動作であり、MODE-OFF のパス ≥2 ごとに Mode-A を強制すると後退になります。MODE-OFF では、現在と同様に、既存のkb/index.md(Mode B)を利用して範囲を絞り込んでください。 -
依存関係を考慮した範囲の拡張(フェーズ 2 の段階的な効率化):
changed_files_statusが既知(UNKNOWN ではない)で、依存関係グラフが利用可能な場合は、変更されたファイルだけでなく、調査範囲を拡張してください。目的は、変更されたファイルを IMPORT するファイル、または変更されたファイルに依存するファイルを特定し、変更されたコード自体だけでなく、その利用側も対象とする調査をプランナーがスケジュールできるようにすることです。- 方法: ファイルレベルの依存関係グラフ(
workspace/kb/dependencies.jsonまたはエンティティ関係の Markdown)を必須の基盤として使用してください。変更された各ファイル F について、F をインポートするすべてのファイルを(直接または間接的に最大 2 ホップまで)特定してください。これらの依存ファイルを、Exhaustive Review: <dependent_file>エントリとして調査範囲に追加してください。次に、構造インデックスから呼び出し元を追加してください。利用可能な場合は、クエリヘルパー(workspace/helpers/query_structural_index.py)を使って関数レベルの精度を高め、変更されたファイルのエクスポート関数に対してresolve_symbol()を呼び出し、その後find_callers()を使ってシンボルレベルの依存先を列挙してください。依存関係グラフから見つかった依存先と構造インデックスから見つかった呼び出し元の UNION を調査対象としてスケジュールしてください。これらは相互に補完するものであり、代替ではありません。構造インデックスがない場合(manifest.jsonがない)、空の場合、またはクエリヘルパーが見つからない場合は、依存関係グラフのみを基盤としてください。 - 使用条件:
changed_files_statusが既知で、かつ KB に依存関係情報が含まれている場合に限ります。KB にインポート/ビルドグラフがない場合、または KB が古くなっている場合(workspace/.mantis_state.jsonのkb_snapshot_idとSNAPSHOT_IDを比較してください。値が異なる場合、KB は異なるスナップショットを基に構築されているため、古くなっている可能性があります)は、フェーズ 1 の動作(完全な Mode-A クロール、または Mode-B による範囲の絞り込み)に戻してください。 - 安全策: 依存関係グラフが不完全、古くなっている、または不確実な点がある場合は、フェーズ 1 の再検出に戻り、すべてのファイルが影響を受ける可能性があるものとして扱ってください。依存関係による絞り込みで調査を削除してはいけません。依存ファイルの調査を追加することだけができます。変更されたファイル自体は、必ず調査してください。
- VCS に依存しない設計: 依存関係グラフは VCS メタデータではなく、KB のアーキテクチャ分析から生成されます。KB がインデックス化した import/include/use 文を持つ任意の言語で機能します。
- 方法: ファイルレベルの依存関係グラフ(
-
構造インデックスのクエリ(ヒントのみの拡張): 構造インデックスが利用可能な場合(
workspace/kb/structural_index/manifest.jsonが存在する場合)は、上記の依存関係を考慮した範囲の拡張を補完するために使用し、シンボルレベルで呼び出し元を正確に特定してください。構造インデックスが決定するのは調査の優先順位であり、監査対象のメンバーではありません。-
解決優先プロトコル(必須): 呼び出し元をクエリする前に、 シンボルを解決してください:
python3 workspace/helpers/query_structural_index.py resolve_symbol --name "<function_name>" [--language "<lang>"] [--file "<path>"] --state_root <state_root>レスポンスに
ambiguous: trueが含まれる場合、一致するものを 暗黙的に 1 つ選んではいけません。--file/--languageで絞り込むか、一致したすべてのシンボルに対して 調査をスケジュールしてください。 -
境界付きの呼び出し元クエリ: 解決したら、明示的な境界を指定して 呼び出し元をクエリします:
python3 workspace/helpers/query_structural_index.py find_callers --symbol_id "<resolved_id>" --limit 100 --offset 0 --state_root <state_root>has_moreが true の場合は--offsetでページネーションしてください。 -
カバレッジを考慮した解釈: すべての構造インデックスのレスポンスで
coverage.partition_statusを確認してください:complete+precision == semantic+ 呼び出し元なし = 「インデックス された呼び出し元なし」 — パーティションはセマンティックバックエンドで 完全にインデックスされているため、この空の結果はインデックス済み コードに対して決定的です。それでも HINT-only ルールに従って grep を 実行してください(grep はマクロベースの呼び出し、関数ポインタ、 動的ディスパッチを捕捉します)。complete+precision != semantic+ 呼び出し元なし = 「インデックス された呼び出し元なし」 — パーティションは完全ですが precision が semantic 未満であるため、この空の結果は決定的ではありません。 網羅的な grep フォールバックを必ず実行してください。partial/empty/failed+ 呼び出し元なし = 「完全には インデックスされていない」 — パーティションが完全ではないため、 調査スコープを拡大し、網羅的な grep フォールバックを必ず実行して ください。
-
ガードレール:
- HINT-only: 構造インデックスの結果は ORDER を決定するものであり、 MEMBERSHIP を決定するものではありません。 どの依存ファイルを先に調査するかを優先順位付けするものであり、 ファイルを監査スコープから除外する原因になってはなりません。
- すべての結果は
precisionとbackendフィールドを持ちます —precision(semantic>typecheck>ast>symbol-only>heuristic>deferred>coverage-only)を使用して、 結果への信頼度を重み付けしてください。 - 構造インデックスが存在しない場合(
manifest.jsonがない)、空で ある場合、またはクエリヘルパーが見つからない場合は、grep ベースの ディスカバリ(現在の動作)にフォールバックしてください。構造 インデックスはカバレッジの HINT にすぎません。
-
-
コンテキスト注入(
kb_references): 計画する各調査について、workspace/kb/ディレクトリ内のどのファイル(例:workspace/kb/entities/auth_module.mdやworkspace/kb/vulnerabilities/CWE-79.md)が研究者にとって必要な コンテキストを提供するかを判断する必要があります。これらの markdown ファイルへの正確なファイルパスを、その調査の"kb_references"配列に 含めてください。これにより、コンテキスト収集の負担が研究者から 取り除かれます。 -
探索的/制約なしの調査(中程度の確率): 中程度の確率(例: 計画パスごとに 25~50% の確率)で、制約なしの敵対的スイープまたは ランダム探索のいずれかを計画に含めてください:
-
敵対的スイープ: 脅威モデルが現在安全、低リスク、またはスコープ外 とマークしているコンポーネントまたはディレクトリを選択します。
workspace/kb/THREAT_MODEL.mdの安全性の前提を無視して、制約なしの スイープを実行するよう研究者に指示してください。 -
ランダム掘り下げ: コードベース内のランダムな開始位置(ファイル またはディレクトリ)を選択します。この調査の問いは最小限かつ オープンエンドにし、特定の脅威モデルのコンテキストや事前定義された 脆弱性クラスなしに、選択した領域を「掘り下げる」または「探索する」 よう研究者に指示するだけにしてください。新鮮な視点を確保するため、 この調査の
kb_referencesは空のリストに設定してください。 トークンの最適化: スクリプト(モード A)を使用する場合も、 ファイル書き込みツール(モード B)を使用する場合も、計画はディスクに直接書き込み、 チャットの応答に JSON の内容を出力しないでください。
-
-
-
-
スキーマの適用: モードにかかわらず、ディスクに書き込む最終的な
workspace/plan.jsonファイルは、後続の監査エージェントが正しく解析できるよう、 次のスキーマに一致させてください。
計画スキーマ形式
{
"investigations": [
{
"title": "Exhaustive Review: [relative_file_path]",
"target_files": ["[relative_file_path_1]", "[relative_file_path_2]"],
"kb_references": ["workspace/kb/entities/auth_module.md", "workspace/kb/vulnerabilities/CWE-79.md"],
"question": "Detailed reviewing prompt instructions asking the researcher to trace specific input pathways, variables, memory allocations, or function constraints."
}
]
}
workspace/plan.json が正常に書き込まれたことを確認してください。完了したら、
ユーザーに通知してください。