deep-app-audit について
deep-app-audit は、Frappe アプリのコード一式を対象に、セキュリティ、正確性、カスタマイズを監査します。エージェント CLI のタスクを調整して検出結果を検証し、実行状態を保存して再開可能なレポートを作成します。
主な機能
- 01セキュリティ、正確性、カスタマイズの検査
- 02エージェント CLI タスクの並列実行
- 03スキャンと検証タスクの分離
- 04テストサイトと Semgrep の任意設定
- 05状態記録と実行再開
- 06タスク結果からのレポート生成
活用シーン
- 01選択した項目で Frappe アプリを監査
- 02有効なタスク結果を使った中断監査の再開
- 03テストサイトを作らずソースのみを検査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ frappe/ skills --skill deep-app-auditインストール後、Claude Code で/deep-app-auditを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents.example.jsonprompts/check.mdcontext.mdreport.mdscan.mdverify.mdquality/_conventions.mdquality/A-customization/A01-no-monkey-patching.mdA02-override-class-calls-super.mdA03-extend-instead-of-override.mdA04-regional-override-first.mdA05-override-whitelisted-method-contract.mdA06-hook-the-transaction-not-the-ledger.mdA07-reuse-the-existing-doctype.mdA08-custom-fields-in-code.mdA09-fixtures-overwrite-the-site.mdA10-remove-customizations-on-uninstall.mdA11-declare-required-apps.mdA12-declare-versions-and-branches.mdA13-clean-bench-install.mdA14-dotted-paths-must-resolve.mdA15-scheduler-method-path-is-an-api.mdA16-prefix-custom-fieldnames.mdA17-keep-standard-field-constraints.mdA18-check-every-writer.mdA19-bound-the-custom-field-count.mdA20-server-side-rules-not-in-client-scripts.mdA22-app-logic-not-in-server-scripts.mdA24-hooks-py-is-static-data.mdA25-handler-signature-matches-call-site.md詳細
アプリの詳細監査
このスキルは、1つの Frappe アプリのチェックアウトを3つのトラックで監査し、1つのレポートを作成します。
| トラック | プロンプト | ID の接頭辞 |
|---|---|---|
| セキュリティ | security/ の領域ディレクトリにあるスコープ | S-A ~ S-L |
| セキュリティ | security/checks/ にある姿勢チェック | S-P |
| 正確性 | quality/B-correctness/ にあるルール | Q-B |
| カスタマイズ | quality/A-customization/ にあるルール | Q-A |
| カスタマイズ | quality/checks/ にあるチェック | Q-K |
プロンプトの ID は、トラックの接頭辞とファイル ID を組み合わせたものです。security/A-authorization/A02-*.md は
S-A02 です。quality/mechanisms/ は品質ルールの背景情報であり、プロンプトのセットではありません。
どちらのトラックも同じ手順で進めます。security/_conventions.md と quality/_conventions.md は同じセクションで構成されており、それぞれが該当トラックの取り決めです。手法、検出事項の基準、重要度の段階、検証手順、検出事項の形式が定められています。prompts/ にあるタスクプロンプトは両方のトラックで共通で、各エージェントを該当トラックの規約に案内します。
実行の流れ
実行は2つの部分で構成されます。
| 部分 | 実行者 | 手順 |
|---|---|---|
| セットアップ:引数、対象、インベントリ、semgrep、テストサイト | あなた(コーディネーター) | 1~4 |
| タスク:スキャン、チェック、検証、レポート | scripts/run_audit.py | 5 |
セットアップには判断が必要です。ベンチ環境はマシンごとに異なり、アプリごとに固有のアクターが存在するため、あなたが行います。タスクのスケジュールには判断が不要なので、スクリプトが行います。スクリプトは各タスクをエージェント CLI の新しいプロセスとして起動するため、タスクごとに新しいコンテキストが用意されます。スキャンを見た検証者は独立した立場ではなく、1つのコンテキストで160件のスキャンを扱うこともできません。
このスクリプトは、特定のモデルやハーネスに依存しません。agents.json は各タスク種別をコマンドに対応付けます。コマンドには、プロンプトを受け取り、ファイルの読み取り、コマンドの実行、ファイルの書き込みができる任意の CLI を指定できます。スキャンタスクと検証タスクで、異なるモデルを使用できます。
スクリプトは次の処理を行います。
- タスクを並列で実行し、各ワーカーにテストユーザーのセットを1つずつ割り当てます
- スキャンファイルが作成されると、重大度の高いものから順に、上限の範囲内で検証タスクをキューに追加します
- 各結果ファイルの形式を確認し、ファイルがない場合や形式が正しくない場合はタスクを再実行します
- 各タスクの後にサイトのリセットコマンドを実行し、サイトから応答がなくなった場合は停止します
run.json(各タスクの状態)とsummary.json(件数)を書き込み、すべてのタスクが完了するとレポートを開始します
各タスクは、実行ディレクトリ内のファイルに結果を書き込みます。結果ファイルが有効であれば、そのタスクは完了です。そのため、停止した実行をスクリプトでもう一度開始すると、中断した箇所から再開します。
アプリを自分で監査したり、タスクエージェントを自分で起動したりしないでください。
1. 引数を確認する
引数には監査するアプリのチェックアウトを指定し、その後にオプションを平文で指定します。パスがない場合は、カレントディレクトリを使用します。
| オプション | 例 | デフォルト |
|---|---|---|
only: 実行する ID プレフィックス | S-A、Q-B05 | すべて |
skip: 除外する ID プレフィックス | S-L、S-P05 | なし |
no checks: 全体を対象とするチェックを実行しない | チェックを実行 | |
no site: ソースのみを読み込む | サイトを作成 | |
site: 既存の使い捨てサイトを再利用する | myapp-audit.localhost | サイトを作成 |
db root password: bench new-site 用 | なし | |
bench: bench ディレクトリ | チェックアウトの上位で見つかったもの | |
output: 実行ディレクトリ | <target>/../<app>-deep-audit/ | |
semgrep rules: frappe/semgrep-rules のローカルクローン | ~/src/semgrep-rules | 実行ディレクトリにクローン |
no semgrep: semgrep ルールを実行しない | semgrep を実行 | |
drop site: 最後に作成したサイトを削除する | トリアージ用に保持 | |
agents: エージェントコマンドのファイル | ~/audit-agents.json | <run dir>/agents.json |
jobs: 同時に実行するエージェント数 | 4 | 16 |
max candidates: 各スキャンの検証上限 | 15 | 15 |
max verifications: 実行全体の検証上限 | 600 | 600 |
timeout: 実行を停止するまでの時間(時間) | 12 | 8 |
「セキュリティのみ」は only: S- です。「正確性のみ」は only: Q-B です。「品質のみ」は only: Q- です。
2. 対象を確認する
指定されたパスに Frappe アプリがあることを確認します。パッケージのいずれかに hooks.py が含まれている必要があります。含まれていない場合は、停止してユーザーに伝えます。
実行内容を 2〜3 行でユーザーに伝えます。対象アプリ、トラック、テストサイトを作成するかどうか、エージェント CLI とモデル、およそのエージェント数を伝えてください。全トラックを実行すると、スキャンとチェックに約 160 個のエージェントが使われ、さらに候補ごとに 1 個のエージェントが使われます。エージェント数が数百個になることもあります。ユーザーがパスとオプションを指定している場合は、確認を求めないでください。コマンドを指定したことが、実行への同意を意味します。
テストサイトには bench への書き込みアクセスが必要です。チェックアウトが bench 内にない場合、または bench が本番環境のものと思われる場合は、no site を使用して、その旨を伝えてください。
3. 実行の準備
この手順は自分で行ってください。アプリのチェックアウト内のファイルは変更しないでください。
-
チェックアウトの絶対パスを解決します。アプリパッケージ名(
hooks.pyが格納されているディレクトリ)と、git -C <target> rev-parse --short HEADで取得した短縮コミットハッシュを記録します。 -
ベンチを読み取り専用で見つけます。ベンチディレクトリには
sites/、apps/、Procfileがあります。インストール済みのアプリは通常、<bench>/apps/<app>にあります。apps/frappe/frappe/__init__.pyから Frappe のバージョンを記録し、対象が必要とするアプリ(hooks.py、pyproject.tomlのrequired_apps)またはインポートするアプリと、ベンチ内のそれぞれのパスを記録します。 -
実行ディレクトリを作成します。すでに
setup.jsonが存在する場合は、再開した実行です。内容を読み、未完了の最初のステップから再開します。 -
エントリーポイントの一覧を作成します。
python <skill dir>/scripts/build_inventory.py <run dir>/inventory.json --root <target>このスクリプトは読み取り専用です。ベンチ、サイト、データベースは不要です。また、対象が必要とする
frappeとアプリの DocType が、チェックアウトの隣の<bench>/appsにある場合は、それらも読み込みます。別のディレクトリにあるアプリについては、それぞれに--doctypes-from <path>を追加します。失敗した場合は、エラーを記録します。一覧がなくても監査を続行します。 -
ユーザーが
no semgrepを指定していない限り、Frappe の semgrep ルールを実行します。このルールは品質ルールのsemgrepフィールドの情報源なので、各スキャンで実行するのではなく、ここで一度だけ実行します。-
semgrep を取得します。
PATHにsemgrepがある場合は、それを使用します。なければ、PATHにuvがある場合はuv tool install semgrepを実行し、semgrep をuv tool run semgrepとして呼び出します。uv のツールディレクトリは、常にPATHに含まれているとは限らないためです。別の方法で uv や pip パッケージをインストールしないでください。 -
ルールを取得します。
semgrep rulesオプションがある場合は、そのクローンをそのまま使用します。そうでなく、<run dir>/semgrep-rulesが存在しない場合は、次のコマンドでクローンします。git clone --depth 1 https://github.com/frappe/semgrep-rules <run dir>/semgrep-rules. 実行ディレクトリにクローンを置くことで、実行を再開した場合も、その実行で使用するルールが固定されます。クローンの短縮コミットハッシュを記録します。 -
チェックアウトをスキャンし、各一致にルール ID のみを指定します。Semgrep はルール ID の先頭にルールディレクトリのパスを付けるため、最後の
.までをすべて削除します。<semgrep> scan --config <rules>/rules --json --metrics=off --quiet --output <run dir>/semgrep-raw.json <target> jq --arg t "<target>/" '[.results[] | {rule: (.check_id | split(".") | last), file: (.path | ltrimstr($t)), line: .start.line, message: .extra.message}]' \ <run dir>/semgrep-raw.json > <run dir>/semgrep.json
いずれかのステップが失敗した場合は、エラーを記録します。semgrep がなくても監査を続行します。
-
-
プロンプトを一覧表示します。上の表にあるディレクトリ内の
*.mdファイルをすべて含めます。名前が_で始まるファイルは除外します。onlyとskipは ID に適用し、no checksのチェックは除外します。 -
<run dir>/setup.jsonを書き込みます。notesは任意です。すべてのエージェントが必要とするアプリに関する事実(DocType 名と異なる製品名など)を記載します。{ "target": "/abs/path/to/app", "app": "myapp", "commit": "abc1234", "bench": "/abs/path/to/bench", "frameworkVersion": "16.0.0-dev", "dependencies": [{"app": "erpnext", "path": "/abs/path/to/bench/apps/erpnext"}], "inventory": "/abs/run/dir/inventory.json", "inventoryError": null, "semgrep": "/abs/run/dir/semgrep.json", "semgrepRules": "/abs/run/dir/semgrep-rules", "semgrepRulesCommit": "def5678", "semgrepError": null, "scans": ["S-A01", "Q-B05"], "checks": ["S-P01", "Q-K01"], "notes": "In the UI, the DocType Sales Invoice is called Bill." } -
エージェントのコマンドを取得します。
agentsオプションがある場合は、そのファイルを使用します。そうでなく、<run dir>/agents.jsonが存在しない場合は、<skill dir>/agents.example.jsonをそこにコピーし、使用しているハーネス用のプロファイルがファイルにある場合は、各ロールにその CLI を設定します。ハーネス用のプロファイルがファイルにない場合、または使用している CLI がわからない場合は、ユーザーに確認します。プロファイルで許可されているツールが各タスクエージェントに付与されるツールなので、許可範囲を広げないでください。
4. テストサイトを起動する
no site が指定されている場合は、このステップをスキップします。自分で行うか、以下の手順をエージェント 1 人に任せてください。サイトがあると、検証者は実際のリクエストを送信できます。サイトがない場合、監査ではソースのみを読み取ります。
-
ベンチディレクトリから
bench --versionを実行して、bench があることを確認します。bench がない場合は、サイトを使わずに続行します。bench やデータベースサーバーをインストールしたり、マシンの設定を変更したりしないでください。 -
サイトを用意します。
siteオプションがある場合は、そのサイトを再利用します。まず、それが本番サイトではないことを確認します。実データが保存されている場合は中止し、サイトを使わずに続行します。それ以外の場合、サイト名は<app>-audit.localhostです。その名前のサイトが存在する場合は再利用します。その名前の所有者は監査です。存在しない場合は作成します。bench new-site <site> --admin-password audit-admin-pw [--db-root-password <pw>]コマンドがプロンプトで停止することがあってはなりません。失敗した場合はエラーを記録し、サイトを使わずに続行します。他のサイトを作成、変更、削除、またはマイグレーションしないでください。
-
対象が必要とするアプリをインストールしてから、対象アプリをインストールします。
bench --site <site> install-app <app>. -
テストユーザーを作成します。実行の各ワーカーにはそれぞれ専用のユーザーセットを割り当てるため、タスクがユーザーを変更しても、タスク後のリセットが他のタスクに影響しません。
jobs個のセットを作成し、0 から番号を付けます。セットkには以下のユーザーを作成します。それぞれのパスワードはaudit-user-pw、enabled = 1とし、オンボーディングやパスワードリセットを要求しないようにします。milkshake-s<k>[email protected]:Website User。他のロールは付与しません。milkshake-s<k>[email protected]:通常の System User。他のロールは付与しません。フレームワークがロールからユーザータイプを判定する場合、デスクトップロールを持たないユーザーは Website User になります。次に、デスクトップアクセス権を持ち、権限は付与しないmilkshake Desk Userロールを作成し、このユーザーに付与します。milkshake-s<k>[email protected]:System User および System Manager。マネージャーが既に実行できる操作と比較するためです。- アプリが定義する各ロール(DocType、ページ、およびレポートの権限内にある、フレームワークが定義していないロール)について、ユーザーを 2 人作成します。
milkshake-s<k>-<role slug>[email protected]と[email protected]に、そのロールだけを付与します。同じロールのユーザーを 2 人用意することで、検証者は別のユーザーのレコードへのアクセスをテストできます。
保存後の各ユーザーのロールを記録します。アプリのロジックによってロールが追加される場合があります。
-
リセットスクリプト
<run dir>/reset_site.pyを作成し、その実行コマンドを記録します。実行は各タスク後にこのコマンドを呼び出し、{slot}をセット番号に置き換えます。このスクリプトは、そのセットの各ユーザーを記録した状態に戻します。具体的には、ロールを記録どおりに設定し、enabled = 1、ユーザータイプ、パスワードを復元します。また、Administrator のパスワードもaudit-admin-pwに戻します。それ以外は何も変更せず、数秒で終了し、bench consoleは使用しません。たとえば、<bench>/sitesから bench の Python を使い、サイトに対してfrappe.initとfrappe.connectを呼び出して実行します。各セットに対してコマンドを 1 回実行し、終了コードが 0 であることを確認します。 -
サイトをバックグラウンドで起動します。ベンチディレクトリから
bench serve --port 8199を実行します。サイトでHostヘッダーが必要な場合は、それを記録します。 -
コントロールの動作を変える設定を記録します。
sites/common_site_config.jsonと、サイトのsite_config.jsonを読み込みます。少なくともignore_csrf、developer_mode、allow_tests、server_script_enabled、disable_website_cache、maintenance_mode、およびすべての*_disabledまたはallow_*キーとその値を記録します。コントロールを無効化または緩和する値を持つ各キーにはweakens: trueと記し、その影響を 1 行で説明します。ignore_csrf: 1の bench は、本番環境なら拒否されるクロスサイトリクエストを受け付けます。そのため、その環境で 200 が返っても、本番環境については何も証明できません。 -
サイトが動作することを確認します。
curl -sS -o /dev/null -w '%{http_code}' <base url>/api/method/pingが 200 を返す[email protected]で/api/method/loginにログインすると 200 が返り、Cookie が設定されるbench --site <site> list-appsにアプリが表示される チェックに失敗した場合は、サイトなしで続行します。中途半端に動作するサイトは、サイトがないよりも悪い状態です。 検証者がそのエラーを証拠として読み取るためです。
-
<run dir>/site.jsonを作成します。slotsには、セットごとのユーザーリストをセットの順序で格納します。notesには、サイトについてすべてのエージェントが知っておくべきことを記載します。たとえば、最初はレコードがないことなどです。{ "ready": true, "site": "myapp-audit.localhost", "baseUrl": "http://localhost:8199", "hostHeader": "myapp-audit.localhost", "bench": "/abs/path/to/bench", "created": true, "apps": ["frappe", "myapp"], "adminPassword": "audit-admin-pw", "slots": [[{"email": "[email protected]", "password": "audit-user-pw", "actor": "plain System User", "roles": ["milkshake Desk User"]}]], "resetCommand": "cd /abs/path/to/bench/sites && ../env/bin/python /abs/run/dir/reset_site.py {slot}", "notes": "The site starts with no records.", "config": [{"key": "ignore_csrf", "value": "1", "weakens": true, "effect": "CSRF is not checked"}] }サイトがない場合は、
{"ready": false, "reason": "..."}を記述します。
5. タスクを実行する
スキルディレクトリからスクリプトを起動し、ハーネスから切り離して、出力を
<run dir>/run.log に送ります。
mkdir -p <run dir>/tmp && [ -e <run dir>/tmp/last-check ] || touch <run dir>/tmp/last-check
setsid nohup python <skill dir>/scripts/run_audit.py <run dir> --agents <agents file> \
--jobs <jobs> --timeout <timeout> \
--max-candidates <max candidates> --max-verifications <max verifications> \
[--only <prefix> ...] [--skip <prefix> ...] >> <run dir>/run.log 2>&1 < /dev/null &
スクリプトをハーネスのバックグラウンドコマンドとして実行しないでください。ハーネスは、たとえば 2 時間など、一定時間が経過するとバックグラウンドコマンドを停止することがよくありますが、実行にはそれ以上かかります。スクリプトには独自の時間制限 --timeout があります。その制限に達すると、エージェントを停止して終了します。
まず --dry-run を付けて一度実行してください。ドライランではエージェントは起動しません。タスクリスト、各タスク種別のコマンド、および各種別の完全なプロンプトが 1 つずつ表示されます。プロンプトを 1 つ読み、サイト、ユーザー、パスが正しいことを確認してください。
ハーネスでデタッチしたプロセスを起動できない場合、またはエージェントプロセスを起動できない場合は、ユーザーにコマンドを伝えて終了してください。ユーザーがコマンドを実行し、完了したら残りの手順を尋ねます。
スクリプトの実行中は、エージェントを起動しないでください。スクリプトはタスクが終了するたびに 1 行を出力します。<run dir>/run.json には各タスクの状態が、<run dir>/logs/<task>.log には各エージェントの出力が記録されます。スクリプトが最後まで実行される前に停止した場合は、同じ引数で再度起動してください。有効な結果がないタスクから続行されます。
ユーザーに進捗を伝える
実行には何時間もかかります。更新がなければ、ユーザーは実行が遅いのか、停止しているのか判断できません。そのため、スクリプトが終了するまで、10~15分ごとに進捗を確認してください。タイマーまたはハーネスからのウェイクアップを使います。ハーネスはデタッチされたスクリプトの終了を通知しないため、ウェイクアップのたびに次の確認を開始する必要があります。ハーネスにどちらの機能もない場合は、実行状況を自分で確認する方法(tail -f <run dir>/run.log)をユーザーに伝え、スクリプトが終了するまで待ちます。
各確認では、実行ディレクトリから次を実行します。
kill -0 "$(cat run.pid)" 2>/dev/null && echo "script: running" || echo "script: exited"
grep -E '^(ok|FAIL) ' run.log | tail -n 1
grep -vE '^(ok|FAIL) ' run.log | tail -n 5
jq -r '"complete: \([.tasks[] | select(.ok)] | length), failed: \(.failed | length), verifications left in the cap: \(.verificationsLeft), site down: \(.siteDown), timed out: \(.timedOut)"' run.json
jq -r '"now: \(now | strflocaltime("%F %T")), updated: \(.updated), last progress: \(.lastProgress), deadline: \(.deadline)", (.running | to_entries[] | "attempt running since \(.value): \(.key)")' run.json
find verdicts -name '*.json' -newer tmp/last-check -print0 | xargs -0r jq -r \
'select(.verdict == "confirmed") | "\(.severity) \(input_filename | split("/")[1]): \(.finding.title)"'
touch tmp/last-check
最後の2つのコマンドには、前回の確認後に確定した検出結果だけが表示されるため、再起動後も同じ検出結果を二度伝えることはありません。
ユーザーには、次の内容を2~3行で伝えます。
- 完了、待機中、実行中、失敗の各タスク数
- 新たに確定した検出結果を1件につき1行で、重大度とIDを添えて伝えます。人による確認がまだ必要であることも伝えます。
- 問題があれば伝えます。失敗したタスク、リセットの失敗、または応答を停止したサイトが該当します。
これらの出力だけを読みます。スキャンファイルと判定ファイルは開かず、検出結果の評価もしないでください。検出結果の評価はレポートタスクが行います。
各確認では、実行が進行していることも確認する必要があります。
- スクリプトが終了している場合。
run.logの最終行は=== exit <code>です。この行がない場合、スクリプトはクラッシュしたか停止しています。run.logの末尾の行をユーザーに伝え、同じ引数でスクリプトを再起動します。 - スクリプトが応答しない場合。 スクリプトは毎分
run.jsonを更新します。updatedが5分より前の時刻の場合、スクリプトは停止しています。kill "$(cat run.pid)"で停止します。エージェントも停止します。その後、スクリプトを再起動します。 - タスクが完了しない場合。 スクリプトは、エージェントプロファイルの
timeoutでエージェントを停止します。agents.example.jsonでは1時間です。last progressは、最後のエージェント試行の終了時刻、またはスクリプトの開始時刻です。そのため、last progressまたはrunning中の試行が、タイムアウトに15分を加えた時間より前のものなら、実行は停止しています。上記と同様に停止し、再起動します。 同じ停止が2回発生した場合は、実行を停止してユーザーに伝えます。
再起動すると、有効な結果がないタスクから再開します。完了したタスクは繰り返しません。
テストサイトが応答を停止すると、スクリプトも停止します。検証ツールが停止したサイトのエラーを証拠として読み取るためです。サイトを再起動し、手順4.8で動作を確認してから、スクリプトを再起動します。
すべてのタスクが完了すると、スクリプトは0で終了します。1で終了した場合は、run.json に失敗したタスクが記載されています。レポートは実行されており、失敗したタスクも記載されています。
run.json に "timedOut": true がある場合、実行は制限時間に達しており、レポートは実行されていません。完了したタスク数をユーザーに伝え、続行するか尋ねます。続行するには、同じ引数でスクリプトを再起動します。起動のたびに --timeout が全時間適用されます。
drop site を使う場合は、この実行で作成したサイトに限り、bench serve を停止して、bench drop-site <site> --force を実行します。
6. ユーザーに伝える
<run dir>/summary.json と、<run dir>/report.md のヘッダーおよびサマリーテーブルを読みます。ユーザーには次の内容を伝えます。
- レポートと実行ディレクトリのパス
summary.jsonにある、トラックと重大度ごとの確定候補数、および反証済み件数と不確実件数。レポートでは候補が根本原因ごとにまとめられるため、検出結果の数は少なくなります。個別の検出結果数はレポートのヘッダーを確認します。- レポートのサマリーテーブルにある Critical と High の検出結果のタイトルを、1件につき1行で伝えます。
- 実行後も残したテストサイトがある場合は、検出結果を再現できるようサイト名を伝えます。
- 実行で省略されたものがあれば伝えます。失敗したタスク、上限により未検証のまま残った候補、
not applicableだったチェック、失敗した semgrep の手順が該当します。
レポートの内容をそのまま返信にコピーしないでください。修正方法を提案しないでください。
レポートタスクが失敗しても、実行ディレクトリにはすべての結果が残っています。その旨をユーザーに伝え、スクリプトを再起動するか尋ねます。再起動時に実行されるのはレポートのみです。
プロンプト
タスクのプロンプトは prompts/ にあるテンプレートです。スクリプトは setup.json と
site.json の値をテンプレートに埋め込み、各プロンプトを <run dir>/prompts/<task>.md に保存します。
| テンプレート | 用途 |
|---|---|
context.md | すべてのプロンプトの冒頭部分:パス、ベンチ、インベントリ、semgrep、サイト、ユーザー、ルール |
scan.md | 1 つのスコープまたはルール。scans/<id>.json を作成します |
verify.md | 1 つの候補。verdicts/<id>/<n>.json を作成します |
check.md | サーフェス全体のチェックを 1 つ実行し、checks/<id>.json を作成します |
report.md | レポート。report.md を作成します |
{{name}} は値です。{{#if name}}...{{else}}...{{/if}} は、値が設定されている場合に一方の部分を残します。
テンプレートにスクリプトが認識しない値が指定されていると、スクリプトは開始時に停止します。
テンプレートの結果形式を変更する場合は、run_audit.py の validate() 内のチェックも変更してください。
警告
出力はエージェントによるものです。検出結果に基づいて誰かが行動する前に、必ず担当者がそれぞれを確認してください。誤検知や見落としが発生する可能性があります。問題がないレポートであっても、アプリの安全性や正確性が証明されたことにはなりません。