patch について
patchは、検証済みの脆弱性情報から人による確認用の候補差分を作るセキュリティスキルです。パッチ内容を出力するだけで、対象リポジトリは変更しません。
主な機能
- 01検出結果から候補差分を生成
- 02静的モードと実行検証モードに対応
- 03重大度またはIDで検出結果を選別
- 04チェックポイントから処理を再開
- 05人による確認用パッチを出力
活用シーン
- 01検証済みのスキャン結果に対する修正案作成
- 02パイプライン結果から候補パッチを生成
- 03適用前にセキュリティ修正案を確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ anthropics/ defending-code-reference-harness --skill patchインストール後、Claude Code で/patchを入力して読み込まれたか確認します。
同梱ファイルREADME.md
詳細
patch
静的パイプラインの第 3 段階です(/vuln-scan → /triage → /patch)。
優先順位付けされた検証済みの検出結果を、差分候補に変換します。
このスキルは、対象リポジトリに差分を適用することは決してありません。出力は
./PATCHES/ 内の不活性なテキストであり、人間が確認して別途適用します。詳しくは
docs/patching.md#reviewing-generated-patches を参照してください。設計上、--apply や
--approve フラグはありません。適用機能が存在しないため、プロンプトインジェクションで
利用されることもありません。
/patch <findings-path> [--repo PATH] [--top N] [--id fNNN] [--model M] [--fresh] を呼び出します。
引数($ARGUMENTS から解析します):
- findings path(最初の位置引数。必須):
TRIAGE.json、VULN-FINDINGS.json、パイプラインのresults/<target>/<ts>/ディレクトリ、または/triageの取り込みテーブルが認識する任意の JSON。 --repo PATH:対象コードベース。読み取り専用です(デフォルトは cwd)。静的モードでは 必須です。引用されたファイルがこのパス配下に解決されない場合、スキルは停止します。--top N:深刻度が最も高い真陽性のうち、上位 N 件のみをパッチします(静的モード)。--id fNNN:この ID の検出結果のみをパッチします。--model M:実行検証モードでvuln-pipeline patchに渡されます。静的モードでは 無視されます(サブエージェントはオーケストレーターのモデルを継承します)。--fresh:./.patch-state/のチェックポイントを無視して、最初から開始します。
ツール。 Read、Glob、Grep、Write、Task を優先します。Glob や Grep が
提供されないセッションもあります。allowed-tools は権限フィルターであり、ローダーでは
ありません。これらが利用できない場合は、上記で許可された読み取り専用の Bash コマンドに
切り替えます。検索には rg/grep、列挙には ls、
内容の確認には head/file/wc、JSON の取り込みには jq を使います。それ以外で
Bash が許可されるのは、python3 .claude/skills/_lib/checkpoint.py(状態の I/O)と
vuln-pipeline patch(実行検証を行う委譲処理)のみです。find は許可されていません。
書き込み範囲。 Write ツールで指定できるのは、./PATCHES/ と
./.patch-state/ 配下のパスのみです。--repo には書き込まず、git apply や
patch を実行せず、対象ソースを編集しないでください。これが必要と思われる手順があれば、
その手順は誤りです。
チェックポイント(Phase 0 の前および各 Phase の後に実行)
状態は ./.patch-state/ に保存されるため、新しい /patch セッションでもパッチや
レビュアーのサブエージェントを再生成せずに再開できます。チェックポイントの I/O はすべて
python3 .claude/skills/_lib/checkpoint.py 経由で行います(アトミックで、JSON 検証済み)。
Write→--from パターンにより、リポジトリ由来のバイト列が Bash の argv に入ることを
防ぎます。ペイロードをヒアドキュメントや標準入力で渡さないでください。
状態ファイル:progress.json(唯一の信頼できる情報源:{"status": "running"|"complete", "phase_done": N, "shards_done": [...]})、
phaseN.json、_chunk.tmp。
実行開始時。 Bash:
python3 .claude/skills/_lib/checkpoint.py load ./.patch-state
status == "absent"または"complete"、あるいは$ARGUMENTSに--freshがある場合 → 新規に開始します。Bash:python3 .claude/skills/_lib/checkpoint.py reset ./.patch-stateを実行し、 Phase 0 に進みます。status == "running"かつphase_done == Nの場合 → 再開します。phase0.json~phaseN.json(およびshards_doneに記載されたshard_*.json)を順に読み込み、作業状態に統合して、Resuming from checkpoint: Phase N completeと出力し、Phase N+1 に進みます。出力が すでにチェックポイントに保存されているサブエージェントは再生成しないでください。
各 Phase N の終了時。 Write ツールで ./.patch-state/_chunk.tmp に
Phase の JSON を書き込み、その後 Bash:
python3 .claude/skills/_lib/checkpoint.py save ./.patch-state <N> <name> --from ./.patch-state/_chunk.tmp
実行終了時。 PATCHES.md と PATCHES.json を書き込んだ後、Bash:
python3 .claude/skills/_lib/checkpoint.py done ./.patch-state 4
Phase 0:引数の解析とモードの検出
0a. $ARGUMENTS を解析
findings path(最初の位置引数)、--repo(デフォルトは .)、--top、
--id、--model、--fresh を抽出します。findings path が指定されていない場合は、
停止して確認してください。
0b. モードを検出する
調査結果のパスを確認します。
- 実行検証モード:パスが、
reports/manifest.jsonl、found_bugs.jsonl、またはrun_*/result.json(パイプライン出力)を含むディレクトリである場合。ただし、その中のどこかにINCIDENTS.jsonがある場合を除きます。D&R の実行ディレクトリにもrun_*/result.jsonが含まれますが、インシデントは静的モードに振り分けられます。調査結果には PoC バイト列、ASAN トレース、再現コマンドが含まれており、パイプラインの検証手順を適用します。 - 静的モード:それ以外の場合です。
TRIAGE.json、VULN-FINDINGS.json、INCIDENTS.json(/dnr-*の出力)、一般的な調査結果 JSON、または Markdown が該当します。PoC はなく、判定役は新しいコンテキストのレビュアーです。
作業状態に mode を記録します。どちらのモードもフェーズ 1 の取り込みは共通で、その後フェーズ 2 で分岐します。
チェックポイント: Write ツールで ./.patch-state/_chunk.tmp に以下を書き込みます。
{"phase": 0, "mode": "exec"|"static", "args": {repo, top, id, model, findings_path}}
続いて Bash で実行します。
python3 .claude/skills/_lib/checkpoint.py save ./.patch-state 0 mode --from ./.patch-state/_chunk.tmp
フェーズ 1:取り込みと正規化
入力の契約は /triage のフェーズ 1 と同じです。すべての入力形式を、辞書のフラットな findings[] に正規化します。存在する情報だけを取り込み、存在しない情報を推測してはいけません。
1a. 認識するコンテナー(優先順位順)
TRIAGE.json—.findings[]を読み込みます。verdict == "true_positive"に絞り込みます。 これが正規入力です。すでに検証、重複排除、優先順位付け、担当者タグ付けが済んでいます。VULN-FINDINGS.json—.findings[]を読み込みます。未検証のため、Warning: VULN-FINDINGS.json is unverified scanner output. Consider /triage first.を表示して続行します。INCIDENTS.json(/dnr-hunt//dnr-respondの出力)—/triageの 1a と同じ方法でマッピングします。.incidents[]のエントリーごとに 1 件の調査結果とし、ネストされたvuln.file/vuln.line/vuln.typeをfile/line/categoryに、vuln.mechanismとimpactをdescriptionにマッピングし、pocを保持します。confirmed_exploitedインシデントのpoc.commandは、修正の回帰チェックになります。トップレベルのruled_out配列は調査結果ではありません。Warning: INCIDENTS.json has not been triaged. Consider /triage first.を表示して続行します。fileのないインシデントは、他の調査結果と同様に 1c に従います。- パイプライン結果ディレクトリ —
reports/bug_NN/ごとに 1 件の調査結果とします。report.jsonをdescriptionに、crash.crash_typeをcategoryに、ASAN のトップフレームをfile/lineにマッピングします。デリゲートフラグ--bug N用にbug_id = NNを記録します。 - トップレベルがリストである、または
findings/results/issues/vulnerabilities配列を持つ一般的な*.json。
1b. フィールドの別名(正規名 ← 受け入れる別名)
| 正規名 | 受け入れる別名 |
|---|---|
file | path, location.file, filename |
line | line_number, location.line, lineno |
category | type, cwe, rule_id, crash_type |
severity | severity_rating, level, priority |
title | name, summary, message |
description | details, report, body, evidence, rationale |
recommendation | fix, remediation, mitigation |
owner_hint | owner, component |
id(取り込み順に f001、f002、...。TRIAGE.json の既存 ID は保持)と source(元ファイルの相対パス)を付与します。
1c. 絞り込みと並べ替え
--id fNNNが指定されている場合:その調査結果のみを残します。--top Nが指定されている場合(静的モード):severityの HIGH > MEDIUM > LOW、次にconfidenceの降順で並べ替え、先頭から N 件を残します。fileのない調査結果は、場所を特定できないため、除外します。理由"no source location"を付けてskippedとして記録します。
1d. 対象コードベースの特定(静的モード)
--repo を解決します。file を持つ最初の 5 件の検出結果について、パスが repo 配下で解決できるか確認します(そのまま試し、次に一般的なプレフィックスを除去して試します)。いずれも解決できない場合は、停止します。引用されたファイルに到達できないことをユーザーに伝え、--repo の値を提案してください。
チェックポイント: Write ツール → ./.patch-state/_chunk.tmp:
{"phase": 1, "mode": ..., "findings": [...], "skipped": [...], "repo": ...}
その後 Bash:
python3 .claude/skills/_lib/checkpoint.py save ./.patch-state 1 ingest --from ./.patch-state/_chunk.tmp
フェーズ 2: パッチの生成
mode で分岐します。
2A. 実行検証モード — パイプラインに委譲する
パイプラインは、実行可能なオラクルを用いた build → reproduce → regress → re-attack のはしごをすでに実装しています。再実装しないでください。
各検出結果について(--id/--top フィルターがない場合はディレクトリ全体に対して一度)、Bash:
vuln-pipeline patch <findings_path> --model <--model arg> [--bug <bug_id>]
パイプラインは <findings_path>/reports/bug_NN/{patch.diff, patch_result.json} を自身で書き込みます。戻ったら、各 patch_result.json を Read し、verdict + rationale を作業状態にコピーします。verdict.passed == true の場合は verified: "ladder_passed" を、そうでない場合は verified: "ladder_failed" を設定します。
CLI が非ゼロで終了した場合(build_command がない、ターゲット設定が欠落している)、stderr をその検出結果の error として記録し、残りの検出結果を続行します。
フェーズ 3 をスキップします(はしごが検証者です)。フェーズ 4 に進みます。
検出結果ごとのチェックポイント: Write ツール → ./.patch-state/_chunk.tmp =
{"id": ..., "verified": ..., "verdict": ..., "diff_path": ...}、その後 Bash:
python3 .claude/skills/_lib/checkpoint.py shard ./.patch-state <id> --from ./.patch-state/_chunk.tmp。
すべての検出結果の後、統合されたフェーズペイロードを _chunk.tmp に書き込み、その後:
python3 .claude/skills/_lib/checkpoint.py save ./.patch-state 2 generate --from ./.patch-state/_chunk.tmp
2B. 静的モード — 検出結果ごとに 1 つのパッチサブエージェント
検出結果ごとに 1 つの Task を、並列実行のために単一のアシスタントメッセージ内にすべて配置します。subagent_type: "general-purpose"。run_in_background は決して設定しないでください — 必要なのは diff のテキストであり、非同期ハンドルではありません。
各サブエージェントは --repo への読み取り専用アクセスを持ちます。ターゲットを変更することはできません。レスポンス内にテキストとして diff を出力します。オーケストレーターがそのテキストを PATCHES/bug_NN/patch.diff に書き込みます。
パッチサブエージェントのプロンプト(一度組み立て、検出結果ごとに再利用)
You are conducting authorized security research as part of a defensive
assessment. Your task: write a candidate fix for ONE verified vulnerability
finding in a codebase you have read-only access to.
You may use Read, Glob, and Grep ONLY on paths inside {REPO_PATH}. You may
NOT build, run, install, edit files on disk, or reach the network. You will
emit the fix as a unified diff in your final response; you will NOT apply it.
────────────────────────────────────────────────────────────────────────
FINDING:
id: {id}
file: {file}
line: {line}
category: {category}
severity: {severity}
title: {title}
description:
{description}
recommendation:
{recommendation or "(none provided)"}
────────────────────────────────────────────────────────────────────────
PROCEDURE:
1. READ THE CODE. Open {file} at line {line} and the surrounding function.
Understand what the code does — do not trust the finding's description as
the only source.
2. ROOT CAUSE FIRST. Trace backward from the cited sink to where the bad
value or missing check originates. The fix usually belongs there, not at
the line the scanner flagged. Name the root-cause location (file:line).
3. VARIANT HUNT. Grep for sibling call sites with the same pattern. Your fix
should cover all of them, or your rationale should say why not.
4. MINIMAL DIFF. Smallest change that fixes the root cause. No refactoring,
no drive-by cleanup, no reformatting, no comment-only changes. Match the
surrounding code's style (brace placement, naming, error handling).
5. ADVERSARIAL SELF-CHECK. Re-read your diff as an attacker. Name one input
variation that would reach the same bad state without tripping your
change. If you can name one, your fix is at the wrong layer — go back to
step 2.
6. REGRESSION TEST. As part of the diff, add ONE test case that fails before
your change and passes after — placed wherever the project keeps its
tests (look for test_*/, *_test.*, tests/, spec/). If no test directory
exists, omit the test and say so in <test_note>.
────────────────────────────────────────────────────────────────────────
OUTPUT — your final response MUST contain exactly these tags. Emit the diff
verbatim between the markers; do NOT wrap it in ``` fences.
<patch_diff>
--- a/path/to/file
+++ b/path/to/file
@@ ... @@
context line
-removed line
+added line
</patch_diff>
<rationale>what changed and why, mechanically — file:line of root cause,
what the change enforces</rationale>
<variants_checked>file:function pairs you grepped for the same
pattern, and whether each needed the fix</variants_checked>
<bypass_considered>the input variation you tried in step 5 and why it
no longer reaches the bad state</bypass_considered>
<test_note>where the regression test landed, or why none was
added</test_note>
If you determine the finding is NOT fixable as described (wrong file, code
already patched, finding is a false positive), emit:
<patch_diff>NONE</patch_diff>
<rationale>why no patch is appropriate</rationale>
起動
findings[] 内の各検出結果について、上記のプロンプト({REPO_PATH}、{id}、{file}、{line}、{category}、{severity}、{title}、{description}、{recommendation} を置換)で Task 呼び出しを構築します。description: "patch {id}"。
len(findings) > ~40 の場合、約 40 件ずつの連続するバッチに分割します(各バッチは 1 メッセージ)。各結果が解析された後に、検出結果ごとのシャードチェックポイントを実行します。
いずれかの Task 呼び出しがサブエージェントのテキストではなく status: "async_launched" を返した場合、ランタイムがそれをバックグラウンド化しています。1 つのリカバリーを選び、バッチ全体でそれを使用します:
- 完了通知が会話に届く場合: 各サブエージェントのタグ付きブロックを、通知の
resultから届き次第解析します。すべての検出結果が処理されるまでターン終了しないでください。 - 通知が届かない場合: transcript ファイルをポーリングしないでください。不足しているパッチサブエージェントを新しい Task バッチで再起動し(より小さなシャード、例: 10)、同期結果を使用します。 同じリカバリーがフェーズ 3 のレビュー担当サブエージェントにも適用されます。
解析
各 Task の結果から、タグ付けされた 5 つのブロックを抽出します。先頭/末尾の
空白、 stray な ``` フェンス、HTML エスケープされたエンティティ(<
> & — 一部のランタイムは通知ペイロード内の山括弧をエスケープします。
diff を書き込む前にアンエスケープしてください)を許容します。<patch_diff> が NONE または
空の場合、
status: "no_patch" とマークします。それ以外の場合は diff テキストを
./PATCHES/bug_NN/patch.diff に書き込み(NN = ソート順のゼロ埋めインデックス)、
rationale、variants_checked、bypass_considered、test_note を記録します。
検出ごとのチェックポイント: Write ツール → ./.patch-state/_chunk.tmp =
{"id": ..., "bug_nn": "NN", "status": ..., "rationale": ..., ...}、続いて Bash:
python3 .claude/skills/_lib/checkpoint.py shard ./.patch-state <id> --from ./.patch-state/_chunk.tmp。
すべての検出の後、統合されたフェーズペイロードを _chunk.tmp に書き込み、続いて:
python3 .claude/skills/_lib/checkpoint.py save ./.patch-state 2 generate --from ./.patch-state/_chunk.tmp
フェーズ 3: 独立レビュー(静的モードのみ)
生成された diff ごとに 1 つのレビュアーサブエージェントを、すべて 1 つのメッセージで、
subagent_type: "general-purpose" として起動します。
レビュアーは検出の description、recommendation、および
パッチ作成者の rationale を決して見ません。 レビュアーが受け取るのは {file, line, category}
と生の diff バイトのみであり、ソース自体を読んで diff が最小限で
スコープ内の修正であるかどうかを再導出します。これにより、検出の文面に埋め込まれた
あらゆる指示が作成者とゲートの両方に到達するのを防ぎます。
レビュアープロンプト(一度アセンブルし、diff ごとに再利用)
You are reviewing a candidate security patch as a maintainer would. You have
read-only access to the unpatched source at {REPO_PATH}. You may use Read,
Glob, Grep. You may NOT build, run, or apply the diff.
You have NOT seen the scanner's description of the vulnerability or the
patch author's reasoning. Work only from the location, the category, and the
diff.
LOCATION: {file}:{line}
CATEGORY: {category}
DIFF UNDER REVIEW:
<diff>
{diff_text — or, for diffs over ~50 lines, replace this block with:
"Read the diff at ./PATCHES/bug_NN/patch.diff" and let the reviewer Read it}
</diff>
────────────────────────────────────────────────────────────────────────
ANSWER FOUR QUESTIONS:
1. SCOPE. Does the diff touch only files/functions on the path between
{file}:{line} and its callers? List any hunk that falls outside that
path.
2. SUPPRESSION. Does the diff fix a root cause, or does it suppress the
symptom (try/except: pass, early-return on a magic value, deleting the
check that fired, lowering a log level)?
3. NEW SURFACE. Does the diff add parsing, trust a new input field, weaken
validation elsewhere, or remove a security-relevant check?
4. STYLE. 0-10: would you merge this as-is?
0-3 wrong layer / suppression; 4-6 correct but noisy; 7-10 minimal,
targeted, matches surrounding style.
────────────────────────────────────────────────────────────────────────
End your response with EXACTLY:
REVIEW: ACCEPT | REJECT
STYLE_SCORE: <0-10>
OUT_OF_SCOPE_HUNKS: <comma-separated file:line, or none>
REASON: <2-4 sentences citing specific diff hunks and source lines>
ACCEPT requires: in-scope, root-cause fix, no new attack surface,
style >= 5. Otherwise REJECT.
起動と解析
status != "no_patch" の検出ごとに 1 つの Task を実行します。末尾のブロックを解析します。
review、style_score、out_of_scope_hunks、review_reason を
検出に付加します。ACCEPT/REJECT に関係なく、すべての静的モードの結果に対して
verified: "static_review_only" を設定します — このラベルは検証クラスを表し、
結果を表すものではありません。
チェックポイント: Write ツール → ./.patch-state/_chunk.tmp:
{"phase": 3, "findings": [...]}
続いて Bash:
python3 .claude/skills/_lib/checkpoint.py save ./.patch-state 3 review --from ./.patch-state/_chunk.tmp
フェーズ 4: 出力
4a. 検出ごとの patch_result.json
各検出(両モード)について、Write
./PATCHES/bug_NN/patch_result.json:
{
"id": "f003",
"source": "TRIAGE.json#2",
"title": "...",
"file": "...",
"line": 0,
"category": "...",
"severity": "HIGH",
"owner_hint": "...",
"mode": "exec" | "static",
"verified": "ladder_passed" | "ladder_failed" | "static_review_only",
"review": "ACCEPT" | "REJECT" | null,
"style_score": 0,
"out_of_scope_hunks": [],
"rationale": "...",
"variants_checked": "...",
"bypass_considered": "...",
"test_note": "...",
"review_reason": "...",
"verdict": { "t0_builds": true, "...": "(exec mode only, from pipeline)" }
}
exec モードでは、さらにパイプラインの
<findings_path>/reports/bug_NN/patch.diff を Read し、そのバイトを
./PATCHES/bug_NN/patch.diff に Write して、両モードが同じ場所に収まるようにします。
4b. ./PATCHES.json
{
"patch_completed": true,
"mode": "exec" | "static",
"repo": "...",
"summary": {
"input_count": 0,
"patched": 0,
"no_patch": 0,
"accepted": 0,
"rejected": 0,
"ladder_passed": 0
},
"findings": [ { ...patch_result.json shape... } ]
}
4c. ./PATCHES.md(インクリメンタル)
ステップ 1 — ヘッダー。 Write ツール → ./PATCHES.md(以前の内容を上書き):
# Candidate Patches
{if mode == "static":}
> **Static review only.** These diffs were authored and reviewed by
> independent agents reading source. They were NOT compiled, run, or
> re-attacked. Read each diff yourself before applying — see
> `docs/patching.md#reviewing-generated-patches` for what to look for.
{if mode == "exec":}
> **Execution-verified.** Each diff passed (or failed) the pipeline
> verification ladder: build → reproduce → regress → re-attack. The ladder
> proves the crash is gone, not that the diff introduces no new problems.
**Input:** {findings_path} · **Repo:** {repo} · {N} findings → {M} diffs
---
ステップ 2 — 検出ごと(ソート: ACCEPT/ladder_passed が先、次に
severity 順)。Write ./.patch-state/_chunk.tmp:
## bug_{NN}: [{severity}] {title} ({id})
`{file}:{line}` · {category} · owner: {owner_hint or "?"}
**Status:** {verified} · review {review or "n/a"} · style {style_score or "n/a"}/10
**Diff:** `PATCHES/bug_{NN}/patch.diff` ({hunk count} hunks, {line count} lines)
**Rationale:** {rationale}
**Variants checked:** {variants_checked}
**Bypass considered:** {bypass_considered}
{if review == "REJECT":}
> **Rejected by reviewer:** {review_reason}
{if out_of_scope_hunks:}
> **Out-of-scope hunks:** {out_of_scope_hunks}
---
続いて checkpoint.py append ./PATCHES.md --from ./.patch-state/_chunk.tmp。
ステップ 3 — フッター。 file を持たない、または status == "no_patch" の
検出のために ## Skipped テーブルを追加し、それぞれ理由を 1 行で記載します。
チェックポイント(最終): Bash:
python3 .claude/skills/_lib/checkpoint.py done ./.patch-state 4
4d. ターミナルサマリー
約 10 行以内:
Patches generated ({mode} mode): {N} findings → {M} diffs.
Accepted: {n} {title of top accepted}
Rejected: {n}
No patch: {n}
{if exec:} Ladder passed: {n}/{M}
Wrote ./PATCHES/bug_NN/, ./PATCHES.md, ./PATCHES.json
{if static:} These are drafts. Review before applying — see docs/patching.md.
ガードレール
- このスキルは diff を決して適用しません。
git applyも、patchも、--repoに対する Edit も行いません。もし必要だと感じたなら、設計が間違っています。 ./PATCHES/と./.patch-state/の配下にのみ書き込みます。- レビュアーの分離。 レビュアープロンプトは
{file, line, category, diff}を受け取り、検出からそれ以外は何も受け取りません。description、recommendation、exploit_scenario、またはパッチ作成者のrationaleを渡してはいけません。 - 必ず
subagent_typeを設定します。 フォークすると、すべての検出の文面が すべてのパッチサブエージェントに漏洩します。 - 1 つのフェーズのすべての Task 呼び出しを 1 つのメッセージで行います。 直列起動は 正しいですが N 倍遅くなります。
- 次のフェーズを開始する前にチェックポイントを取ります、毎回。
- exec モードは委譲し、決して再実装しません。
vuln-pipeline patchが PATH にない場合は、停止してユーザーに伝えてください。静的モードに暗黙的に フォールバックしないでください。
このスキルのテスト
canary フィクスチャに対する静的モード:
/vuln-scan targets/canary
/triage VULN-FINDINGS.json --repo targets/canary --auto
/patch TRIAGE.json --repo targets/canary --top 3
期待される結果:PATCHES/bug_00..02/ の下に差分が 3 つ生成され、それぞれ
verified: "static_review_only"、review: ACCEPT となり、仕込まれたオーバーフロー/UAF/書式文字列のバグに対してスタイル評価が 7 以上になります。
パイプラインの出力に対する実行検証モード:
vuln-pipeline run drlibs --runs 3 --parallel --stream --model <m>
/patch results/drlibs/<ts>/ --model <m>
期待される結果:vuln-pipeline patch に処理を委任し、バグごとに
verified: "ladder_passed" を提示し、差分を ./PATCHES/ にコピーします。
設計上の注意点
- TRIAGE.json が正規の入力です。 検証されていない検出結果に対するパッチ作成は誤検知にトークンを浪費するためです。利便性のため、VULN-FINDINGS.json も警告付きで受け付けます。
- 静的モードでは、差分内に回帰テストを出力します。 テストは実行しません。このスキルは対象コードを実行できないためです(静的パイプラインの制約)。このテストは、差分を適用する人間向けです。
- レビュー担当者には検出結果の説明文を見せません。 対象のソースには、スキャナーの
descriptionフィールドに残るような指示が埋め込まれている可能性があります。パッチ作成者は修正箇所を把握する必要があるため、その説明文を確認しますが、レビュー担当者は確認しません。そのため、埋め込まれたテキストが審査をすり抜けることはありません。 verifiedは検証区分であり、合否ではありません。static_review_onlyは、ACCEPT/REJECTにかかわらず「エージェントが確認した」ことを意味します。ladder_passed/ladder_failedは「ASAN が判定した」ことを意味します。後続のツールはreviewではなく、このフィールドに基づいて処理を分岐する必要があります。- 出力形式はパイプラインと一致しています(
PATCHES/bug_NN/{patch.diff, patch_result.json})。そのため、利用側はどちらのモードで生成されたかを気にする必要がありません。