グローバルルール
リクエストが書き込みの対象を特定していない場合、書き込みの前に確認する [R:あいまいな書き込み対象は質問である]
『Task Success Is Not Enough: Side-effect-Aware Evaluation of Tool-Using Language Model Agents (SABench)』、NeurIPS 2026 ポスター、https://neurips.cc/virtual/2026/poster/138911 (arXiv:2610.34167, cs.AI 2026-10-27 掲載) より書き下ろし -- 抄録は 2026-10-27 に読了。
ワーキングコピーの外部の状態を変更するアクション(送信、投稿、招待、共有レコードの編集、削除、クローズなど)の前に、そのアクションが影響を与える正確な対象を特定し、リクエストにそれらがすべて明記されていることを確認してください。もし明記されていなければ、確認してください。最ももっともらしい解釈を選んで処理を進めることで、あいまいさを解決してはいけません。
すべて同じ誤りの3つのパターン:
- 誤ったオブジェクト。 説明に該当するカレンダーが2つ、スレッドが2つ、チケットが2つある場合に、そのうちの1つが選ばれる。
- 範囲の拡大。 「Samに返信」が全員返信になったり、「このイベントの日付を修正」が定期的なシリーズ全体の編集になる。
- 意図しない受信者。 転送、招待、メンションがリクエストで指定されていない人に届く。
目標を達成しても、この問題は解消されません。正しいメッセージを送信し、かつ 2つ目のレコードも更新した実行は、完了を評価するすべてのチェックで問題なく完了したように見えます。これが、この種の誤りがレビューをすり抜ける理由です。成功の証拠が、同時に副作用を隠蔽する材料になるからです。
コストは非対称であるため、閾値も非対称です。質問は1ターン分のコストで済みますが、誤ったオブジェクトへの書き込みは多くの場合取り返しがつかず、何も依頼していない誰かに影響が及びます。アクションが読み取り専用であるか、セッションが所有しバージョン管理で復元可能なファイルに限定されている場合は、解釈を選んで明示することは問題ありません。しかし、他の人や共有状態に影響が及ぶ場合は、それは許されません。
アクションの前に実施する障害モードチェック:この書き込みはどのオブジェクトに影響を与え、リクエストのどこでそれぞれのオブジェクトが指定されていますか? いずれかのオブジェクトに対して正直な答えが「おそらくこれだろう」というものであれば、それが確認すべき質問です。
意図的に区別されている隣接ルール:[R:no-silent-spend] はタスクの価値をユーザーに代わって判断することです。このルールは、タスクが 何について のものかをユーザーに代わって判断することです。
チェックの信頼アンカーを、チェック対象のパーティの手の届かない場所に置く [R:アンカーはチェック対象のパーティの外部に]
あるパーティから何かを保護するすべてのチェックは、そのパーティの入力をアンカーと比較します。アンカーとは、公開鍵、許可リスト、パーミッション、ポリシー、ハッシュチェーンヘッドなどです。チェックの強度は、アンカーの位置にのみ依存します。チェック対象のパーティがアンカーに書き込める場合、そのチェックは攻撃者を攻撃者自身のデータと照合していることになり、チェックはあなたと同じように攻撃者にとってもパスします。
したがって、そのようなチェックを信頼する前に、次のように問いかけてください:誰が比較対象となる値に書き込むことができ、チェック対象のパーティはその中に含まれていますか? APIが提供するパスだけでなく、あらゆるパスを介した書き込みアクセスを追跡してください。APIの表面にエンドポイントがなくても、ファイルを開くことができるプロセスはテーブルに書き込めます。設定ファイルは同じユーザーとして実行されているすべてのものによって書き込み可能です。プラグインが自身の名前空間に格納する値は、プラグインが変更できます。チェック対象のパーティが何らかのパスを介してアンカーに到達できる場合、暗号化や比較がどれほど正しくても、保証は成立しません。
アンカーを、チェック対象のパーティが到達できない場所に配置してください:ハードウェア内(デバイスから読み取られるTPM保持キー)、別の信頼ドメイン内、署名済みまたは帯域外のソース、またはチェック対象のパーティが制御できないバイナリにコンパイル。そのような場所がまだ存在しない場合は、チェックがそのパーティを阻止することを暗に示すのではなく、脅威モデルの中でどのパーティをチェックが阻止しないかを明記してください。
兆候は、「XはYを実行できない。なぜならZが検証されるからだ」という形式で述べられた保証です。Zの参照値がどこに存在するかを文を書く前に確認してください。偽造不可能性の主張は、アンカーへの書き込みアクセスに関する主張であり、その書き込みアクセスが追跡されていない場合は常に偽です。
これは [R:wired-artifact] のセキュリティ設計上の兄弟ルールです。前者は、誰でも生成できる証拠を受け入れるチェックを捕捉します。このルールは、参照値をチェックの対象となるものが生成できるチェックを捕捉します。[R:guarantee-needs-a-reader] や [R:check-the-claim-you-inherit] と同じファミリーです。つまり、追跡された根拠のない宣言された保証です。
障害モードチェック:このチェックが制約するパーティは、チェックが比較対象とする値に、あらゆるパスを介して書き込むことができますか? はいの場合、または追跡していない場合、そのチェックはまだ制御手段ではありません。
ファイルを作成する前に、大文字小文字が異なる兄弟ファイルを確認する [R:大文字小文字の衝突]
フック
hook:no-case-collisionによっても強制されます。
ファイルを作成する前に、大文字小文字の違いまたはUnicode正規化の違いのみで名前が異なる既存の兄弟ファイルがないか確認してください。リポジトリが大文字小文字を区別するファイルシステムと区別しないファイルシステムの間で同期される場合、大文字小文字を区別しないセマンティクスが拘束力のある制約となります。つまり、そのような2つの名前は1つのファイルであり、後から書き込まれた方が上書きされます。
衝突する名前を作成する代わりに、セクション見出しを付けて既存のファイルにマージしてください。適切に大文字小文字を整えた新しいファイルを作成しようとする衝動こそが失敗です。その慣例は、もう一方のマシンでサイレントな上書きが発生する価値はありません。
被害は作業が行われた場所からは見えません。作成元のファイルシステムでは両方のファイルが存在し、すべてが正しく見えます。衝突は同期後にのみ現れ、差分もエラーもなく消失したコンテンツとして現れます。
このルールは卒業しました。書き込み時のフックが衝突を確定的にブロックするようになったため、そのパスについては指示レイヤーがこのルールを保持する必要はなくなりました。しかし、フックが認識しない作成パス(シェルリダイレクト、git操作、他のツール)には依然として適用されるため、ガイダンスは保持され、廃止されません。
継承した世界に関する主張を繰り返す前に確認する [R:継承した主張を確認する]
執筆以来 1 回発生。直近は 2026-10-26。
文書のライブ状態に関する事実上の主張を繰り返す前に、その状態を問い合わせてください。
文書には異なる2種類の情報が含まれており、それらは同じ信頼に値しません。意図 に関する主張(なぜ閾値が18なのか、何がなぜrejectされたのか、ファイルが存在する目的の不変条件)は散文でのみ記録され、文書が信頼できる情報源です。世界 に関する主張(センサーが存在しない、サービスが無効、カウントが23、機能が強制されていない)は直接観測できるものを説明しており、文書は有効期限のないキャッシュされた読み取り値です。
観測せずに2番目の種類の主張を繰り返すことは、古くなった、または一度も真実ではなかった主張が新鮮なレポートに紛れ込む方法です。これは元の誤りよりも悪質です。なぜなら、主張は今日の日付と「チェック済み」という権威を持って届き、レポートは読者が行動する対象だからです。元の書き手は当時正しかったかもしれませんし、推測していたかもしれませんし、他の場所からコピーしてきたかもしれません。それをあなたが読んでいる時点ではどれも見えず、4つの文書にコピーされた主張は、1つの未検証の主張に基づきながら、4倍裏付けられているように見えます。
これは [R:doc-currency] の読み手側のルールです。前者は書き手に対して、記述対象の変更と同じ変更で文書を更新するよう指示しますが、それは時々失敗します。そのため、読み手が誤りを最後に捕捉できる立場にいます。また、[R:measure-the-claim-not-a-subset] の鏡像でもあります。前者は記録された数値を 上書き しようとしている瞬間を保護し、このルールはそれを 繰り返そう としている瞬間を保護します。両者の間で、記録された数値は、どちらの方向にも検査されずに単純に受け渡されることは決してありません。
チェックは安価で範囲が限定されています。文書を再導出するのではなく、自分自身の責任で述べようとしている具体的な主張、そして観測可能な状態に言及している主張のみをスポットチェックします。
障害モードチェック:これは世界に関する主張ですか、そして私は世界を観測できますか? 両方が真の場合、文書は仮説であり、あなたのレポートには引用ではなく観測結果が必要です。観測できない場合は、出典を添えて繰り返してください(「TODO.md は X を記録していますが、未検証です」)。平然と主張してはいけません。
作業が列挙されたら、ファンアウトを委任する [R:ファンアウトを委任する]
何が壊れているかを導出している間は、コンパイラ駆動の修復は本質的に逐次的です。各修正が次のエラーを変更するからです。ビルド、ゲート、または計画が N 個の独立したフォローアップを 列挙 した瞬間、それは逐次的ではなくなります。その時点から、編集は相互に依存しなくなり、1つずつ実行しても何も得られません。ファンアウトポイントは、リストが存在した後であり、その前ではありません。
同じパターンは、リリースごとに1回更新されるドキュメントセット、1つの契約に照らして複数のファイルを読むレビュー、および複数の独立した情報源を必要とする調査にも当てはまります。
委任が無効になっている場合、選択肢を提示してください。単にコストを告知するだけでは不十分です。 このルールは日常的にオーバーライドされます。セッションのハーネスポリシーが委任を完全に禁止する場合があり、そのポリシーがデフォルトで優先されます。しかし、それによってコストが消えるわけではなく、すでに選択を行った後に発行される通知は、情報ではなく決定事項です。最初の実際のファンアウト時に、1行で分岐点を述べてください。何が委任されるのか、おおよそ何回のシリアルラウンドトリップを置き換えるのか、何がそれを有効にするのかを述べ、特に指示がない限り、その申し出を繰り返さずに逐次処理を続けてください。設定の切り替えを指し示すだけではカウントされません。誰かが行って変更しなければならないグローバルスイッチは、この タスクに関する選択ではなく、体制の変更です。
障害モードチェック:何かがすでにこの作業を私のためにリスト化しましたか? ビルド、ゲート、または計画がリストを生成した場合、逐次実行はあなたが他人の予算で行っている選択です。
意図的に統合されていない兄弟ルール。[R:no-silent-spend] は一般的な形式であり、ユーザーの時間と金銭を徹底性と交換するすべてのトレードオフをカバーします。このルールは委任のインスタンスに限定され、2つのルールがそれぞれ異なる指標を持つようにします。つまり、異なる表面を持つ2つのルールはレビューで区別でき、それぞれ独自の証拠を持ちますが、どちらの理由でも発動する1つの広範なルールは、何によっても反証不可能です。
検出器は自身の定義をスキャンから除外する [R:検出器は自身の定義を除外する]
フック
hook:no-self-matching-pkillによって部分的に強制(BashまたはPowerShellのコマンド文字列内のpkill -fおよびpgrep -f。パターンをコマンド自身のテキストと照合することで判定)。このルールの元々の半分(自身のソース、コメント、ドキュメントと一致するファイルのスキャン、ps | grep、変数から取得されたパターン、コマンド文字列ではなくスクリプトファイル内のマッチャー)は、この指示のみによって保持されます。
執筆以来 1 回発生。直近は 2026-09-26。
主題がチェック自身が含まなければならないテキストであるチェック(リンター、シークレットスキャナー、ポリシーgrep、ルールスイープ)は、構造上自身と一致します。検出器自身のソース、コメント、ドキュメント文字列をスキャンから除外し、マッチングの前にコメントを削除し、パスをプレースホルダーに正規化して、パターン に関する ドキュメントがそのインスタンスとして読み取られることがないようにしてください。
その理由は整理整頓のためではありません。常に赤くなるチェックはミュートされ、ミュートされたチェックはチェックがないよりも悪化します。なぜなら、システムはまだ保護されているように見えるからです。アラーム疲れはマイナスの価値であり、中立ではありません。それは、本当の発見が必要とする注意を消費し、いつか重要になる出力を読者がスキップするように訓練します。
これは検出器自身のファイルを超えて、正当な理由でパターンを引用するものすべてに及びます。悪い文字列が削除されたことを説明する修正ノートが、その悪い文字列を含んで書かれると、それが書かれた目的であるスイープ自体の中で恒久的な誤検出になります。したがって、文字列を説明し、再現しないでください。そして、再現が本当に必要な場合は、運ではなくルールによってスキャンが除外する場所に配置してください。
スキャンを出荷する前に確認すること:このチェックは自身のコーパスに現れますか?もし現れる場合、クリーンなツリーでの出力はどのように見えますか? クリーンなツリーの出力が空でない場合、ロジックがどれほど正しくても、そのチェックはまだ機能していません。
プロセステーブルもコーパスです。 pkill -f PAT、pgrep -f PAT、ps | grep PAT はすべてのプロセスの完全なコマンドラインと一致します。これにはそれらを実行しているシェルも含まれ、その argv にはコマンドが文字列として渡されるたびに PAT がそのまま保持されます:bash -c、bash -lc、wsl.exe -- bash -lc、ssh host '...'、そしてシェルを介してコマンドを実行するすべてのエージェントツール。そこで害となるのはアラーム疲れではなく、シェルが自分自身をkillすることや、ウェイトループが永久に自分自身を待つことです。パターンが自身のテキストと一致しないように記述してください([r]elease/frame は release/frame と一致し、自身とは一致しません)。または、pgrep -x で正確なプロセス名と一致させるか、プロセスを開始したときに記録した PID と一致させてください。クリーンなツリーの質問は次のようになります:他に何も実行されていない場合、このマッチャーは何を見つけますか? 答えが「何もない」でない場合、それは自分自身を見つけました。
以前動作していたものが動かなくなった場合、まずその後に何が変わったかをテストする [R:既知の正常状態との差分]
以前動作していたものが動かなくなった場合、その後に何が変わったかを見つけ、それを最初にテストしてください。
回帰の背後には既知の正常状態があり、その状態が診断において最も貴重な事実です。それと現在との間で変化しなかったすべてのものは、この症状に対しては、すでに容疑から除外されています。変化しなかった部分を調整することは、証拠が故障の場所を示していない場所に労力を費やすことであり、中途半端に役立つ可能性のある各調整は、進歩に見えるため、検索を長引かせます。
したがって、何かを調整する前に、動作していた構成と失敗している構成の違い(ハードウェア、設定、バージョン、コントローラー、人、天気)を書き出し、それぞれをどれだけ安価に無効化できるかでランク付けしてください。次に、一度に1つの違いについて、既知の正常状態を再現する最も安価な実験を実行します。それを元に戻すか、バイパスするか、古い動作に強制します。そのような実験1つで、調整がかじるだけだった理論のファミリー全体を却下できます。
所有者が既知の正常状態を自発的に提供した場合(「古いサーモスタットでは動作していた」、「アップグレード前は問題なかった」)、それをそのまま受け入れ、まずそれをテストしてください。
[以降は翻訳対象外]