mcpField
M
mantis-history

mantis-history

github.com/googleセキュリティ2.7k1.5k 回インストール3 日前に更新
リポジトリ

mantis-history について

mantis-historyは、Mantisのセキュリティワークフローでバージョン管理履歴を調べるスキルです。関連する変更を選別して修正内容を分析し、後続工程で利用できるJSONL形式の記録を作成します。

主な機能

  1. 01バージョン管理履歴の分析
  2. 02セキュリティ関連変更の選別
  3. 03脆弱性と修正情報の抽出
  4. 04結果のキャッシュと履歴改変の検出
  5. 05JSONL形式での履歴出力

活用シーン

  1. 01過去の変更からセキュリティ修正を探す
  2. 02後続分析に履歴情報を提供する
  3. 03脆弱性の種類と影響ファイルを整理する

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/google/mantis --skill mantis-history

インストール後、Claude Code で/mantis-historyを入力して読み込まれたか確認します。

詳細

履歴アナライザー(/mantis-history)

システムの目標

過去の脆弱性を抽出します。リポジトリのバージョン管理システム (VCS)の履歴を分析し、過去の脆弱性、セキュリティ関連の修正、パッチ、 関連ファイルを抽出して、後続のスキルに役立つ過去の学習データベースを作成します。

コマンド定義

  • コマンド: /mantis-history
  • 説明: リポジトリのバージョン管理システム(VCS)の履歴を分析して 過去の脆弱性と修正を抽出し、構造化された過去の学習ファイル (workspace/historical_learnings.jsonl)を生成します。
  • 引数(任意。オーケストレーターから渡され、Block A が使用): --snapshot_root/--snapshot_id/--state_root。履歴はスナップショットではなく、 ライブリポジトリのルート(Block A のステップ 5)から VCS ログを読み取ります。 --state_root はキャッシュ/出力/スクリプトの配置にのみ使用します。すべて 指定されていない場合は DEGRADED になります(現在と同様に、ライブ cwd で動作します)。

入出力の仕様

  • 読み取り対象:
    • workspace/.mantis_state.json(現在のループパスを追跡するため)。
    • コードベースのディレクトリ構造と主要ファイル(スタックを特定するため)。
    • VCS 履歴ログ(コミットメッセージ、タイトル、差分)。
    • mantis-summary.md(任意。利用可能な場合)。
    • 内部履歴分析キャッシュ(任意。存在する場合)。
  • 書き込み対象:
    • VCS 抽出スクリプト(その場で workspace に書き込みます)。
    • workspace/historical_learnings.jsonl。
    • 内部履歴分析キャッシュ。
    • すべて --state_root/workspace/ 配下(キャッシュ、historical_learnings.jsonl、 抽出スクリプト)に保存し、対象ツリーの外部に保持します。任意の history_status マーカー(UNSUPPORTED_VCS / PARTIAL_SHALLOW)。
  • 前提条件:
    • 対象リポジトリと VCS ログにアクセスできること。
  • 冪等性の保証:
    • キャッシュを信頼できる情報源とします。毎回実行時にキャッシュから出力 DB を 再構築し、キャッシュが空でない限り、出力を空に切り詰めることはありません。 VCS 履歴の書き換え(_analyzed_head が到達不能になった場合)または vcs_type/リポジトリ ID の変更時にキャッシュを無効化します。VCS が none/ unknown の場合、このステージは空の DB と history_status=UNSUPPORTED_VCS を 書き込み、終了します。

手順

ステップ 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.

履歴分析における重要事項:固定されたスナップショットのコピーでは .git/.hg/.repo が 取り除かれています。そのため、Block A のステップ 5 に従い、すべての VCS ログ/差分/ blame コマンドは、CODE_ROOT の配下ではなく、ライブリポジトリのルート(Mantis の起動元の 作業ディレクトリ)で実行する必要があります。CODE_ROOT に VCS メタデータがないからといって 処理を中止しないでください。キャッシュ、workspace/historical_learnings.jsonl、 生成した抽出スクリプトは --state_root/workspace/(STATE 相対)に書き込んでください。 同期/クリーンアップで消去されないよう、対象ツリーには絶対に書き込まないでください。 エントリーには、来歴情報として active_snapshot.snapshot_id のみを記録してください。

