mcpField
S
session-bash-audit

session-bash-audit

github.com/theodoreadエージェントワークフロー044 回インストール4 週間前に更新
リポジトリ

session-bash-audit について

session-bash-auditはClaude Codeのセッション記録を読み取り専用で分析し、Bashコマンドの傾向とルールへの適合状況を測定します。セッション行動の確認や測定結果の比較、権限プロンプトの調査に使え、レポートの解釈上の制約も示します。

主な機能

  1. 01Bashコマンド傾向の測定
  2. 02保存したベースラインとの比較
  3. 03権限ルールの再現
  4. 04現在の権限の検証
  5. 05単一セッションや期間の確認

活用シーン

  1. 01複数セッションでのBashルール遵守状況の確認
  2. 02変更前後の動作の比較
  3. 03繰り返し発生する権限プロンプトの調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/theodoread/agent-skills --skill session-bash-audit

インストール後、Claude Code で/session-bash-auditを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

README.md
references/
research.md
references/baselines/
2026-08-24-auto-mode.json
scripts/
audit.py
prompts.py

詳細

Session Bash 監査

Claude Code セッションで Bash ツールが実際にどのように使われているかを、常時読み込まれる指示ファイルに記載された Bash ルールと照らし合わせて測定し、その数値をもとに、修正を「どこに」適用すべきかを判断します。最初の実行(2026-08-24、4 日間で 3,956 回の呼び出し)の結果は references/research.md にまとめてあります。新しい実行結果を解釈する前に、「Root causes」と「Mode comparison」のセクションをお読みください。推論の大半はそのまま当てはまり、再検討する必要はありません。

