verify-cli-run について
CLI コマンドが実際に起こした変更を検証する、追加ツール不要のスキルです。終了コードや出力だけに頼らず、実行前に期待する結果を定め、ファイル状態の比較で証拠不足と失敗を区別します。
主な機能
- 01実行前に期待する結果を記録
- 02前後のファイル状態を比較
- 03証拠とコマンド自身の報告を区別
- 04可・否・不明・責任なしで判定
- 05観測できなかった範囲を記録
活用シーン
- 01ビルドによる対象ファイルの更新を確認
- 02マイグレーションの作成ファイルを確認
- 03CLI が行ったコード変更を調査
- 04リモート操作をサーバー側で確認する必要性を判断
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ reticlehq/ reticle --skill verify-cli-runインストール後、Claude Code で/verify-cli-runを入力して読み込まれたか確認します。
詳細
コマンドが宣言どおりの動作をしたことを証明する
コマンドは終了コード 0 を返し、✓ done と出力しました。ツールが独自の成功分岐に到達したことは分かりました。しかし、何かが実際に起きたかどうかは分かりません。
CLI の検証における問題は、これに尽きます。誰もが確認する 2 つのことは、どちらもツール自身が説明しているだけです。 終了コードは、作業を行ったのと同じコードが選んでいます。出力もそのコードが書いています。ツールが実行したことについて誤っている場合、その両方で同じように誤っています。まさにそれが、両者の一致が何の証明にもならない理由です。
このスキルに必要なツールのインストールはありません。4 つのルールと、いくつかの git だけです。
すべてを決めるルール
結果を裏付ける証拠は、アクションを実行したものから得てはいけません。
使う前に、すべての事実を評価してください。
| 手元にあるもの | 等級 | コマンドが成功したことを証明できますか? |
|---|---|---|
| ディスク上のファイルの実行前と実行後の状態 | 結果 | はい。 書き込みが行われたかどうかを決めたのはファイルシステムであり、ツールではありません |
| 後から問い合わせたときに応答する API | 結果 | はい。 ツールではなく、別の当事者があなたに応答しています |
| 終了コード | 存在 | いいえ。ツールが選びました |
| stdout / stderr | 文脈 | いいえ。ツールが書きました |
ツール自身の --verbose レポート | 文脈 | いいえ |
下の 3 行にあるものはすべて実際の情報ですが、どれも証拠にはなりません。判定に使うのではなく、判定の説明に使ってください。
1. 実行する前に結果を明確にする
これが手順です。出力を見た後に書いた期待値は、起きたことに合わせて納得させられてしまいます。事前に書いておけば、満たされるか、満たされないかのどちらかです。
コマンドを実行する前に、トランスクリプトに 1 行で書き留めます。
EXPECT: dist/index.js is rewritten, and no file outside dist/ changes.
EXPECT: src/utils.ts gains a function called parseConfig.
EXPECT: the migration creates 3 files under migrations/ and nothing else.
事前に明確に述べられない結果は、検証できません。述べられない場合は、その旨を伝えて停止してください。それは合格ではなく、正直な no-fault です。
2. 実行前の状態を記録する
git リポジトリの場合。 こちらが望ましいケースで、1 行で済みます。
git status --porcelain > /tmp/before.txt
git status --porcelain は、ほぼ完璧な証拠の取得手段です。構造化され、低コストで、ツールから独立しています。Git のインデックスに記録されるのは、ツールが何をするつもりだったかではなく、ディスクに書き込まれたものです。
git リポジトリではない場合、または対象のパスがリポジトリの外にある場合:
find <declared-root> -type f -newermt '1970-01-01' -exec shasum -a 256 {} + | sort > /tmp/before.txt
宣言するルートについて、次の 3 つのルールに従ってください。
- 対象でない限り、
node_modules、.git/objects、大きなビルドキャッシュは除外します。node_modules全体のハッシュを取ると、数万個のファイルが対象になります。 - 対象を明示的に宣言します。 ツールはどこにでも書き込めます。あなたが監視するのは、自分で選んだリストです。
- そのリストに含まれないものはすべて死角です。 起きなかったふりをせず、手順 6 で報告してください。
3. すでに成立しているか確認する
CLI 作業で最もよくある誤った成功判定は、dist/index.js が存在するので「ビルドによって dist/index.js が生成された」と合格にすることです。実際には何もしていない、何もしない再ビルドだったとしてもです。
実行する前に、期待する結果がすでに成立しているかを確認してください。成立している場合、そのコマンドでは証明できません。コマンドによって変化する結果を選ぶか、先に成果物を削除し、そのことを明記してください。
4. 実行して、結果を別々に記録する
<the command> > /tmp/out.txt 2> /tmp/err.txt; echo "exit=$?"
終了コードは記録してください。証拠として使うわけではありません。判定を説明し、ファイルシステムの状態と食い違ったときに気づくために使います。
知っておくべきことは 3 つあります。
- 終了コードには桁あふれがあります。
sh -c 'exit 256'の終了コードは 0 です。大きなコードが、常に想定どおりとは限りません。 130はSIGINT、137は通常、強制終了です。これらは実行がどのように 終了したか についての事実であり、成功したかどうかを示すものではありません。- 何も実行しないことを選んでも、終了コード 0 を返すツールがあります。AI コーディング CLI では、これはよくあります。
5. diffを確認し、証拠としてdiffを読む
git status --porcelain > /tmp/after.txt; diff /tmp/before.txt /tmp/after.txt
git diff -- <the paths you expected to change>
ステップ1で想定したことについて、これだけを根拠に答えてください。
毎回確認する価値のある点が2つあります。どちらも手間はかかりません。
- ほかに何も変わっていないこと。 ビルドがロックファイルも書き換えた場合や、フォーマッターが依頼されていないファイルを整形した場合も、発見事項です。
- 存在だけでなく内容。 ファイルが存在するというだけでは、期待した内容がそのファイルに含まれていることよりも弱い証拠です。ただし、非対称性に注意してください。ファイルが現れたかどうかはファイルシステムによって決まりますが、その中身はツールがすべて書き込みました。存在は内容より強い証拠です。
6. 4つのうち1つの判定を下す
2つではありません。追加された2つの値が重要です。無知を都合よく良い知らせに置き換えないための値だからです。
| 判定 | 条件 |
|---|---|
| はい | ステップ1で挙げた結果がdiffに現れており、それが以前から真実だったわけではない |
| いいえ | diffがその結果と矛盾している、またはツールが主張したことをファイルシステムで確認できない |
| 不明 | 必要なものを確認できなかった。監視されていなかった、対象範囲が違っていた、または影響が確認していない場所にある |
| 問題なし | すべて監視され、問題はなく、証明すべきものも宣言されていない |
unknownは失敗ではなく、決して失敗として報告してはいけません。 「確認できなかった」と「壊れている」は、人を正反対の方向へ導きます。前者はもう一度確認するよう促し、後者は何かを修正しに行くよう促します。
そして、何を根拠に「はい」と判断したかを述べてください。「dist/index.jsがディスク上で変更された」は判定です。「ビルドで成功したと表示された」は判定ではありません。それしか根拠がない場合、正直な答えはunknownです。
7. 確認できなかったことを述べる
見落としたものを述べられない判定は、すべてを確認した判定と見分けがつきません。毎回、抜けているものを挙げてください。1行で十分です。
Did not observe: the network (cannot see whether it called out); writes outside ./src and ./dist;
files created and deleted during the run; anything the tool's child processes did.
常に存在する、デフォルトで挙げる価値のある抜けが4つあります。
- ネットワーク。 コマンドがエンドポイントに接続したかどうかは確認できません。主張がリモート(プッシュ、デプロイ、PR)に関するものなら、ファイルシステムでは答えられません。
- 宣言したルートの外部への書き込み。
~/.config、グローバルキャッシュ、/tmpなどです。ほとんどのAIコーディングCLIは、実行のたびに独自の状態ディレクトリに書き込みます。 - 一時ファイル。 実行中に書き込まれて削除されたファイルです。実行前後のスナップショットで分かるのは、正味の影響だけです。
- 子プロセス、およびコマンド終了後も動作するもの。フォーク、遅延フラッシュ、バックグラウンドアップロードなどです。
何も手間をかけずに多くを見つけられる2つの方法
2回実行する。 ビルド、フォーマッター、コード生成のステップ、マイグレーションは、2回目には空のdiffを生成するはずです。繰り返し実行するたびに変更を加えるツールには不具合があります。これは比較対象となる期待値がなくても確認できます。
<command> && git status --porcelain > /tmp/a.txt && <command> && git status --porcelain > /tmp/b.txt && diff /tmp/a.txt /tmp/b.txt
相手側に問い合わせる。 ネットワークツールについては、ファイルシステムでは確認できませんが、サービスに問い合わせることはできます。gh pr view、git ls-remote、デプロイされたURLへのcurlなどです。これはツールが自分自身について報告するのではなく、別の相手があなたに答えるため、結果を裏付ける証拠となります。また、リモートに関する主張で利用できる唯一の証明方法です。
ツール自身のローカル記録を代わりに使うことは認めないでください。git pushは.git/refs/remotes/origin/mainを書き込みますが、そのshaはリモートが何を返したとgitが信じているかをgitが書き起こしたものです。ディスク上にあっても、ツールが自分自身について説明していることに変わりはありません。リモートに問い合わせてください。
実例:AIコーディングCLI
これらのツールはファイル編集そのものが製品であり、そのトランスクリプトは最も信頼性に欠ける情報だからです。これは最も確かなケースです。
EXPECT: src/config.ts gains a function `parseConfig`. Nothing outside src/ changes.
$ git status --porcelain > /tmp/before.txt
$ grep -c "parseConfig" src/config.ts # already-true check → 0
$ claude -p "add a parseConfig function to src/config.ts" ; echo "exit=$?"
$ git status --porcelain > /tmp/after.txt ; diff /tmp/before.txt /tmp/after.txt
M src/config.ts
$ git diff src/config.ts | grep "^+.*parseConfig"
+export function parseConfig(raw: string): Config {
VERDICT: yes, bought by the working-tree diff, which is independent of the agent's report.
It was not already true (grep returned 0 before).
Did not see: writes under ~/.claude (the tool records every session there); the network;
whether a permission prompt declined an edit it also claimed.
判定の根拠にならなかったものに注目してください。終了コードと、エージェントが関数を追加したと述べた段落です。
このスキルを超えてエスカレーションすべき場合
この方法には対応できる範囲に4つの限界があり、それぞれに適切な対処法があります。
| 必要なこと | 使用するもの |
|---|---|
| コマンドがホストに呼び出しを行ったことを確認する | プロキシ、または後から相手側に確認する |
| 対話型パネルや TUI を操作する | 擬似端末。シェルからその中に入力することはできません |
| CLI ではなく ウェブアプリ を検証する | Reticle と verify-ui-change スキル |
| 他の人が再確認できる判定結果を作成する | トランスクリプトではなく、検証アーティファクト |
絶対にしてはいけないこと
diff が予想と一致しなかったからといって、ステップ1で設定した期待値を弱めてはいけません。結果を見てから目標を書き換えると、検証ステップが正当化のステップに変わってしまいます。修正後の期待値は元の期待値とまったく同じように読めるため、後からトランスクリプトを見ても、その書き換えに気づくことはできません。
diff が一致しないなら、それが検証結果です。そのまま報告してください。