あなたのタスクは、コードベースのアーキテクチャーを分析し、セキュリティに関係する履歴の範囲を判断し、プロジェクトのバージョン管理システム(VCS)から過去の脆弱性を抽出して記録するスクリプトをその場で作成することです。

次の手順で履歴分析ステージを実行してください。

  1. フェーズ 1:コードベースを分析し、対象とする履歴を定義する:

    • 既存の概要(利用可能な場合は mantis-summary.md など)を読み取るか、 コードベースのルート構成を手早く確認して、主要なファイル、プログラミング言語、 中核となるコンポーネントを把握します。
    • メモリー破損、認証バイパス、SQL インジェクション、バッファーオーバーフローなど、 このプロジェクトに関係する過去のセキュリティ問題の種類と、対象とするキーワードや コミットを判断します。
  2. フェーズ 2:履歴抽出スクリプトを作成する:

    • VCS サポートガード(スクリプトの書き込み/実行の前に実行): .mantis_state.json の vcs_info から vcs_type を判定します(または LIVE ルートで検出します)。vcs_type が none または unknown である場合、あるいは VCS 履歴に到達できない場合は、空の workspace/historical_learnings.jsonl を書き込み、ファイル先頭またはサイドカーのマーカーに history_status = "UNSUPPORTED_VCS" を設定して、終了します — 履歴を捏造してはいけません。multi-vcs(.repo)の場合は、サブプロジェクトごとに履歴を反復処理するか、エラーになる git 形式のスクリプトを実行するのではなく、history_status = "UNSUPPORTED_VCS" を設定した空のファイルを書き込みます。SHALLOW git クローン(git rev-parse --is-shallow-repository == true)の場合は、続行しますが history_status = "PARTIAL_SHALLOW" を設定して、下流のステージが「このファイルに過去の脆弱性なし」を「クリーン」と解釈しないようにします。

    • 状態ファイル workspace/.mantis_state.json から現在のパス番号を読み取り、現在の ISO 8601 タイムスタンプを解決します。

    • リポジトリのバージョン管理システム(VCS)の履歴ログと対話するスクリプト(例:Python、bash、または任意のもの)をワークスペースに直接書き込みます。

    • コスト効率とスケールの最適化: 履歴分析のコスト効率を維持し、効率的に実行するために、スクリプトは以下の最適化を実装する必要があります:

      • コミットメッセージ/説明文の事前フィルタリング: diff を取得する前に、 スクリプトはコミットメッセージのスクリーニングに用いる関連キーワードを 動的に決定する必要があります。これを行うには、まず対象範囲にある リポジトリのファイルと言語/ドメインを調査して主要なスタック(例: ソフトウェアかハードウェア/RTL か)を特定し、次にセキュリティ/バグに 関するキーワードのカスタマイズされたリストを LLM/分析エージェントに 問い合わせるか、より広範なキーワードセットにこれらのドメイン固有の 用語を追加して使用します。メッセージやタイトルがこれらの関連キーワードに 一致しないリビジョンはスキップし、対象範囲のコードベースに無関係な チェンジセットを不必要に取得して分析することを避けます。
      • diff のフィルタリングとサイズ制限: 非本番コード(例: テスト、 ドキュメント、設定ファイル)のみを変更するコミットは無視します。 過度に大きな diff(例: 数千行を超える変更)を持つコミットはスキップ します。これらは通常、個別のセキュリティパッチではなく自動フォーマット 変更や大規模なリファクタリングであるためです。
      • 結果のキャッシュ(キャッシュが信頼できる唯一の情報源): workspace/ 配下にローカルキャッシュ(JSON または SQLite)を維持し、 revision_id -> analyzed をマッピングします。さらに、分析済みの 各リビジョンについて抽出された完全なレコード、_analyzed_head ハイウォーターマーク、およびキャッシュが構築された対象の vcs_type + リポジトリの識別情報を保存します。実行のたびに、 キャッシュから workspace/historical_learnings.jsonl を 再構築します(キャッシュが「分析済み」と言っているという理由だけで リビジョンをスキップし、その結果出力が空のままになるのは 非同期化バグです)。空でない出力 DB を空に切り詰めては 決していけません。_analyzed_head より新しいリビジョンのみを 分析します。 書き換え検出: キャッシュを信頼する前に、_analyzed_head が 現在のライブ履歴で依然として解決できることを確認します(git: git cat-file -e <_analyzed_head> が成功し、かつ git merge-base --is-ancestor <_analyzed_head> HEAD; hg: hg log -r <_analyzed_head> が成功する)。解決できない場合 (force-push / rebase / squash)または vcs_type/リポジトリの 識別情報が変更された場合は、キャッシュを無効化し、最初から 再抽出します。
      • バッチ処理(diff のバッチ化): コミットの diff ごとに 1 回の LLM 呼び出しを行う代わりに、スクリプトは複数のコミットの diff と メッセージ(例: 3 から 5 コミット)を 1 回の LLM 呼び出しに まとめる必要があります。LLM にバッチ内のすべてのコミットを分析させ、 バッチの検出結果の JSON 配列を返すように依頼することで、リクエストの オーバーヘッドとコストを削減します。
      • モデル選択: 最初のコミット分析/フィルタリングには軽量で コスト効率の高いモデルを使用し、疑わしい脆弱性のより深い検証が 必要な場合にのみ、より重いモデル層にフォールバックします。
    • 詳細分析: セキュリティに関連しそうなリビジョンまたはコミットに ついては、スクリプトはコミットの diff とメッセージ/変更説明を 取得する必要があります。

    • LLM/エージェント分析: スクリプトは(例: サブエージェント メッセージや Agent API サブコマンドを介して)API 呼び出しを行うか、 LLM サブエージェントを使用して、変更の diff とメッセージを分析し、 そのリビジョン/コミットがセキュリティ修正であったかどうか、影響を 受けたコンポーネント、脆弱性の種類、影響、および緩和 diff を 判断する必要があります。API 呼び出しを最小限に抑えるために、 バッチ処理とキャッシュを使用するようにしてください。

    • 情報の欠落: セキュリティ関連のキーワードが存在しないことに 過度に重きを置かないでください。多くのセキュリティ修正には CVE が 割り当てられず、多くのセキュリティ脆弱性は、それが脆弱性であると 気付かないまま修正されています。

    • 出力形式: スクリプトに、抽出された検出結果を workspace/historical_learnings.jsonl という名前の JSONL ファイルに 出力するよう指示し、次の形式に一致させます:

履歴から得た知見のスキーマ形式(workspace/historical_learnings.jsonl)
{
  "revision_id": "...",
  "title": "...",
  "description": "...",
  "code_paths": ["file:line_number"],
  "vuln_type": "...",
  "mitigation_diff": "...",
  "cve": "...",
  "history": [
    {
      "stage": "history_extractor",
      "action": "created",
      "details": "Extracted from repository revision history.",
      "pass_number": <current_pass_number>,
      "timestamp": "<current_iso8601_timestamp>"
    }
  ]
}
  1. フェーズ 3:実行と検証:
    • 作成したスクリプトを実行して、VCS の履歴を分析し、リビジョンを処理して、workspace/historical_learnings.jsonl ファイルを生成します。
    • スクリプトが完了するまで待ち、workspace/historical_learnings.jsonl が正常に書き込まれ、抽出されたデータが含まれていることを確認します。

完了したら、ユーザーに通知してください。

コメント