~/.claude/ を読み取ります。対象は、トランスクリプトの保存先である ~/.claude/projects/*.jsonl と、権限の再現に使う ~/.claude/settings.json です。どちらも Claude Code 自体が使用する読み取り専用のファイルであり、書き込まれることはありません。そのため、Claude Code を実行するマシンならどこでも動作し、インストールも不要です。それ以外のハーネスでは読み取るものがないため、スクリプトはゼロ件として報告せず、その旨を伝えます。ここに掲載している測定値とベースラインは、ある一人のマシンで、ある一組のルールのもとで得られたものです。自分自身のベースラインではなく、比較用の参照点として扱い、初回実行時に自分の値を保存してください。

ここにあるパターンはすべて POSIX シェルのイディオムです。&&、;、|、cd、sed -n、ヒアドキュメントなどが該当します。つまり、この監査が対象とするのは、Bash ツールが POSIX シェルを実行するセッションです。Windows では Git Bash または WSL のセッションが対象で、変更なしで適用できます。PowerShell のセッションでは、これらのパターンに一致しないコマンドが生成されます。そのため、レポートに「問題なし」と表示されても、実際には「このトランスクリプトに対してツールが違う」という意味です。実際の PowerShell のトランスクリプトで実行されるまでは、Windows で不自然なほど問題がない結果が出た場合、まず疑うべきは「問題なし」ではなく、2 つ目の可能性です。

cd-own-repo と git-C-own-repo は、Claude Code がプロジェクトディレクトリをスラッグ化する方法でコマンドの対象をスラッグ化し、「自分のリポジトリ」かどうかを判定します。しかし、2026-09-05 までは、どのプラットフォームでも誤っていました。ハーネスが行うのは、ASCII の英字または数字以外のすべての文字の置き換え(当日の CLI バイナリから読み取ったルールで、200 文字を超える場合はハッシュサフィックスが付きます)なのに、このスクリプトは / と . だけを置き換えていたのです。そのため、パスにアンダースコアを含むリポジトリは一致せず、両方の行でゼロと報告され、完全にルールが守られているように見えていました。スクリプトは現在、ハーネス自身のルールを使うため、Windows のパス(\、:)も Linux のパスと同じようにスラッグ化されます。ただし、上の段落のとおり、これらの行がゼロであることの信頼性も、トランスクリプトが POSIX シェルのものかどうかに左右されます。

どのプラットフォームでも、Git ワークツリーから実行されたセッションでは、同じ 2 つの行が気づかれないまま誤った結果になります。これは、トランスクリプトに異常が見えないため、より厄介な問題です。 どちらのタグも、コマンドの対象とプロジェクトのスラッグを完全一致で比較します。一方、ワークツリーのセッションのスラッグはリポジトリのものではなく、ワークツリーのパスです。そのため、git -C <the main checkout> の呼び出しは(ブランチがマージされる場所であり、隣接するワークツリーのツールも引き続き参照するため、ワークツリーから実行する場合に最もよくある、自分のリポジトリを対象とする形式です)、別のものとしてスラッグ化され、タグがまったく付きません。同等の cd は cd-other とタグ付けされます。これは推奨される「別のリポジトリ向け」の形式に付けられる名前です。このルールは、違反の可能性が最も高いセッションでまさに測定されず、ゼロと報告されます。

これは修正ではなく、明示された制限事項です。データから修正を裏付けられないためです。このスクリプトはトランスクリプトをオフラインで読み取り、ディレクトリが消えている可能性のある後になって実行するため、スラッグがどのチェックアウトを指していたのかを Git に問い合わせることはできません。手がかりになるのはスラッグ自体の形状だけですが、存在するのは複数あるレイアウトのうち 1 つだけです。Claude Code の <repo>/.claude/worktrees/<name> は --claude-worktrees- というセグメントを残します(これはハーネスのスラッグ化ルールから導かれたもので、実際に観察されたものではありません。この作者のマシンにある 211 個のプロジェクトディレクトリにワークツリーはありません)。一方、VS Code の既定の <repo>.worktrees/<name> と、チェックアウトの隣にあるフラットな <repo>-<branch> は、通常のリポジトリ名と見分けがつきません。一方のレイアウトだけに対する中途半端な修正は、ほかのレイアウトでルールが確認済みであるかのように見せてしまいます。Windows の場合と同じく、セッションがワークツリーから実行された可能性がある場合は、この 2 つの行がゼロでも未検証として扱ってください。 exit-masked はパイプラインの形を数えるだけで、その形によって何かが隠されたかどうかは、このスクリプトでは答えられず、マシンごとに異なります。 パイプラインはデフォルトで最後のステージのステータスを報告します。これがこの行の名前の由来です。ただし、pipefail が設定されたシェルでは、右端のゼロ以外のステータスが報告されます。そのため、inv quality.precommit 2>&1 | tail -3 はゲートが失敗すればゼロ以外で終了し、何も隠されていません。トランスクリプトに記録されるのはコマンドであり、シェルではありません。そのため、高い割合に意味を読み取る前に、セッション自身のシェルに確認してください。監査対象のセッションで Bash 呼び出しとして、zsh なら setopt | rg pipefail、bash なら set -o | rg pipefail を実行します。設定ファイルを見ても答えにはなりません。このオプションはハーネス変数で条件分岐されていることが多く(筆者のマシンでは ~/.zshenv が CLAUDECODE の場合に限って設定します)、同じマシンでもエージェントのシェルでは有効になり、それ以外ではどこでも無効ということがあります。

session-harvest の claims は、同じ名前の行を別の方法で数えるため、2つの数値は互いに反対方向に誤っています。 harvest.py の EXIT_MASKED_RE は生のコマンドにマッチするため、引用符付き文字列やヒアドキュメント本体に書かれたパイプラインも実際のものとして数えます。一方、audit.py はその両方を取り除くので、引用されたものを見逃しませんが、2026-09-06 までは、ヒアドキュメント以降のコマンドをすべて落としていました。その日までの1週間に claims が検出し、audit.py が検出しなかった390件の呼び出しのうち、388件はそのヒアドキュメントのバグで、2件は実際に引用符付きで言及されたものでした。バグは修正済みですが、引用による過剰カウントは残っています。そのため、今日この2つを比較する場合、claims のほうが少し大きくなると予想されます。同日のあるセッションでは7対4で、余分な3件はいずれも python3 - <<'PY' の調査用コード内の 2>&1 でした。2つのスキルは別々にインストールされ、互いをインポートできないため、ストリッパーを共有することは plans/2026-09-03-skill-dependencies-and-bundling.md の検討事項です。それまでは、この差は想定内であり、どちらの数値ももう一方を検証するものではありません。

この行は残り、2つの理由から EXPECTATIONS による評価の対象外のままです。どちらの理由も同じ結論を示しています。このガードがあるため、同じコマンドでも cron、CI、コンテナ、そしてその設定がないマシンでは依然としてステータスが失われます。この形が無害だと学習したセッションが、そのコマンドを別の場所で実行されるスクリプトに書き込む可能性もあります。また、トランスクリプトから算出する評価では、コマンドを実行したシェルが分からないため、前提に依存した確信めいた数値になってしまいます。head/tail は代わりに出力の欠落からその習慣を評価するため、どこでも成り立ちます。

このスキルが読み取り、実行し、書き込むもの

  • 読み取り:~/.claude/projects/*.jsonl と ~/.claude/settings.json。いずれも Claude Code 自身のファイルで、読み取り専用です。また、存在する場合は、独自の期待値を $XDG_CONFIG_HOME/session-bash-audit/expectations.json(Windows では %APPDATA%\…)、または --expectations <path> で指定した場所から読み取ります。
  • 実行:このスキル自身のディレクトリに対する、読み取り専用の git コマンドを3つ。ベースラインの書き込み時に限り、計測を行ったツールのバージョンを記録するため、audit.py 自身に対して ls-files、rev-parse HEAD、status --porcelain を実行します。それ以外は何も実行しません。prompts.py はアクセス許可ルールをプロセス内で再現し、Probe 手順では、ユーザーが実行して結果を読むためのコマンドを表示します。
  • 書き込み:--save-baseline を指定した場合に限り、ベースラインを $XDG_STATE_HOME/session-bash-audit/(Windows では %LOCALAPPDATA%\session-bash-audit\)に書き込みます。すでにベースラインがある場合は上書きせずに拒否します。意図的に削除するには --force を使います。ダンプは --json <path> で指定した場所に書き込みます。トランスクリプト、設定、自身のインストール先には決して書き込みません。
  • ネットワーク:使用しません。

4つの手順 — スキルが実行し、ユーザーは結果を読むだけです

該当するものはどれですか。

質問手順
「Bash を使うセッションの状況はどうか」、測定の新しいパターン測定(以下を参照)
「変更はうまくいったか」、「再確認」、変更から1週間後ベースラインと比較
「権限設定は想定どおり動作するか」、モードやルールの編集後稼働中の権限を調査
「プロンプトが多いのはなぜか」、「まだプロンプトが出るのは何か」プロンプト — ルールを再実行する
「このセッションの状況はどうか」、ハーベストからベースラインに対して**--session**

最初の3つには scripts/audit.py、4つ目には scripts/prompts.py を使います。 以下では S=~/.agents/skills/session-bash-audit とします。

測定

python3 $S/scripts/audit.py --days 4 --samples 5
python3 $S/scripts/audit.py --days 7 --project <repo> --json <scratch-dir>/calls.json

読み取り専用で、標準ライブラリのみを使用し、1週間分のトランスクリプトなら約10秒です。テーブルだけを表示するには --samples 0 を指定します。 --json のダンプは、アドホックな追加質問をする際の入力になります(ここではそのデータに対して python3 -c を実行してもかまいません。リポジトリのコードではなく、一度限りのスナップショットだからです)。ダンプはジョブ/セッションのスクラッチディレクトリに置き、/tmp に直接置かないでください。

ベースラインに対する単一セッション — セッションがまだその結果を受けて行動できるうちに答えが返ってくる唯一のモードです。session-harvest のステップ5でこれを呼び出します。セッション全般ではなく、自分の状況を知りたいセッションから直接実行してください。

python3 $S/scripts/audit.py --session <session-id> --compare ~/.local/state/session-bash-audit/<file>.json

ID はトランスクリプトのファイル名から拡張子を除いた部分で、一意なプレフィックスを指定すれば十分です。このスクリプトのほかの機能はすべて事後に傾向を測定しますが、これは実行中のセッションを測定します。

割合ではなく件数として読み取ってください。 セッションビューでは、各行に件数を先に表示します。

== this session, 247 calls ==
  head/tail                   38   15%
  exit-masked                 22    9%   14 wrapped a gate, 8 a listing
  rg-replace                   1    0%   -rn x 1

ゼロ件も含めてすべての行が表示されます。件数も示されるのは、セッション規模の割合では、実際の検出結果が丸められて見えなくなるためです。中央値が247回の呼び出しであるセッションでは、1件は0.40%ですが、表示は 0% になります。2026-09-06に67セッションを対象に測定したところ、rg-replace が検出された30セッションのうち、13セッションは 0% と表示されていたことになります。0 は確認済みで問題がなかった行です。行自体がまったく表示されない場合は、このビューが rg-replace、find-not-fd、grep-r-not-rg、find-exempt に対してそれまでその状態でした。コーパステーブルの列を引き継いでいましたが、コーパステーブルにはこれらの項目を表示する幅がなかったからです。

異なる2種類の失敗を1つの数値で示しても対処につながらないため、2つの行には内訳があります。exit-masked は、マスクされた呼び出しのうち、ゲートを実行したものと一覧表示を実行したものを分けます。一覧表示を40回マスクしても読む人はいませんが、ゲートを1回実行してその後に「問題なし」とするのは別です。rg-replace はフラグの表記を示します。-rn は行番号を失わせ、一致したテキストを書き換えます。-ril は大文字小文字を区別しないファイル一覧検索を、大文字小文字を区別する行検索に変えます。また、単独の -r はたいてい、意図的に使う rg -o -r '' という抽出イディオムであり、そもそも間違いではありません。

コンパクションされたセッションは2つのセッションであり、全体の行はどちらの実態も表していません。 トランスクリプトに継続ターンが含まれる場合、レポートには全体の下に、その前後それぞれの行が表示されます。7日間のバックグラウンドジョブで2026-09-13に確認したところ、コンパクション前はコマンドチェーンが67%、head/tail が48%、ヒアドキュメントが32%でしたが、後は1%、0%、0%でした。これを1つのセッションとして読むと47%、33%、22%となり、実際の誰の動作も表していません。セッションの最近の呼び出しが合計値とまったく異なるように見えたため気づきましたが、これは確認方法にはなりません。分割にはハーネス独自の isCompactSummary フラグを使います。継続ターンの冒頭の文で判定した場合、実際の10 MBのトランスクリプト1つで3件が返され、そのうち2件は、この文について話し合うセッション自身がその文を引用したものでした。

--since は --until の反対側に当たるため、ウィンドウは2回の実行と差し引きではなく、2つのフラグで指定できます。件数は差し引かれますが、サンプル、ゲートと一覧表示の内訳、切り詰めに関する行は差し引かれません。これらは、試したすべての実行で全体のプレフィックスを説明していました。

python3 $S/scripts/audit.py --session <session-id> --since <the continuation turn's instant> --samples 4

このモードでも --json <path> を使用でき、出力されるレポートの対象と同じ、ウィンドウでフィルターされたセットを書き出します。2026-09-06 までは、--session のパスがフラグを読み取る前に戻っていたため、エラーもファイルもないまま、session-harvest が常に使うこのモードで書き出しを利用できませんでした。 --save-baseline はここではスキップせず、拒否されます。1つのセッションのレートはコーパスのベースラインではなく、何もせずに黙って終わるフラグより、そう伝えるフラグのほうが望ましいためです。

ここで同梱されているベースラインではなく、自分で保存したベースラインと比較してください。 $S/references/baselines/ には、作成者のマシンでそのマシンのルールに基づいて測定したファイルが1つあります。これは参考値であり、セッションを --compare すると、自分のセッションと他人の環境との差が報告されます。初回実行時に自分のベースラインを保存し(--save-baseline)、それを使ってください。数値が悪い実行でも保存してください。ここでためらう人がいます。ベースラインは目標として読み込まれることはありません。EXPECTATIONS は方向性(down または zero)を示すため、判定は差分に基づいて計算されます。したがって、最初のベースラインが悪くても、次の実行で超えるべき基準が設定されるだけです。満足できる実行からしか保存しないと、基準が測定値ではなく選別結果になり、時系列が損なわれます。

[PITFALL: どのモードでも、毎回、パイプを使わずに実行してください。 出力は数十行で、ハーネスは全体を保持します。レポート自体が head/tail による切り詰めを対象としているのに、| head -N を付けると、再実行が必要になるだけでなく、誤った結論に至ることがあります。2026-09-02 に確認:あるハーベストでは、このコマンドを … --compare … | head -12 として実行し、レートの行と最初のサンプルブロックを見て、--compare は比較結果をまったく出力しなかったと結論づけました。エラーも、OK/MISS 列も、n/m expectations met の行もありませんでした。その後、ベースラインの JSON を手作業で読み、差分を再構成して、スクリプトとベースラインを原因候補とする計画を提出しました。どちらも原因ではありませんでした。比較結果は、切り詰められた箇所から40行下に出力されていました。同じセッションでは head/tail が45% でした。これにより、発見とその原因が1回の実行で明らかになりました。

現在はどちらのモードでも比較結果がサンプルブロックより上に出力されるため、出力が切り詰められても判定ではなく大部分が失われます。ただし、これは二重の防御策であり、パイプの使用を許可するものではありません。]

[PITFALL: ルールを書いたばかりのエージェントが、そのルールに従う可能性が高いとは限りません。そのため、この数値をセッションに実行結果を尋ねて置き換えることはできません。2回確認済みです。2026-08-30:head/tail にゲートを通すことを禁止するルールを書き続けていたセッションは、自身の呼び出しの33%でそのパターンを出しました。測定対象のセッションよりも悪い結果でありながら、自己評価では「うまくいった」と報告しました。2026-09-01:_このモードを実装した_セッションは、自身を測定した結果、head/tail が47%、書き換え前のベースラインより+17ppとなり、ほかにも3つの失敗がありました。自分のコミットメッセージにルールを引用していたにもかかわらずです。2回とも同じ結果で、どちらのケースでもセッション自身は実行に問題がなかったと感じていました。]

[PITFALL: 以前は heredoc がコミットの多いセッションで過剰にカウントされていましたが、2026-09-01 に解消されました。 ここでは複数行のメッセージを書く推奨方法が、本文に heredoc を使った git commit -F - だったため、コミットのたびにタグが付き、この列はセッションのコミット数と照らし合わせて読む必要がありました。 ~/.agents/AGENTS.md ではそのルールが逆になりました。メッセージはバッククォートや $ を使わず、-m にインラインで記述するようになりました。-m では承認プロンプトにメッセージが表示されますが、-F <file> ではパスの背後に隠れるためです。そのため、コミットの多いセッションで heredoc が検出された場合、再び実際の発見であり、単なるアーティファクトではなくなりました。この変更をまたぐサンプルでは、そのセッションが保持していたバージョンのルールへの準拠度が測定されます。サンプルには、測定時に適用されていた ~/.agents/AGENTS.md のコミットを記録してください。そうしないと、逸脱に見えるレートが、実はセッションが以前のルールに正しく従った結果である可能性があります。]

比較 — 手作業で表を読む必要がない、「うまくいったか」の確認です。

python3 $S/scripts/audit.py --days 7 --samples 0 --compare $S/references/baselines/2026-08-24-auto-mode.json

各モデルの現在の割合をベースラインの横に表示し、差をパーセンテージポイントで示します。各予想の結果は OK/MISS で表示されます (スクリプト内の EXPECTATIONS:連鎖、head/tail、sed -n、cat、ヒアドキュメント、git-in-chain は down、 自分のリポジトリ内での cd と git -C による変更、および組み込みの rg -r はゼロ)。いずれかの実行で呼び出し回数が50回に満たないモデルは、判定対象ではなく ? と表示されます。

これらの予想はある著者独自のルールセットであり、Bash に関する事実ではありません。ご自身のルールセットで評価してください。 各項目は、あるマシンの ~/.agents/AGENTS.md を読み取った結果です。find-not-fd が down なのはそのファイルが fd を推奨しているためであり、cd-own-repo が zero なのはその形式を明示的に禁止しているためです。ご自身の指示がどうであれ、項目の内容は変わりません。借用するのは判定だけです。独自のルールを {"<row>": "down"|"zero"} 形式の JSON で記述して --expectations <path> を指定するか、$XDG_CONFIG_HOME/session-bash-audit/expectations.json(デフォルトは ~/.config/…、Windows では %APPDATA%\…)に置けば、何も指定しなくても読み込まれます。

{ "chain": "down", "head/tail": "down", "cd-own-repo": "zero" }

このファイルは同梱のセットに追加されるのではなく、置き換えます。2つのドキュメントに同時に帰属する判定は、誰も読み返せない判定になってしまうためです。そのため、評価対象にする項目はすべて改めて記述してください。不明な項目名や down/zero 以外の判定を指定すると、有効な値を示すエラーになります。何も評価されないまま項目が黙って無視されることはありません。比較のヘッダーには、使用したドキュメントが表示されます。

zero の予想は件数で判定され、セルには差ではなくその件数が表示されます。 2026-09-06までは率の範囲(<= 2%)で判定していましたが、これはどんな規模でもゼロの定義にはならず、両極端で問題を見えなくしていました。その日までの7日間では、最も呼び出し回数の多いモデルのゼロ項目はすべて合格していた一方で、数百件の該当例がありました。git-C-mutating は288件、git-C-own-repo は231件、echo-exit は146件、cd-own-repo は94件で、すべて OK と報告されていました。また、157回の呼び出しがあったセッションでは、実際に使われた rg -rn が1件あったにもかかわらず、セッション表示の件数とは異なり 1%(OK) と表示されました。反証できない判定は問題を隠します。それは、問題を大げさに示す判定よりも悪いものです。コーパスの判定行に、以前より多くの不合格が表示されることを想定してください。不合格は以前から存在していました。テストは絶対値で行われるため、差は表示されません。ゼロに近い項目のパーセンテージポイント差は -0pp に丸められます。また、分母が異なる件数の差では、160回のセッションを15,000回のベースラインと比較した際に、改善したかのように見えてしまいます。

zero の予想は rg-replace 自体ではなく、rg-replace-bundle で評価します。 親項目は、意図的な抽出イディオム rg -o -r '' <pattern> <path> と、誤操作の両方をカウントします。2026-09-06までの30日間にあった86件のうち、13件はこのイディオムでした。そのため、そこで zero を要求すると、実際のフラグの正しい使い方まで禁止することになります。バンドル項目は常に誤りとなる方です。r を含む2文字以上のフラグは、-r がグループの残りを置換文字列として取り込んだことを意味します。判定行と不合格項目をユーザーに報告し、「修正箇所の判断」の表に従って各不合格項目の対応先を決めてください。ルールまたはモードを変更した後は、次の比較に備えて新しいベースラインを保存してください(--save-baseline --note "<mode in force>")。古いファイルも残してください。差分こそが重要です。

保存したベースラインは $XDG_STATE_HOME/session-bash-audit/(デフォルトは ~/.local/state/…、Windows では %LOCALAPPDATA%\session-bash-audit\)に保存されます。現在、引数なしの --save-baseline で書き込まれる場所です。2026-09-03までは、この行に $S/references/baselines/… と記載されていました。そこはインストール済みスキルの内部であり、再インストール時に置き換えられる成果物です。また、このコーパスでは別の箇所で、編集すべきドリフトと呼ばれています。スキルが保持を求める、真にマシンごとに異なる状態を、上書きされるよう設計された場所に保存していたのです。別の場所に保存したい場合は、明示的なパスを指定してください。インストール先以外ならどこでも構いません。

プローブ — トランスクリプトには記録できない、実際の権限の挙動です。

python3 $S/scripts/audit.py --probe

このマシンのルールに基づき、各コマンドでプロンプトが表示されるかどうかも含めて、6つのコマンドを出力します。acceptEdits のもとで実行してください。 それぞれを独立した Bash ツール呼び出しとして実行してください。スクリプトから実行すると、テスト対象であるハーネスの権限チェックを迂回してしまいます。<scratch> には、ハーネスで設定されている場合は $CLAUDE_JOB_DIR/tmp を、そうでなければリポジトリ外の任意のスクラッチディレクトリを指定します。エージェントはプロンプトを確認できません。実行後、プロンプトが表示されるはずだった手順を列挙し、実際にどう見えたかをユーザーに確認してください。一致しない場合は、ルールがモードの許可を上書きしている、プレフィックスルールが一致していないなど、実際の問題として扱い、日付とともに references/research.md の「Harness facts」に記録し、修正を適切な担当先に振り分けてください。

プロンプト — ユーザーから「確認が多すぎる」と報告があった場合、どの呼び出しで、なぜプロンプトが表示されたかを確認します。

python3 $S/scripts/prompts.py --days 2
python3 $S/scripts/prompts.py --since 2026-08-24T19:13:00Z --project <repo>

承認済みのプロンプトはトランスクリプトに痕跡を残さないため、この処理ではハーネスの照合ロジック(区切り文字で分割し、ask を allow より優先し、組み込みの読み取り専用セットと acceptEdits の適用範囲内の許可を考慮)を、現在の ~/.claude/settings.json に照らして再現し、セッションごとのプロンプト表示率の推定値と、各呼び出しで最初に該当したプロンプト表示理由をサンプル付きで順位付けして出力します。ルール変更の前後に実行してください。「変更後」の実行で確認するのは、単に別の形に変わっただけではなく、そのパターン自体がなくなったことです。理由ごとに、以下の表に従って適切な担当先に振り分けてください。ほとんどの場合、原因は説明文ではなく、権限ルールを生成する仕組みにあります。これを導入した 2026-08-25 の実行結果は、references/research.md の「Prompt audit」に記載されています。

Measure の出力は、次の順に読みます。

  1. per model — ベースラインです。references/research.md の「Baseline 2026-08-24」の表と比較してください。連鎖実行と head/tail の割合が主要な指標です。2026-08-24 の変更後は、cd-own-repo、git-mutating-in-chain、git-C-mutating がほぼゼロになっているはずです。
  2. per session — 平均ではなく、外れ値を確認します。同じルールでも、連鎖実行率が 90% のセッションと 15% のセッションがある場合、これはルールの文言ではなく、処置やタスクの形に関する問題です。ルールを変更する前に、そのセッションのサンプルをいくつか読んでください。
  3. pattern totals — 各行にはコスト(「why」)が含まれています。「prompt friction」がコストとして示されているパターンの件数が多くても、影響があるのはプロンプトが表示されるモードに限られます。対象期間中に有効だったモード(~/.claude/settings.json の permissions.defaultMode と、セッション側で上書きされていたかどうか)を確認してください。
  4. truncation 後の再実行 — | head/| tail の直接的なコストです。出力上限を増やして同じコマンドを再実行した場合を指します。それぞれ、呼び出しが無駄になるうえ、再実行の間に切り詰められた出力をもとに判断が行われた分のコストも発生します。
  5. denied — 分類器による拒否(Blocked by classifier)は、そのセッションで自動モードが有効だったことを意味します。「ユーザーが続行を望まない」は、人による拒否です。どちらの場合も、どのようなコマンドの形が拒否につながったかを確認する価値があります。

修正箇所を決める

監査の目的は、「指示ファイルに一文追加する」という反射的な対応を防ぐことです。仕組みに応じて適切な箇所に振り分けてください。右の列には修正を加えるべき場所の 種類 を示しています。括弧内には、具体例として作者のマシン上での場所を示しています。

調査結果修正箇所
ルールに記載された 理由 が当てはまらなくなった(例:「プロンプトの手間」が、プロンプトを表示しないモードで使われている)ルール自体のソースを書き換えます。より強い表現で言い直すのではありません。問題が理由にある場合、文言だけでは発生率は変わりません。(agents-md のフラグメントと、その隣に置かれた根拠ページ)
コマンドの形式で確認を求められるが、読み取り専用で一般的である権限の許可リストに、プレフィックスルールとして追加します(生成される tools.toml のエントリ)。ただし、Claude Code での git -C 形式のようなコマンドには適用できません。そこではプレフィックスルールが一致しないため、サンドボックス側で対処します
コマンドは正当に write だが、コードを失う可能性がなく、指示によって実行頻度が高くなっているそのツールに許可オーバーライドを設定し、実際にコードを失う可能性があるフラグ形式には確認オーバーライドを設定します(git add と git reset --hard の違い、2026-08-25)
読み取り専用のタスクランナー呼び出しで確認を求められるタスクごとの明示的な許可ルールを追加します。タスクランナーはリポジトリごとの任意のコードを実行するため、その全機能を一律に許可することはできません。名前を指定したタスクのみを列挙します
コマンドの形式が、プレフィックスルールよりも細かく権限モードによって制御される許可リスト自体にモード対応を実装します。ハーネスの settings.json を直接編集してはいけません
ハーネスのスクラッチディレクトリへの書き込みで確認を求められるハーネスの追加ディレクトリ設定を、他のハーネス設定と同じ場所で宣言します
ハーネス自体が反対の内容を指示している(自動モードの「Bash を優先する」というリマインダー)文言ではなく、モードを変更します。現在のシステムリマインダーに反するルールを書いてはいけません
Plan/Explore 形式のサブエージェントだけが誤動作するそれらの起動時プロンプトを修正します。組み込みサブエージェントはどの階層の AGENTS.md/CLAUDE.md も読み込まないため、すべてのルールをインラインで言い直す必要があります
モデルごとに挙動が異なる(同じルールでもモデルによって発生率が異なる)記述する内容はありません。その旨を references/research.md に記録し、タスクに使用するモデルを選びます

強制よりも指導を優先してください。PreToolUse の誘導フックは使いません。エージェントにも開発者と同じ基準を適用します。何を実行すべきか自分で把握できるべきであり、裏で黙って修正されるべきではありません。却下したフックの設計は references/research.md にあります。

学んだことを記録する

  • 測定する価値のある新しいパターン → scripts/audit.py に、理由を正直に記した PATTERNS の行を追加して一度実行し、件数とその意味を記した日付入りの段落を references/research.md に追加します。コストが明記されていない行からは何も学べないため、追加しないでください。
    • 質問ごとに1行にし、同じコマンドの準拠形と非準拠形をまたぐ1行は作らないでください。 そのような行が示す率は、どちらの質問にも答えていないのに網羅性があるように見えるため、何かを測定しているがゆえに、まさにギャップが見えなくなります。2026-09-02に確認:単一の grep/find 行が grep、rg、find、fd を同じように検出していたため、grep -r より rg を、find より fd を優先するルールは一度も測定されていませんでした。測定すると、2つの部分はそれぞれ90%と47%の準拠率となり、1つの数値では表せない結果でした。ルールが同じコマンドの2つの表記を区別するなら、行も2つ必要です。
    • 件数を信頼する前に、複数行コマンドも含め、手書きのケースで正規表現をテストしてください。 2026-09-02に見つかった2つのバグは、どちらも数値を実態以上に良く見せていました。先読み内の .* は改行で止まり、区切りアンカーには \n が含まれていませんでした。split_chain は常に改行で分割していたにもかかわらず、呼び出しの2行目にあるコマンドがすべて検出されていませんでした。
  • ルールやモードの変更後に新しいベースラインを作成する場合 → references/research.md のベースライン表に日付入りの行を追加します。古い行を上書きしないでください。重要なのは差分です。
  • ハーネスに関する事実(自動モードの動作、モードが自動承認する内容、ルールの優先順位)→ ドキュメントのURLと確認日を添えて、references/research.md の「ハーネスに関する事実」セクションに記録します。これらは Claude Code のバージョン間で変わるため、日付入りの記録が、根拠と単なる伝聞を分けます。
  • 実際にはリポジトリのバグや設計上の判断である、単発の発見 → 該当リポジトリの plans/ に記録します(plan-conveyor スキルを参照)。この文書からリンクしてください。

これらの変更はすべて、このスキル自身のソースに加えてください。~/.agents/skills/ 配下のインストール済みコピーは、次回のインストールで上書きされ、他の場所には反映されません。skill-authoring-taudelta スキルには、編集 → ゲート → コミット → プッシュ → 再インストール → 検証の手順があります。

コメント