mantis-patch について
mantis-patchは、Mantisのセキュリティワークフローで指摘を修正・検証するスキルです。隔離環境で最小限のコード変更を作成してテストし、バイナリやファームウェアでソースコードがない場合は緩和策を提示します。
主な機能
- 01最小限のセキュリティ修正の作成
- 02隔離環境での適用と検証
- 03一時変更のロールバック
- 04指摘とパッチ状態の更新
- 05バイナリ向け緩和策の提示
活用シーン
- 01再現したソースコードの脆弱性を修正する
- 02隔離環境でパッチを検証する
- 03ソースコードのないバイナリの緩和策を検討する
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ google/ mantis --skill mantis-patchインストール後、Claude Code で/mantis-patchを入力して読み込まれたか確認します。
同梱ファイルreferences/patch_rebasing.md
詳細
パッチ適用(/mantis-patch)
システムの目標
セキュリティパッチ適用のエキスパートです。最小限かつ正確なコード修正を生成し、ソースコードファイルに適用して、隔離されたサンドボックス内で検証した後、長期メモリにログを追加します。
コマンド定義
- コマンド:
/mantis-patch [--target_root=<path>] [--state_root=<path>] [--snapshot_root=<path>] [--snapshot_id=<id>] [--snapshot_pinned=<true|false>] - 説明: トランザクション分離(シャドウディレクトリまたはファイルバックアップ)を使用して最小限のセキュリティ修正を生成し、パッチを適用して検証します。
- パラメーター(すべて省略可能。指定がない場合は従来の動作):
--target_root:読み取るコードスナップショットのルート(CODE_ROOT)。オーケストレーターがスナップショットを固定する場合は--snapshot_rootを渡します。--target_rootは、呼び出し元がすでに準備したツリーを渡す場合に使用します。--snapshot_root:この処理で固定された不変スナップショットのルート。--snapshot_id:固定されたスナップショットの SNAPSHOT_ID 文字列(スナップショット一致チェックで使用)。--snapshot_pinned:この処理で固定された不変スナップショットが存在する場合はtrue、false/省略時は縮退/レガシーモードです(後方互換性を参照)。--state_root:workspace/を含む Mantis 状態ディレクトリのルート(既定値は現在のディレクトリ)。このファイル内のすべてのworkspace/...パスは状態ルート相対であり、<state_root>/workspace/...以下に解決されます。
入出力の契約
- 読み取り対象:
workspace/findings/(patch_statusが"VERIFIED_SECURE"または"MITIGATION_PROPOSED"ではない、再現済み検出結果の JSON ファイル)。workspace/.mantis_state.json(現在のループパスを追跡するため)。workspace/.mantis_state.jsonのactive_snapshot(root、snapshot_id、snapshot_pinned)— Block A で解決され、--snapshot_*フラグが指定されていない場合に CODE_ROOT と、スナップショット一致チェックで使用する SNAPSHOT_ID を提供します。- 対象のソースコードファイル。
- 検出結果に含まれる再現スクリプトのパス(
repro_file_path)とコマンド(run_command)。 - 検出結果 ID に一致する既存のバックアップファイル(オプション B を使用する場合)。
- 書き込み対象:
- ソースコードの変更(トランザクションで適用し、ロールバックします)。
- 検出結果の JSON ファイルを直接更新(
"patch_status"、"patch_diff"、"reattack_status"と"reattack_variants"を含む再攻撃の詳細、履歴を設定)。 workspace/learnings.jsonlに追記。- 再利用可能なヘルパースクリプト
workspace/helpers/append_patch.py。
- 前提条件:
workspace/findings/に検出結果が存在すること。
- 冪等性の保証:
- スナップショットを考慮したスキップ:
patch_statusがすでに"VERIFIED_SECURE"または"MITIGATION_PROPOSED"の検出結果をスキップするのは、記録されたpatch_base_snapshotが現在の SNAPSHOT_ID と一致する場合に限ります(つまり、今回のスナップショットに対して検証済みの場合)。patch_base_snapshotが存在しない、空である、または現在の SNAPSHOT_ID と異なる場合、終端ステータスは古いものです。スキップせず、検出結果を再度開いて現在のスナップショットに対して再検証してください。レガシーモード(active_snapshotも--snapshot_*フラグもない場合)では、従来どおりpatch_statusのみでスキップします。 - トランザクション分離:一意に生成された一時ディレクトリ内でコードを変更するか、一時的なファイルバックアップ(
target.c.bak-[id])を作成し、完了時にベースラインの状態を復元します(try...finallyによるロールバック機構を使用)。 - 作成後は、既存の
append_patch.pyスクリプトを再利用します。
- スナップショットを考慮したスキップ:
手順
標準的なコードの動作を損なわずに、正常に再現されたセキュリティ上の欠陥を修正します。
パッチ適用と検証の段階を、次のとおり実行します。
-
スナップショットとロケーターの解決(コードに触れる前に一度実行):
0a. Block A(ロケーターの解決)を使用して、CODE_ROOT、SNAPSHOT_ID、snapshot_pinned、state_root を解決します。
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-adapterの Scenario 2 に従いハーネス側で行われます):active_snapshotが存在し、かつactive_snapshot.pass != state.pass_numberの場合、このパスではスナップショットを STALE として扱います。STOP 「stale active_snapshot: pass mismatch」とするか、HALT として処理を 縮退させます(snapshot_pinnedは実質的に false:権威ある判定は行わず、 Block B は NOT_MATCHED、再現はnot_attemptedとします)。 これは、再ピン留めせずに Stage 15 のパス増分をまたいでactive_snapshotを保持したカスタムハーネスを検出します。リファレンス メタエージェントは毎パス再ピン留めするため、このチェックがそこで発動する ことはありません。Block B 自体ではこれを検出できません(passは考慮せず、snapshot_idのみを確認します)。このステージでは、mantis-patch は対象コードを READ します(検出結果のみを 扱うステージではありません)。そのため、Block A の手順 1~6 をすべて実行 します。CODE_ROOT は不変のピン留め済みスナップショットです。そこに書き込み、 コンパイル、または再現テストを実行してはなりません(Block A の手順 4)。 変更はすべて、プライベートなシャドウ内で行ってください(下記の手順 2)。
0b. PATCH_MODE を決定します(解決済みの値を使った機械的な判定です)。
active_snapshotが存在せず、--snapshot_root/--snapshot_id/--target_rootのいずれも渡されていない ⇒ LEGACY モード(現在の動作。 手順 3 の新しい上限は適用されません)。snapshot_pinned == true⇒ PINNED モード(以下のゲートをすべて適用します)。snapshot_pinned == falseかつ SNAPSHOT_ID がリテラルのlive:で始まる ⇒ HALT/DEGRADED モード(スナップショットのピン留めが試みられましたが 失敗しました。このパスでは権威ある判定は禁止されます。手順 3 を参照)。
0c. 処理する各検出結果について、Block B(スナップショット一致チェック) を使って MATCHED/NOT_MATCHED の結果を算出します。
SNAPSHOT MATCH CHECK for finding F (decides MATCHED vs NOT_MATCHED): 1. If snapshot_pinned is false -> NOT_MATCHED. Stop. 2. Read F.discovery_commit: - missing OR empty OR the literal "MIXED" -> NOT_MATCHED. - not exactly equal to SNAPSHOT_ID -> NOT_MATCHED. - exactly equal to SNAPSHOT_ID -> MATCHED. There is no other route to MATCHED; never fuzzy-compare. The global "default the field and proceed" backward-compat rule does NOT apply to discovery_commit: absent = NOT_MATCHED. (There is NO separate "dirty" gate: a dirty tree's SNAPSHOT_ID already embeds the working-tree content hash, so within-pass findings MATCH and cross-pass bare-commit findings do not.)MATCHED/NOT_MATCHED の結果は、手順 2(分離モードの選択)と手順 3(判定)で 使用します。PINNED モードでは、この結果だけを理由に判定を格下げすることは ありません。NOT_MATCHED の検出結果は手順 3 のゲートで現在のスナップショットに 対して再検証され、合格した場合は現在の
patch_base_snapshotが付与されます。 -
パッチ対象の検出結果を読み込む:
workspace/findings/ディレクトリ内の JSON ファイルを読み込みます。現在のスナップショットに対して終端検証済みでは ない検出結果を絞り込みます。つまり、patch_statusが"VERIFIED_SECURE"または"MITIGATION_PROPOSED"であり、かつpatch_base_snapshotが現在の SNAPSHOT_ID(Snapshot & Locator Resolution 手順 0)と一致する場合を除き、未処理として扱います。終端状態の検出結果でも、patch_base_snapshotが存在しない/空である/異なる場合は STALE です。 再検証の対象に含めてください。(SNAPSHOT_ID がない LEGACY モードでは、これまで と同様にpatch_statusのみで絞り込みます。)対象に含めた検出結果のうち、repro_statusが"reproduced"であるもの、またはその検出結果がエクスプロイト チェーンであるものを残します。エクスプロイトチェーンの例としては、タイトルが"Exploit Chain:"で始まる場合、履歴に"chainer"ステージからのエントリーが ある場合、または"constituent_findings"プロパティが存在し、空でない場合が あります。該当するものがなければ、ユーザーに通知してください。 -
最小限のパッチを生成して適用する: 再現されたセキュリティ上の欠陥ごとに 処理します。
-
対象の種類を問わない対応(バイナリとソースコード): 対象がソースコード の場合は、以下の説明に従ってコードパッチの生成と適用を進めます。対象が コンパイル済みバイナリまたはファームウェアのバイナリで、ソースコードを 利用できない場合は、バイナリの変更やバイナリパッチ用スクリプトの作成を 試みないでください。代わりに、ブランチの分離/変更/差分の手順を省略し、 深い技術的知識を必要としない、本番環境でこの問題を緩和するための一般的かつ 概要レベルの推奨事項を作成します。この緩和策の文字列を
patch_diffフィールド の代わりに出力し、"patch_status"を"MITIGATION_PROPOSED"に設定します。 -
エクスプロイトチェーン: 検出結果がエクスプロイトチェーンである場合(タイトルまたは履歴の詳細に
"Exploit Chain:"が含まれている、あるいは"constituent_findings"プロパティが存在し、空でない場合)、コードパッチや差分を生成しないでください。代わりに、UUID の"constituent_findings"配列を読み取り、サブ検出結果を特定してください。これらの構成検出結果(ディスク上のworkspace/findings/<uuid>.jsonに記載されています)のパッチステータスを監視してください。重要: 構成検出結果の最新のパッチステータスがディスク上で確認できるよう、バッチ内のすべての個別の検出結果を処理し終えるまで、エクスプロイトチェーンの評価を保留してください。次の伝播ルールを順番に評価して、エクスプロイトチェーンのステータスを評価してください。
-
有効性チェック: 各構成検出結果の有効性
"status"を読み取ります。いずれかの構成検出結果の"status"が"FALSE_POSITIVE"の場合、エクスプロイトチェーンの検出結果の"status"をその値(例:"FALSE_POSITIVE")に更新し、チェーンに対するそれ以降のパッチ適用/検証を直ちにスキップしてください。いずれかの構成検出結果の"status"が"DUPLICATE"の場合は、その"duplicate_of"プロパティを再帰的にたどって正規の検出結果を特定してください。重複の解決手順:
- 検出結果ファイルの場所を特定する: 重複検出結果(または重複チェーン内の任意の親)のファイルが移動されている場合があります。次の場所を順に検索して、
<uuid>.jsonを探してください。workspace/findings/<uuid>.json(有効な検出結果)workspace/findings/.trash/<uuid>.json(重複排除済みのゴミ箱)workspace/archive/findings_pass_*/<uuid>.jsonまたはworkspace/archive/loop*_findings/<uuid>.json(過去のパスのアーカイブ)いずれの場所にもファイルが見つからない場合は、ファイル欠落エラーとして扱ってください。
- 循環の検出: 解決中、訪問済みの検出結果 UUID の集合を保持してください。現在の解決チェーン内で、すでに訪問した UUID に遭遇した場合は、検証エラーを発生させてください(循環を検出)。
- 最大深度: 再帰の深度は最大 5 ステップに制限してください。チェーンがそれより深い場合は中止し、エラーを報告してください。
- ステータスの取得: 正規の検出結果(
"status"が"DUPLICATE"ではない、または"duplicate_of"を持たないもの)まで解決したら、その正規の検出結果の"status"と"patch_status"を、後続のすべてのチェックと伝播に使用してください。エクスプロイトチェーンの検出結果自体を"DUPLICATE"に更新しないでください。
- 検出結果ファイルの場所を特定する: 重複検出結果(または重複チェーン内の任意の親)のファイルが移動されている場合があります。次の場所を順に検索して、
-
ファイルの欠落: いずれかの構成検出結果の JSON ファイルがディスク上にない場合は、チェーンの
"patch_status"を"ERROR"に設定してください。 -
構成検出結果が未設定または古い(保留): 構成検出結果は、次のいずれかに該当する場合、未検証として扱います。
"patch_status"が未設定(null または欠落しており、まだ再現/処理されていないことを示す)、または"patch_status"が終端状態であるものの、そのpatch_base_snapshotが存在しない/空である/現在の SNAPSHOT_ID と異なる(古いスナップショットで検証されている — Snapshot & Locator Resolution ステップ 0)。構成検出結果のいずれかが未検証の場合、チェーンの"patch_status"は未設定(null または欠落)のままにし、その構成検出結果が現在のスナップショットで再検証されるまで、チェーンのそれ以降の評価を保留/中断してください。(SNAPSHOT_ID がない LEGACY モードでは、従来どおり、このルールの「未設定」の部分のみを適用してください。) -
構成検出結果のエラー: いずれかの構成検出結果の
"patch_status"が"ERROR"の場合、チェーンの"patch_status"を"ERROR"に設定してください。 -
構成検出結果の失敗: いずれかの構成検出結果の
"patch_status"が"VERIFICATION_FAILED"の場合、チェーンの"patch_status"を"VERIFICATION_FAILED"に設定してください。 -
伝播の成功: すべての構成要素が現在のスナップショットに対する検証を完了している場合(各構成要素が
{"VERIFIED_SECURE", "MITIGATION_PROPOSED", "VERIFICATION_INCOMPLETE"}のいずれかであり、かつ、LEGACY モードを除き、各終端構成要素のpatch_base_snapshotが現在の SNAPSHOT_ID と一致する場合):- いずれかの構成要素が
"MITIGATION_PROPOSED"の場合、チェーンの"patch_status"を"MITIGATION_PROPOSED"に設定します。 "MITIGATION_PROPOSED"の構成要素がなく、いずれかの構成要素が"VERIFICATION_INCOMPLETE"の場合、チェーンの"patch_status"を"VERIFICATION_INCOMPLETE"に設定します。- すべての構成要素が
"VERIFIED_SECURE"の場合、チェーンの"patch_status"を"VERIFIED_SECURE"に設定します。
- いずれかの構成要素が
チェーンの検出事項自体については、ブランチ分離、テスト、再攻撃の手順を省略します。
-
-
任意の並列軌道探索: フレームワークがサブエージェントをサポートしている場合は、 複数のサブエージェントを並行して起動し、多様なパッチ実装を設計させることができます。 生成されたパッチのうち、標準機能を損なわずにコードを正常に保護できるものをすべてテストし、 最初に動作したパッチではなく、最適なパッチ(たとえば、最も簡潔で読みやすく、 慣用的な修正)を選択します。
-
元の不具合のあるファイルを読み、関数の依存関係や構造を把握します。
-
セキュリティ上の欠陥を緩和する、最小限かつ正しいパッチを設計します(たとえば、境界チェックの追加、 サイズの検証、NUL 終端文字の挿入)。他の機能は損なわないようにします。
-
トランザクション分離(VCS 非依存かつ安全): 安全性、信頼性、VCS 非依存性を確保するため、 VCS に基づくブランチ操作(
git branch、git checkout、git stashなど)は使用しないでください。実行環境に適した方法を使って、トランザクション分離を確実に行う必要があります。分離方法のゲート(機械的判定):
- snapshot_pinned が true(PINNED モード)の場合 → オプション A(一時ディレクトリによるシャドーイング)が必須です。オプション B と CODE_ROOT 配下に書き込むあらゆる方法は禁止です(Block A の手順 4:固定されたスナップショットには書き込まないでください)。
- それ以外で、検出事項が再試行(すでに以前の
"patch"履歴エントリまたはpatch_base_snapshotがある)である場合、または(PINNED モードで、その Snapshot Match Check の結果が NOT_MATCHED の場合)→ オプション A が必須です (検出事項と一致しなくなったライブツリーを編集する危険を避けてください)。NOT_MATCHED 条件の 「PINNED モード AND」という限定は重要です。LEGACY モード(snapshot_pinned=false)では、 Block B がスナップショットがないことによる結果として、すべての検出事項に対して NOT_MATCHED を返します。 これはドリフトを示すものではありません。そのため、NOT_MATCHED は「スナップショットが変更された」という意味を持つ PINNED の場合にのみ適用し、「スナップショットが存在しない」という意味の LEGACY の場合には 適用しないでください。 - それ以外(snapshot_pinned が false で、初回の試行、つまり以前の
"patch"履歴エントリもpatch_base_snapshotもない場合)は、オプション A(推奨)、オプション B:ファイルレベルのバックアップ、 または以下の不変条件を完全に満たす限り、オプション C:代替分離(たとえば、名前空間分離、 コンテナボリューム、ローカルサンドボックス)の設計・実装を選択できます。この条件は、LEGACY と HALT の両モードにおける 初回試行の検出事項に該当します(どちらにも保護すべき以前のパッチはなく、PINNED の読み取り専用スナップショット環境にもありません)。
どの方法を選んでも、以下の不変条件を保証する必要があります。
- ワークスペースを一切汚染しない: 元のソースツリーにバックアップファイルや中間ビルドファイルを残しません。
- 並行実行の安全性: 分離方法が、他の並行実行中のエージェントと競合しないようにします。
- ロールバックの保証: 失敗時に元の状態へ復元できるよう、すべての操作をエラートラップまたは
try...finallyブロックで囲みます。
-
オプション A:一時ディレクトリによるシャドーイング(推奨/PINNED の場合は必須)
-
警告/リソース上の制約: 数百 MB を超えるソースツリーの場合、またはホストを多くの並列パッチワーカーが共有している場合は、
PINNEDモードでない場合に限り、/tmpやメモリの枯渇を避けるため、変更されたファイルだけを扱う オプション B を選ぶとよいでしょう。PINNEDモードでは、サイズにかかわらずオプション B は禁止されています(スナップショットは読み取り専用です)。フルコピーを収められない場合、判定を捏造せず、ステップ 3 の HALT 処理を参照してください。 -
2 つのルートへのコピー: 一意に生成した SHADOW_ROOT(例:
mktemp -d/tempfile.mkdtemp())を、CODE_ROOT とあらゆる/workspace/パスの両方の外側に作成し、関連するソースツリーを、暗黙の cwd ではなく、Snapshot & Locator Resolution のステップ 0 で解決されたスナップショットである CODE_ROOT から SHADOW_ROOT にコピーします。CODE_ROOT は変更せず、読み取り専用のままにします。 -
すべての編集、コンパイル、再現テストは SHADOW_ROOT 内で行ってください。cwd = CODE_ROOT で、変更・コンパイル・再現を行うコマンドを実行してはなりません(Block A のステップ 4)。
-
-
重要なガード(パスと作業ディレクトリの安全性): 実行するすべてのコマンド(コンパイル、テスト、検証)が、作業ディレクトリ(
Cwd)を SHADOW_ROOT に明示的に設定して実行されるようにしてください。検出結果のrun_commandに、CODE_ROOT(スナップショット)またはライブソースルート配下の絶対パスが含まれている場合は、実行前にそのプレフィックスを SHADOW_ROOT 配下の対応するパスに書き換えてください。ガードチェック: パスを書き換えるときは、対象のコードベースファイルを示すパスのみを書き換えてください。パスが
/workspace/セグメントで始まる、またはこれを含む場合(Mantis の状態と検出結果が保存される場所)は、プレフィックスを置き換えないでください(検出結果/状態は、信頼できるstate_root/workspace/に保持する必要があります)。この区別が明確なのは、固定された SNAPSHOT_ROOT/CODE_ROOT に/workspace/セグメントが含まれないことが、オーケストレーターによるスナップショットのマテリアライズによって保証されているためです。CODE_ROOT またはstate_root/workspace/に対して、変更・検証コマンドを実行してはなりません。 -
{TARGET_ROOT}トークンの置換(実行前に必須):mantis-reproduceは、対象ツリーのパスにリテラルトークン{TARGET_ROOT}を使用してrun_command/reattack_run_commandを保存します(reproduce のステップ 3)。呼び出し側がこれを置換することを想定しています。保存されたrun_commandまたはreattack_run_commandを実行する前に、リテラルトークン{TARGET_ROOT}を、実行対象のツリーに置き換えてください。- Block-G の パッチ未適用ベースライン の実行時:CODE_ROOT からコピーした、新たに作成したパッチ未適用の CODE_ROOT コピーに置き換えます(新しい
mktemp -dコピー)。 - パッチ適用後の検証および 攻撃/再攻撃 の実行時:パッチ適用済みのシャドウコピーである SHADOW_ROOT に置き換えます。この置換は、上記の CODE_ROOT→SHADOW_ROOT のプレフィックス書き換えより 前に 行う必要があります(シャドウ実行では、トークンの展開によって CODE_ROOT パスになり、さらに書き換えが必要になる場合があります)。リテラルトークンが未置換のままだと、コマンドは失敗します → 証拠なし → 強制的に ERROR となります(Block F/Block G では、command-not-found/No-such-file を EVIDENCE ABSENT として扱います)。リテラルトークン
{TARGET_ROOT}を含むコマンドを実行してはなりません。
- Block-G の パッチ未適用ベースライン の実行時:CODE_ROOT からコピーした、新たに作成したパッチ未適用の CODE_ROOT コピーに置き換えます(新しい
-
CODE_ROOT(固定スナップショット)の元のソースファイルと、SHADOW_ROOT の変更済みファイルを比較して、統合パッチの差分を生成します。差分ヘッダーに CODE_ROOT/SHADOW_ROOT の絶対パスが漏れないよう、ラベルを使用してください。
-
完了したら、一時的なシャドウディレクトリを完全に削除してください。
-
オプション B:ファイル単位のバックアップ(フォールバック)
- 並行処理と排他性に関する警告: オプション B は元のワークスペース内のファイルを直接変更するため、他のワークスペース変更エージェントと並行して実行すると、並行処理上の安全性が保証されません。ロックによって、必ず順次実行されるようにしてください。
- 排他的なワークスペースロック: バックアップや編集を行う前に、エージェントは
workspace/.workspace_edit.lockの排他ロックを取得しなければなりません(Python ではfcntl.flockとfcntl.LOCK_EXを使用するか、同等のシステムレベルのロックを使用してください)。エージェントは、対象の検出事項に関するパッチ適用、検証、再攻撃、復元の全工程を通じて、このロックを継続して保持しなければなりません。最終的なベースラインファイルが復元または確定された後にのみ、ロックを解放してください。 - 実行前チェック: 編集の前に、現在の検出事項の ID に一致する既存のバックアップファイル(例:
*.bak-[current_finding_id])がワークスペース内にないか確認してください。見つかった場合は、それらを復元して削除してください。 - バックアップの作成: 変更する予定のソースファイルごとに、一意のサフィックスを付けたコピーを作成してください(例:
cp target.c target.c.bak-[finding_id])。 - 新規ファイル: ロールバック時に削除できるよう、新たに作成したファイルを記録してください。
- 変更の適用: 元の対象ファイルを直接編集してください。
- 統一差分の生成: ラベルを使用してヘッダーを正規化し、バックアップと変更後のファイルを比較してください(例:
diff -u --label target.c --label target.c target.c.bak-[finding_id] target.c)。
-
3 者間パッチのリベース(フェーズ 2 の段階的な効率化): 以前のパスのスナップショットとパッチが引き続きディスク上に存在する場合(以下の到達可能性チェックを参照)、パッチャーは新しいパッチを一から生成する代わりに、以前のパスのパッチを現在のスナップショットにリベースできます。これは、以前の修正が行番号のわずかなずれを除いて引き続き適用できる、一般的なケースでの最適化です。
- 方法: 以下の到達可能性条件(a)〜(d)がすべて成立する場合は、3-way マージの仕組み(
base/ours/theirsの一時コピー、git merge-file/diff3の呼び出し、コンフリクトマーカーの処理)について、ファイル読み取りツールで 3-Way Patch Rebasing を読みます。不確かな点がある場合、またはリファレンスを読み込めない場合は、必ず新しいパッチの生成にフォールバックします(Phase-1 の動作)。 - 使用条件(パッチャーが読み取れないフラグではなく、観測可能な状態による到達可能性): 以下の条件がすべて成立する場合にのみ、リベースを試みます。(a)前回パスのスナップショットディレクトリと、そのファイルのパッチ適用前のバージョンが、
<state_root>/.mantis_snapshots/配下のディスク上に実際に存在すること(保持設定によって残っていること。ベーススナップショットが GC されている場合は条件を満たさないため、フォールバックします)。(b)検出事項のsignatureが、以前のpatch_diffを持つアーカイブ済み検出事項と一致すること(同じバグ、同じシグネチャ)。これが、以降の条件で参照するアーカイブ済み検出事項です。(c)アーカイブ済み検出事項のpatch_base_snapshotが存在し、現在のSNAPSHOT_IDと異なること(以前のパッチが検証されたスナップショットが変更されていること。これが正しい「スナップショット変更」の判定です。PINNED モードでは、研究者がスタンプし、重複排除処理が補完し、計画処理は一致した検出事項を元のdiscovery_commitを保ったままそのままコピーするため、現在の検出事項のdiscovery_commitは常に== SNAPSHOT_IDになります。したがって、現在の検出事項に対して Block B を判定してはいけません)。アーカイブ済み検出事項のpatch_base_snapshotが存在しないか空の場合(以前のパスがレガシー、または Phase-2 より前のパッチャーがこれを書き込んでいない場合。手順 6 のヘルパーバージョンマーカーで検出します)、スナップショット変更の判定は UNKN となるため、必ず新しいパッチの生成にフォールバックします(変更されていない可能性のあるベースにリベースしてはいけません)。(d)検出事項の主ファイルがchanged_filesに含まれていること。signatureが存在しない場合(レガシー検出事項)は、条件(b)を満たせないため、新しいパッチの生成にフォールバックします。--snapshot_keepを条件にしてはいけません。このフラグはオーケストレーターに設定され、パッチステージには渡されず、読み取ることもできません。ディスク上の存在確認(a)が適切な観測可能な代替手段であり、どの保持設定でも機能します(デフォルトの keep-2 では直前のパスが保持されます)。changed_filesとchanged_files_statusは、workspace/.mantis_state.json(active_snapshotの読み取りにも使う同じ状態オブジェクト)から読み取ります。
- 方法: 以下の到達可能性条件(a)〜(d)がすべて成立する場合は、3-way マージの仕組み(
-
リベースの成功/失敗/ガードレール: 成功(クリーンマージ → リベース済みパッチを使用し、引き続き Block G を実行。履歴メモは
patch-rebased-from: pass_<N-1>)、失敗(マージコンフリクト/ファイル削除/名前変更 → 新しいパッチの生成にフォールバック)、およびガードレール(不確かな点が少しでもあれば Phase-1 にフォールバックし、未解決のコンフリクトや無関係な変更を含むリベース済みパッチは決して適用しない)については、 3-Way Patch Rebasing を参照してください。 -
--reattackでのパッチ未適用ベースラインの再実行(Phase 2):@mantis-reproduce --reattackサブエージェントが新しいスナップショット上のパッチを再攻撃する場合(Block B が NOT_MATCHED。PINNED モードのみで、パッチの検証後にスナップショットが変更されたことを意味します)、パッチ適用済みビルドに対して攻撃をテストする前に、必ず現在のスナップショット上でパッチ未適用のベースラインを再確立する必要があります。これにより、再攻撃を意味のあるものにできます。たとえば、現在のパッチ未適用スナップショットでバグが再現しなくなった場合(上流のコードで修正された場合など)、再攻撃の結果は合格ではなく、判定不能です。- 方法: パッチ済みへの攻撃の前に、現在のスナップショットの新規の未パッチコピーに対して再現プログラムを実行します(ブロック G ステップ 1 に従います)。未パッチのベースラインがトリガーしない場合(エビデンスが存在しない)、履歴メモとともに
reattack_status = "inconclusive_baseline_changed"を設定し、failed_to_bypassを主張してはいけません(パッチは生きたバグに対してテストされていないため)。未パッチのベースラインがトリガーする場合は、通常どおりパッチ済みへの攻撃を続行します。 - HALT モードの注記: HALT モード(
snapshot_pinned=false、live:SNAPSHOT_ID)では、ブロック B は常に NOT_MATCHED になりますが、これは真正のスナップショット変更を表すものではありません — ツリーをピン留めできなかったことを意味します。@mantis-reproduce --reattackサブエージェントは HALT での C5 再ベースラインをスキップし(reproduce C5 HALT ガードレールを参照)、既存の HALT 上限に従います。 - ガードレール: これは VERIFIED_SECURE ゲートを変更するものではありません — ブロック G は依然として未パッチのベースラインがトリガーすることを要求します。これはスナップショットが変更されたときに、再攻撃パスに再ベースライン手順を追加するだけです。
- 方法: パッチ済みへの攻撃の前に、現在のスナップショットの新規の未パッチコピーに対して再現プログラムを実行します(ブロック G ステップ 1 に従います)。未パッチのベースラインがトリガーしない場合(エビデンスが存在しない)、履歴メモとともに
-
-
パッチ後の検証実行: (コードパッチが存在しないバイナリのみの場合はこのステップをスキップしてください)。パッチが機能することを確認するために、分離された実行環境内で再現プログラムを再実行します。パッチを検証するには、再現エントリの正確な
"repro_file_path"と"run_command"を使用してください。-
Cwd の強制: 再現プログラムは、作業ディレクトリ(Cwd)をシャドウディレクトリに設定して実行する必要があります(オプション A を使用する場合)。コマンドが元のワークスペースではなく、シャドウディレクトリ内のコピーを対象としていることを確認してください。
-
到達シンクのエビデンスの定義 — ブロック F(到達シンクエビデンスゲート)。パッチ検証では、エビデンスは未パッチのベースラインに対して必要であり、パッチ後の攻撃実行に対して決して必要ではありません(正しいパッチは入力がシンクに到達する前に正当に停止します)。
REACHED-SINK EVIDENCE GATE (mechanical): 各再現スクリプトは、repro_hints に記録された 1 つのチャネルを通じて REACHED-SINK EVIDENCE を生成します: (a) スクリプト/ソースハーネス -> シンクを呼び出す前に、正確なバイト列 MANTIS_REACHED_ENTRYPOINT を サイドカーファイル $SENTINEL_FILE に書き込み、flush+fsync します(または バッファリングなしで書き込みます)。(ファイルは、バッファリングされた stdout を切り捨てる クラッシュを生き延びます。) (b) バイナリ / ファームウェア / 生ペイロード -> reached-sink の証拠は、ターゲットのシンク関数を 明示的に示す、キャプチャされたクラッシュバックトレースまたはサニタイザーフレーム (ASan/UBSan/MSan/TSan)です(ターゲットが生成したトレース)。ターゲットを呼び出す前に あなたが作成したラッパーが書き込むマーカーは SETUP EVIDENCE ONLY です。これは 「起動を試みた」ことを証明するものであり、「シンクに到達した」ことではありません。 したがって reached-sink の証拠としては不適格です。パス内マーカー(チャネル a)も、 ターゲットが生成したバックトレース/サニタイザートレース(チャネル b)も 達成できない場合、そのシンクには到達していません。 EVIDENCE PRESENT(reached-sink)= (チャネル a) サイドカーファイルに、 パス内で書き込まれた MANTIS_REACHED_ENTRYPOINT が含まれている、または (チャネル b) ターゲットが生成したバックトレース/サニタイザー出力がシンクを名指ししている。 ラッパーの起動前マーカーのみは EVIDENCE PRESENT ではありません。 EVIDENCE ABSENT には以下が含まれます: コンパイラ/ビルドの非ゼロ終了。終了コード 127 (コマンドが見つからない)。「No such file」メッセージを伴う終了コード 2。 DECISION GATE(特定の判定文字列ではなく DECISION をゲートします): - EVIDENCE が PRESENT の場合にのみ、repro_status = reproduced または statically_confirmed を記録します。ABSENT の場合 -> repro_status = not_attempted (再試行可能)、STOP。 - パッチ検証では、EVIDENCE は UNPATCHED ベースライン(Block G)で必要とされ、 パッチ適用後の攻撃実行では必要とされません(正しいパッチは正当にもシンクの前で 入力を停止します)。 - このターゲットに対して達成可能な証拠チャネルが存在しない場合は、 not_attempted / VERIFICATION_INCOMPLETE にダウングレードします。 決してマーカーを合成してはいけません。 -
あらゆる
VERIFIED_SECUREの前のハードゲート — Block G (Unpatched-Baseline + Benign-Control Gate)。CODE_ROOT の SHADOW コピー内で実行します。 Block G ステップ 1 の「SNAPSHOT_ROOT の FRESH UNPATCHED コピー」とは、 CODE_ROOT から取得した新しいコピーを意味します:未パッチのベースライン+パッチ適用後のゲート(VERIFIED_SECURE を設定する前): 0. 適用条件:repro_status == reproduced の場合にのみ適用されます(実行可能な PoC が存在します)。repro_status == statically_confirmed(実行可能な PoC がない)の場合、VERIFIED_SECURE は適用できないため、MITIGATION_PROPOSED を記録します(ERROR は絶対に設定しないでください)。 1. 未パッチのベースライン:Block F を使用して、SNAPSHOT_ROOT の未パッチの新規コピーに対してリプロデューサーを実行します。証拠がない場合、またはバグが発生しない場合は、patch_status = ERROR("reproducer_invalid_on_current_snapshot")とし、VERIFIED_SECURE を設定しないでください。 2. パッチ適用後の整合性(「パッチでブロックされた」ケースと「ビルドの破損」を区別します): - 必須:パッチ適用後のビルドが終了コード 0 でコンパイルされる必要があります。0 以外の場合は、VERIFICATION_INCOMPLETE です。 - 必須(無害なコントロール):正当な無害な(攻撃ではない)入力を、パッチ適用後のビルドで実行します。クラッシュせずにシンクパスに到達する必要があります(Block F による EVIDENCE PRESENT)。これにより、パッチがハーネス/エントリーポイントを破損させたのではなく、バグの範囲を狭めたことを証明します。このターゲットに対して無害なコントロールを構築できない場合、クリーン実行だけを根拠に VERIFIED_SECURE を主張することはできません。VERIFICATION_INCOMPLETE とし、無害なコントロールを実行できなかった理由を記録してください。 (厳格モード:無害なコントロールがシンクに到達しない場合、コンパイルと実行が正常でも VERIFIED_SECURE とするには不十分です。) 3. パッチへの攻撃:攻撃入力をパッチ適用後のビルドで実行します。VERIFIED_SECURE とするには、次のすべてが必要です。手順 1 で未パッチの状態で問題が発生した(証拠が存在する)、手順 2 の整合性が保たれている、手順 3 で攻撃によるクラッシュや問題の発生がない、かつ `--reattack` の実行でもバイパスされないこと。それ以外の場合は VERIFICATION_FAILED です。サニタイザー整合性のガードレール(Block G): このゲートでのすべての実行(未パッチのベースライン、無害なコントロール、攻撃、再攻撃)では、未パッチのベースラインで問題を発生させたものと同じサニタイザーフラグを使用する必要があります。ベースラインが UBSan(終了コード 0、リカバリーモード)によって問題を発生させた場合、攻撃実行も UBSan でコンパイルする必要があります。そうしないと、バグがまだ存在しているにもかかわらず、攻撃実行がトレースなしで終了コード 0 となり、誤って
VERIFIED_SECUREと判定されるおそれがあります(INV-1 違反)。後続のステージで同じフラグを使用できるよう、使用したサニタイザーフラグをrepro_hintsに記録してください。 -
HALT/DEGRADED の上限: PATCH_MODE が HALT/DEGRADED(snapshot_pinned が false で、SNAPSHOT_ID が
live:の場合)なら、このパスでは正式な判定は禁止されます。達成できるpatch_statusの上限は"VERIFICATION_INCOMPLETE"です。このモードで"VERIFIED_SECURE"を出力してはいけません。 (LEGACY モードには影響しません。) -
ファイル欠落のルール: 検証時にリプロデューサーのファイル(
repro_file_path)またはcode_pathsの対象ファイルが見つからない場合は、patch_statusを"ERROR"に設定してください。ファイルの欠落を「再現しなかった」として扱ってはいけません。また、ファイルが欠落した状態で"VERIFIED_SECURE"を出力してはいけません。(これは Block F/Block G の「No such file」/exit 127→ EVIDENCE ABSENT の経路でも強制されます。)
-
VERIFIED SECURE(以下の条件をすべて満たすことが必須): 以下のすべてを満たす場合にのみ、
patch_statusを"VERIFIED_SECURE"に設定します。- ブロック G が完全に通過している: 未パッチのベースラインが、CODE_ROOT の新しいコピー上で到達済みシンクの証拠 (ブロック F) を伴ってバグをトリガーした。パッチ適用済みビルドがコンパイルされた (終了コード 0)。良性/整合性コントロールが維持された。そしてパッチ適用済みビルドに対する攻撃入力がクラッシュ/トリガーしない。
- 再攻撃がバイパスに失敗している: 新しく独立した
@mantis-reproduce --reattackサブエージェント (下のブロックに従って起動) がreattack_status = "failed_to_bypass"を書き込んでいる。これは、非空のreattack_variants配列と ≥ 3 個の有効なバリアント入力 (reproduce ステップ 3a) がすべて、パッチ適用済みシャドウ上で元の脆弱性クラスをトリガーできなかったことを意味します。空または少なすぎるバリアントセットはVERIFICATION_INCOMPLETEが上限となり、VERIFIED_SECUREには決してなりません。 - デグレードしていない: PATCH_MODE が HALT/DEGRADED ではない。PATCH_MODE が HALT/DEGRADED の場合 (スナップショット不一致 / ピン留め不可能なスナップショット)、上限は
"VERIFICATION_INCOMPLETE"であり、"VERIFIED_SECURE"には決してなりません。ブロック G がベースラインを確立できなかったと報告した場合 (証拠が存在しない、または現在の未パッチスナップショットでバグがトリガーしない)、patch_statusを"ERROR"("reproducer_invalid_on_current_snapshot") に設定してください —"VERIFIED_SECURE"を出力してはいけません。ブロック G の適用可否チェックでrepro_status == statically_confirmedが見つかった場合は、"MITIGATION_PROPOSED"を記録してください (決して ERROR ではありません)。真の独立性を確保するため、パッチ適用済みシャドウ (パッチ適用後の SHADOW_ROOT のコピー) に対して新しい@mantis-reproduce --reattack --finding_id=[finding_id]サブエージェントを起動し、再攻撃を実行してください。
重要: 再攻撃のために
@mantis-reproduceサブエージェントを呼び出す場合:- オプション A (シャドウイング) を使用する場合 (PINNED モードでは常に)、次を渡してください:
--reattack--target_root=<PATCHED_SHADOW_ROOT>— 適用したパッチを含むシャドウコピー。--target_rootは AUTHORITATIVE かつ sentinel-EXEMPT (ブロック A ステップ 1a/2) であるため、サブエージェントはパッチ適用済みツリーを直接読み取ります。--snapshot_pinned=false— パッチ適用済みシャドウは意図的に変更されているため、reproduce サブエージェントはそのスナップショットのセンチネル/一致チェックをスキップしなければなりません。--state_root=<state_root>— あなたの authoritative な状態ディレクトリ (すべてのreattack_*フィールドと履歴がstate_root/workspace/の下に配置されるようにするため)。--finding_id=[finding_id]— 検証対象の検出の ID。
- オプション B (バックアップ) または オプション C (代替) を使用する場合 (LEGACY モードでのみ可能)、
--reattack、両方のルートをライブワークスペースに向けて (またはデフォルトの.のままにして)、--finding_id=[finding_id]を渡してください。
--reattackを付けて実行されるリプロデューサーエージェントは、その結果を元のワークスペース検出 (state_root/workspace/findings/) 内のプライマリ検出のreattack_status、reattack_file_path、reattack_run_command、reattack_outputフィールドに直接書き込み、最初のrepro_*フィールドはそのまま保持します。 -
VERIFICATION FAILED: サンドボックス実行で依然としてバグがトリガーされる場合、または再攻撃がパッチをバイパスすることに成功した場合、パッチは不十分です。修正を再評価して適応させてください。
-
VERIFICATION INCOMPLETE: パッチ適用後の初回検証実行は成功したものの、その後の再攻撃チェックがサンドボックスインフラのエラー、環境タイムアウト、またはプラットフォームの制限により失敗/タイムアウトした場合は、
"patch_status"を"VERIFICATION_INCOMPLETE"に設定してください。 -
再攻撃が未設定 / SNAPSHOT_MISMATCH → VERIFICATION_INCOMPLETE:
reattack_statusが未設定の場合(再攻撃サブエージェントがSNAPSHOT_MISMATCHまたはsetup_failedの履歴メモを残して未設定のままにした、あるいは再攻撃がまったく実行されなかった)、patch_statusを"VERIFICATION_INCOMPLETE"に設定してください — 決してVERIFIED_SECUREにしてはいけません。再攻撃ステータスが未設定であることは、独立性が確認されなかったことを意味します。SNAPSHOT_MISMATCHは、再攻撃がパッチの検証時とは異なるスナップショットに対して実行されたことを意味します。いずれの場合も、パッチは決定的に検証されていません。 -
結論が出ないベースライン → VERIFICATION_INCOMPLETE:
reattack_statusが"inconclusive_baseline_changed"の場合(再攻撃サブエージェントが現在のスナップショットで未パッチのベースラインを再実行し、バグがもはや発生しなかった — パッチの検証以降にベースラインが変化した)、patch_statusを"VERIFICATION_INCOMPLETE"(または詳細"reproducer_invalid_on_current_snapshot"を伴う"ERROR")に設定してください — 決して"VERIFIED_SECURE"にしてはいけません。パッチは現在のスナップショット上の生きたバグに対してテストされていません。それを安全であると主張することは、誤った権威ある判定となります。
-
-
パッチとロールバックトランザクションを抽出: (バイナリのみのターゲットではこのステップをスキップしてください)。コードベースを変更された状態のままにしないでください。最終的な結果(
VERIFIED_SECUREであるか、リトライを使い果たしたかのいずれか)が得られたら、次のようにします。- 成功した場合、正確な変更を表す unified diff を生成し、
"patch_diff"フィールドに保存します。- **オプション A(シャドウイング)**を使用している場合、CODE_ROOT 内の元のファイルとシャドウディレクトリ内の変更されたファイルを比較して、この diff を生成します。
- **オプション B(バックアップ)**を使用している場合、バックアップファイルと変更されたファイルを比較してこの diff を生成し、バックアップのサフィックスが現れないようにヘッダーを明示的にラベル付けします(例:
diff -u --label target.c --label target.c target.c.bak-[finding_id] target.c)。 - **オプション C(代替)**を使用している場合、未変更のベースラインファイルと最終的なパッチ済みファイルを比較する、クリーンで VCS に依存しない unified diff を生成します。
- 複数のファイルが変更された場合、個々の unified diff を生成し、それらをクリーンに連結して単一の
"patch_diff"文字列にします。VCS 固有の diff コマンドを使用しないでください。
- トランザクション形式のクリーンアップ / ロールバック: コードベースを元の状態に復元します。
- **オプション A(シャドウイング)**を使用している場合、一時的なシャドウディレクトリを完全に削除します(例:
rm -rf <shadow_directory>)。元のコードベースは一度も変更されていないため、それ以上の復元は不要です。 - オプション B(バックアップ)を使用している場合、バックアップファイルをターゲットファイルにコピーして戻すことで元のファイルを復元し(例:
cp target.c.bak-[finding_id] target.c)、バックアップコピーを削除し(rm target.c.bak-[finding_id])、パッチ適用プロセス中に作成された純新規ファイルを削除します。workspace/reproducers/ディレクトリ内に書き込まれた再攻撃/PoC スクリプトファイル、workspace/helpers/ディレクトリ内に書き込まれたヘルパースクリプト、およびメモリデータベースファイルworkspace/learnings.jsonlを削除しないでください。これらは明示的に保持する必要があります。 - **オプション C(代替)**を使用している場合、対応する破棄またはロールバックのステップを実行して、すべての変更痕跡を完全に消去し、一時リソースを削除し、元のワークスペースがクリーンなベースライン状態のまま残されることを確認します。
- **オプション A(シャドウイング)**を使用している場合、一時的なシャドウディレクトリを完全に削除します(例:
- 成功した場合、正確な変更を表す unified diff を生成し、
-
長期メモリへの追記(継続的なレビューのリンク): 処理した各セキュリティ上の欠陥について、
workspace/learnings.jsonlという名前のワークスペースデータベースファイルに、構造化された JSON の行を 1 行追記します(追記モードを使用)。これにより、ストラテジスト(/mantis-plan)が後続のパスでこれらの履歴レコードを読み取り、すでにパッチが適用されたファイルに対する修正案の提示を避けることができます。- メモリエントリの形式:
{"title": "[security_flaw_title]", "code_paths": ["[path1:line1]"], "status": "[VERIFIED_SECURE / MITIGATION_PROPOSED / VERIFICATION_INCOMPLETE / VERIFICATION_FAILED / ERROR]", "patch_base_snapshot": "[current SNAPSHOT_ID, or omit in LEGACY mode]", "snapshot": "[current SNAPSHOT_ID, or omit in MODE-OFF]"}
- メモリエントリの形式:
-
トークンを最適化したファイル更新: LLM の出力トークンを最小限に抑えるため、JSON オブジェクト全体を出力に再度含めたり、手動で書き直したりしないでください。 代わりに、最初の検出事項の更新時に、再利用可能なヘルパースクリプト(例:
state_root/workspace/helpers/append_patch.py)を作成してください。ヘルパーの最初の行をバージョンマーカーコメントにしてください:# MANTIS_HELPER_VERSION = 2。既存のヘルパーを再利用する前に、その最初の行を読み取ってください。正確なマーカーMANTIS_HELPER_VERSION = 2が含まれていない場合、そのヘルパーは古いバージョンの処理に由来するため、古いものとみなされます(patch_base_snapshotを書き込めません)。再利用できるのはマーカーが一致する場合のみです。新しいパラメーターを指定して既存のヘルパーを実行し、必要なフィールドを追加してください。既存のオブジェクトに、次の内容を追加してください:
"patch_status"フィールド("VERIFIED_SECURE"、"MITIGATION_PROPOSED"、"VERIFICATION_INCOMPLETE"、"VERIFICATION_FAILED"、または"ERROR"のいずれか)。- 現在のSNAPSHOT_ID(Snapshot & Locator Resolutionの手順0)を設定した
"patch_base_snapshot"フィールド。この判定が得られたスナップショットです。このフィールドを省略できるのは、SNAPSHOT_IDが存在しないLEGACYモードの場合のみです。このフィールドにより、スナップショットを考慮したスキップ(冪等性の保証)と、パス間でのチェーンの伝播が正しく行われます。 - パッチが成功した場合は、統合差分を含む
"patch_diff"フィールド。 - 再攻撃を実施した場合は、
"reattack_status"、"reattack_file_path"、"reattack_run_command"、"reattack_output"、および"reattack_variants"フィールド("reattack_variants"内の各オブジェクトは、正確に{"description": "...", "triggered": true/false}を含む必要があります)。 "history"配列へのエントリ:
{ "stage": "patch", "action": "patched", "details": "Patch status evaluated as [VERIFIED_SECURE/MITIGATION_PROPOSED/VERIFICATION_INCOMPLETE/VERIFICATION_FAILED/ERROR] on snapshot [patch_base_snapshot or 'legacy']", "pass_number": <current_pass_number>, "timestamp": "<current_iso8601_timestamp>" }
完了したら、ユーザーに通知してください。