AVFoundation (AVPlayer / AVPlayerLayer / AVPlayerItemVideoOutput / AVAsset) の落とし穴・文書化されていない実装挙動・debugging チェックリストを集約した reference skill。Swift / Objective-C で AVPlayer を使った動画再生 / seek / scrub / frame stepping を実装・debug するときに発火。VLCKit ではなく **AVFoundation 系** の問題に特化。
audit
プロジェクト監査。「監査して」「audit」「/audit」で発火。設計/UX/品質/テストなどの観点でコードベース全体を監査し、課題をissuesディレクトリに書き出す。実行ログで重複実行を防止。特定の差分・コミットのレビューには使わない(codex-review / cross-review を使う)。
インストール方法を見る含まれるファイル(1)
- SKILL.md46.1 KB
SKILL.md(原文)
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Audit
プロジェクト監査オーケストレーター。以下の手順に従って監査を実行してください。
監査の姿勢(敵対的に読む)
全監査タイプ共通の姿勢。「問題がないことを確認する」監査ではなく、「壊れている前提で証拠を探す」監査を行ってください。
- コード・コメント・README・過去 issue の主張(「〜は保証されている」「対応済み」「安全」)は証拠ではなく仮説として扱い、実装で裏を取る
- 各発見には 発火条件(どんな入力・状態・順序・環境で顕在化するか)を書く。書けないものは「未確認リスク」と明記する(断定しない)
- テストの存在を安全の根拠にしない。そのテストは実装を追認しているだけでないか(循環テスト・常に真のアサーション・実物とずれたモック)を疑う
- 「見つかりませんでした」で終わらせず、どこをどう攻めて見つからなかったのかを残す(次の監査の起点になる)
- フォーマット / プロトコル実装(コンテナ・codec・wire・時刻計算)の監査では、読み合わせに加えて「仕様から独立に計算したオラクルで実出力を測る」実験を必ず 1 本混ぜる。レビュアーが同じ前提(例: 「media_time は DTS 基準」)を共有していると読み合わせを何回重ねても同じ穴は見えない(SnapTrim #251: 読み合わせ 19 回 → 0 件、オラクル実験 1 回 → HIGH 1 件 + MEDIUM 2 件)。実験の 3 要点: (a) 入出力の対応付けをバイト一致で取る(プレイヤー / ライブラリの解釈に依存しない)、(b) 期待値をコードではなく仕様の条文から計算する、(c) 出力をもう一度入力にする(冪等性・累積誤差)。ffmpeg 等で「elst あり / なし / 負 CTS」のように仕様の分岐ごとに検体を作ると効く
- ただし推測だけで issue を量産しない。発火条件を示せない懸念は issue 化せず、報告に留めるか「未確認」と明記した上で観測ポイントとして書く(
refuse-low-value-coverage.mdと同じで、数のための水増しをしない) - 🚨 件数・全数勘定を書くなら、走査した母集合を機械で数えて併記する。母集合を書けない件数は書かない。「唯一の実害は 1 件」「他に該当なし」は走査範囲の申告であって、体を増やしてもクロスレビューを通しても検証されない(自己申告なので誰も見ない)。実測 2026-09-06: dead-code 監査の「唯一の実害は 1 件」は 7 つある Go module のうち 2 つしか走査していなかった。main の検閲で初めて落ちた。
~/.claude/CLAUDE.md「レビュー方針」の「N 箇所すべてに対応したと書くならその N を機械で数える」の監査版
Step 1: 実行ログの確認
issues/audit-log ファイルを読み取ってください(存在しない場合はスキップ)。
このログには過去の監査実行記録が含まれています。
Step 2: 監査タイプの選択
以下の監査タイプ一覧をユーザーに提示してください。
ログに直近7日以内の実行記録がある場合、該当タイプに (最終: MM/DD) を付記してください。
監査タイプ一覧
| ID | カテゴリ | 名前 | 説明 |
|---|---|---|---|
| design | 設計 | 設計改善 | 今後問題になりうる設計上の課題を探す |
| responsibility | 設計 | 責務集中 | 責務が集中しているクラス/モジュールを探す(行数でなく多角的に判定) |
| duplication | 設計 | コード重複 | コピペされたロジック、抽出すべき類似実装を探す |
| polymorphism | 設計 | ポリモーフィズム置換 | 条件分岐(if/switch)をポリモーフィズムで置き換えられる箇所を探す |
| leaky-abstraction | 設計 | 抽象境界の具象漏れ | 抽象(protocol/基底クラス/レイヤー境界)に具象の知識が漏れている箇所を探す |
| encapsulation | 設計 | 知識の帰属 | データの所有者の外へ振る舞い・不変条件・判定が漏れている箇所を探す(leaky-abstraction とは漏れる向きが逆) |
| ui-components | 設計 | UIコンポーネント共通化 | 共通化できるビュー・UIパターンを探す |
| ux | UX | UX改善 | UX的に劣っている箇所を探す |
| security | 品質 | セキュリティ | ハードコードされた秘密情報、インジェクション脆弱性、安全でない依存関係などOWASP観点の問題を探す |
| resource-leaks | 品質 | リソースリーク | リソースリークの可能性が高いコードを探す |
| broken-code | 品質 | 壊れたコード | コードベースの破損や設計的破綻を探す |
| dead-code | 品質 | デッドコード | 未使用のimport・関数・変数・クラス、到達不能コードを探す |
| error-handling | 品質 | エラーハンドリング | 握りつぶされた例外、不整合なエラー処理パターン、リカバリ不能な障害パスを探す |
| false-green | 品質 | 偽の緑 | 検査・ゲート・ランナーが「判定できなかった」を「合格」として返す箇所を探す |
| performance | 品質 | パフォーマンス | N+1クエリ、不要な計算、メモリ効率の悪い処理を探す |
| concurrency | 品質 | 並行・排他 | check-then-act・排他の持ち主の寿命・終わらない状態・共有名前空間の衝突を探す |
| test-cleanup | テスト | 無意味テスト削除 | 意味のないテストコードを探して削除する |
| test-helpers | テスト | テストヘルパー共通化 | 繰り返し使われているテストヘルパーを共通化する |
| dependency | 管理 | 依存関係 | 未使用・脆弱・重複した依存パッケージを探す |
| ci | 管理 | CI の構成 | 走るべき変更で走らない workflow・テスト、無駄に走る重い workflow、効いていないキャッシュを、run のログと API の実測で探す |
| lint-from-done | 改善 | lint転用調査 | issues/done から lint ルールに転用できるパターンを探す |
| general | 総合 | 総合課題発見 | カテゴリを問わず問題になりうる課題を探す |
選択方法
AskUserQuestion は最大4選択肢のため、カテゴリ別に2段階で選択させてください。
1問目: カテゴリを選択(multiSelect: true)
- 設計 (design, responsibility, duplication, polymorphism, leaky-abstraction, encapsulation, ui-components)
- 品質 (security, resource-leaks, broken-code, dead-code, error-handling, false-green, performance, concurrency)
- テスト (test-cleanup, test-helpers)
- その他 (ux, dependency, ci, lint-from-done, general)
2問目以降: 選択されたカテゴリ内の具体的なタイプを選択(multiSelect: true)。 以下のルールに従ってください:
-
カテゴリ内のタイプが1つしかない場合は自動選択してこの質問をスキップ
-
候補が合計4つ以下の場合はまとめて1問で提示
-
候補が合計5つ以上の場合は4つずつに分割して質問(カテゴリ単位でまとめる。1カテゴリ内に5つ以上ある場合もさらに4つずつに分割)
-
新しい監査タイプを足す前に、
issues/done/の bug issue を数えて軸の分布を見る。推測で軸を立てると、 この repo で再発していない観点を作る (実測 2026-09-14: done 108 件を読むと最多軸が既存タイプの穴だった。retro 373) -
ciは 2026-10-02 に足した (dotfiles で手で回した点検を型にした)。完了 issue 559 件のうち paths filter に触れたものが 13 件・キャッシュが 8 件、 GHA の構成の監査 (issue 073) の前例がある。GitHub Actions 以外の CI の repo では C1〜C4 の確かめ方を読み替える。 まだ実走していない。初回は C1〜C4 の分類が使えるか・偽陽性が出ないかを見る -
concurrencyは 2026-10-07 に足した。done の bug 166 件のうち既存タイプの指針に入らない最多の軸だった (258・366・380・381・544 など。 ただし半数近くが lockman の敵対レビューの連番で、1 module に偏る)。まだ実走していない。初回は K1〜K4 の分類が使えるか・偽陽性が出ないかを見る -
完了済み issue の検出と done への移動は監査タイプに置かない。
/issue-syncを使う (2026-10-07 にissues-doneを削った。2 回の実走で完了判定 0 件、issue-syncと役割が同じ)
Step 3: 実行モードの選択
~/.claude/skills/forge/_common/modes.md を読み取り、「モード一覧」テーブルから利用可能なモード名・説明を取得してください。
このファイルが存在しない場合はプロジェクトローカルの _claude/skills/forge/_common/modes.md を試してください。
両方存在しない場合は forge が未導入のため、自動的に「直接実行」を選択し、以下の選択をスキップしてください。
取得したモード一覧 + 直接実行を以下のように2段階で選択させてください。
1問目: 実行方式を選択
- forge(forge スキル経由で実行)
- 直接実行(forge を使わず直接タスクを実行する)
2問目(forge 選択時のみ): modes.md から読み取ったモード名を最大4つ提示して選択させてください。
Step 4: 監査の実行
選択された監査タイプと実行モードに基づいて監査を実行します。
forge モードが選択された場合
/forge スキルを呼び出して以下のプロンプトを実行してください。
ユーザーが選択したモードを明示的に指定してください。
各監査タイプのプロンプト:
- design:
[モード名]モードで実行して。今後問題になりうる、設計系に改善するべき実装を探してissuesディレクトリに書き出して - responsibility:
[モード名]モードで実行して。責務が集中しているクラス/モジュールを探してissuesディレクトリに書き出して。ただし行数やメソッド数の多さだけで責務集中と判定しないこと。責務の数(変更理由の数)・凝集度の低さ・依存の広がり・状態の絡み・抽象度の不統一など複数観点で裏付けが取れた箇所のみを違反とし、単に大きいだけのものは除外する。各件には分割案と、その分割で ~/.claude/rules/verify-design-intent-before-refactor.md の「リファクタリングの目的は…」節が判断基準に挙げる問いのどれがどう良くなるかを書き、どれも良くならない分割案は報告しないこと。分割案は同節の「分けた後の形」も満たすこと - duplication:
[モード名]モードで実行して。コピペされたロジックや類似実装を探して、共通化すべき箇所をissuesディレクトリに書き出して - polymorphism:
[モード名]モードで実行して。条件分岐(if/else チェーンや switch 文)でタイプや種別に応じた振り分けをしている箇所を探し、ポリモーフィズム(プロトコル/インターフェース/サブクラス)で置き換え可能な候補をissuesディレクトリに書き出して。特に同じ条件が複数箇所に散在しているケースを優先して - ui-components:
[モード名]モードで実行して。UIコンポーネント(モーダル、リスト、ボタン、フォーム等)の中で共通化・抽出できるビューパターンを探してissuesディレクトリに書き出して - leaky-abstraction:
[モード名]モードで実行して。抽象(protocol / 基底クラス / レイヤー境界)に具象の知識が漏れている箇所を探してissuesディレクトリに書き出して。発見は L1 依存方向の漏れ / L2 語彙の漏れ / L3 識別子分岐 / L4 capability の嘘 / L5 暗黙契約 / L6 痩せすぎ抽象 / L7 投機的抽象 のどれかに必ず分類し、分類できない印象論は報告しないこと。lint・型・exhaustive switch が既に機械的に止めている違反は「発見」に数えない。各件に発火条件と「silent に壊れるか compile error で止まるか」を必ず書き、意図的設計の証拠(rules / コメント / 既存 issue / test)を一度探して反証を試みてから報告して - encapsulation:
[モード名]モードで実行して。データの所有者(= その値を保持し不変条件に責任を持つコード単位。第一義は struct / class のメンバーで、クラスの無い言語では状態を持つ module・package 変数。DB やファイルそのものではなく、それを束ねる型 / 関数を所有者とみなす)の外へ、その内部知識に依存する振る舞い・不変条件・判定が漏れている箇所を探してissuesディレクトリに書き出して。発見は E1 帰属誤り / E2 不変条件の外部維持 / E3 生の値の越境 / E4 内部表現の露出 のどれかに必ず分類し、分類できない印象論は報告しないこと。各件に「知識の正しい帰属先」「散在箇所の実数と走査した母集合」「発火条件(新しい呼び出し側が増えたときに何が壊れるか)」「silent に壊れるか compile error で止まるか」を必ず書き、wire / DTO / config 構造体が振る舞いを持たないこと・表示や整形を View 側が持つこと・テスト seam・薄い委譲を 1 段増やすだけの提案は違反に数えないこと - ux:
[モード名]モードで実行して。UX的に劣っている箇所を探してissuesディレクトリに書き出して - security:
[モード名]モードで実行して。ハードコードされた秘密情報、インジェクション脆弱性、安全でない依存関係などセキュリティ上の問題を探してissuesディレクトリに書き出して - resource-leaks:
[モード名]モードで実行して。リソースリークしている可能性の高いコードを探してissuesディレクトリに書き出して - broken-code:
[モード名]モードで実行して。コードベースを見て壊れている箇所がないか、設計的に破綻している箇所がないか調べてissuesディレクトリに書き出して。未使用・到達不能なだけのコードは dead-code の担当なので数えないこと - dead-code:
[モード名]モードで実行して。未使用のimport・関数・変数・クラスや到達不能コードを探してissuesディレクトリに書き出して - error-handling:
[モード名]モードで実行して。握りつぶされた例外、不整合なエラー処理パターン、リカバリ不能な障害パスを探してissuesディレクトリに書き出して - false-green:
[モード名]モードで実行して。検査・ゲート・CI・テストランナー・CLI の合否判定のうち、「判定できなかった」を「合格」として返している箇所を探してissuesディレクトリに書き出して。発見は F1 判定不能を合格に畳む / F2 対象 0 件が合格 / F3 exit code の取り違え / F4 走っていないのに緑 / F5 検査対象の集合が想定より狭い のどれかに必ず分類し、分類できない印象論は報告しないこと。各件に「その検査が名指ししている退行」「その退行を当てたら red になるか (確認したか / 未確認か)」「走査した母集合」を必ず書き、理由コメントのある best-effort・gate ではない警告・「判定不能」を第 3 の結果として出しているものは違反に数えないこと - performance:
[モード名]モードで実行して。N+1クエリ、不要な計算、メモリ効率の悪い処理などパフォーマンス上の問題を探してissuesディレクトリに書き出して - concurrency:
[モード名]モードで実行して。並行・排他・終了の扱いの不具合を探してissuesディレクトリに書き出して。発見は K1 check-then-act / K2 排他の持ち主の寿命 / K3 戻らない・諦めない状態 / K4 共有名前空間の衝突 のどれかに必ず分類し、分類できない印象論は報告しないこと。各件に発火条件 (どの 2 つの実行がどの順で重なると壊れるか) と走査した母集合を必ず書き、子孫プロセスの回収漏れ・解放漏れは resource-leaks の担当なので数えないこと。調べ方と偽陽性の除外は audit skill の直接実行の concurrency の指針に従うこと - test-cleanup:
[モード名]モードで実行して。テストコードのうち、意味のないテストになっているコードを探して削除して。削除したテストは ~/.claude/rules/refuse-low-value-coverage.md の「テストを削除するときは、失ったカバレッジを issue に起こす」節どおり、中身・削除理由・失ったカバレッジを issue に書くこと - test-helpers:
[モード名]モードで実行して。テストコードのうち、繰り返し使っているヘルパーを見つけて共通化して - dependency:
[モード名]モードで実行して。未使用・脆弱・重複した依存パッケージを探してissuesディレクトリに書き出して - ci:
[モード名]モードで実行して。CI の構成を監査して、走るべき変更で走らない workflow・テスト (C1)、無駄に走る重い workflow (C2)、効いていないキャッシュ (C3)、時間を食っている step (C4) をissuesディレクトリに書き出して。設定を読んだだけの推測は報告せず、各件に run の ID とログの行 (または API で取った step の所要) を根拠として付けること。調べ方は audit skill の直接実行の ci の指針に従うこと - lint-from-done:
[モード名]モードで実行して。issues/doneの中身を確認して、lintに転用すると有用そうなことがないかを調べてissuesディレクトリに書き出して - general:
[モード名]モードで実行して。プロジェクトを眺めて、設計とかUXとかカテゴリなんでもいいので、問題になりうる課題を探してissuesディレクトリに書き出して
直接実行 (not forge) が選択された場合
forge を使わず、あなた自身が直接タスクを実行してください。 Explore エージェントでコードベースを調査し、発見事項を issues ディレクトリに書き出してください。 出力フォーマットは issues 配下の既存ファイルに合わせてください(既存ファイルがない場合は、問題の説明・該当箇所(file:symbol)・発火条件・推奨対応の4点を各 issue に含めてください。発火条件が示せないものは「未確認」と明記してください)。
設計系 (design / responsibility / duplication / polymorphism / leaky-abstraction / encapsulation / ui-components) を直接実行でまとめて回すときは、1 体で全タイプを見てよいが、1 つの発見は一番狭く当てはまる型 (L1〜L7 / E1〜E4 など) に 1 回だけ帰属させる。同じ発見を各タイプの結果として数えない (2026-10-07 の zundamon の監査で 1 本の issue に 7 タイプが並んだ)。forge で回すときは各タイプの個別プロンプトを使う (単独で回した responsibility・leaky-abstraction は固有の発見を出している)
各監査タイプの調査指針:
- design: アーキテクチャ全体を俯瞰し、密結合・循環依存・レイヤー違反・拡張困難な箇所を探す
- duplication: コピペされたロジック・同じ判定の別実装を探す。字面ではなく判定の中身で探し (同じ条件を別の書き方で持つものを含む)、散在の件数は走査した母集合と併記する。知識の持ち主が決まる重複は encapsulation へ寄せる
- security: ハードコードされた秘密情報・インジェクション (シェル・正規表現・パス)・外部入力の無害化漏れ・安全でない依存を探す。各件に、攻撃者がその入力を実際に制御できる経路を書く (経路を示せないものは「未確認」)
- dead-code: 未使用の import・関数・変数・型、production から到達しないコードを探す。grep の「参照 0 件」は overload やテストからの参照を区別できないので、言語のツール (compiler / analyzer /
deadcode等) の結果で裏を取る。テストからしか呼ばれないコードも production 到達不能として数える - error-handling: 握りつぶされたエラー・エラーの意味を変えてしまう変換・部分失敗の後に中途状態が残る経路・リカバリ不能な障害パスを探す。合否を返す経路 (検査・gate・CI) は false-green の担当
- performance: N+1・ループ内の不要な再計算・毎フレーム / 毎 tick の全走査・無制限に伸びるデータを探す。効果の大きさは実測か「見積もり」と明記する (
perf-claims-need-measurement.md) - dependency: 未使用・重複・版のずれた (module 間で版が揃っていない) 依存、既知の脆弱性を持つ依存を探す。未使用の判定は manifest と import の突き合わせを機械で行う
- polymorphism: 条件分岐(if/else チェーン・switch/case)でタイプや種別ごとに処理を分けている箇所を探し、ポリモーフィズム(プロトコル準拠・サブクラス・ストラテジーパターン等)で置き換え可能な候補を特定する。特に、同じ条件が複数箇所に散在しているケースを優先する
- ui-components: モーダル・リスト・ボタン・フォーム等のUIパターンを横断的に比較し、共通コンポーネントとして抽出できる類似実装を探す
- leaky-abstraction: 抽象に具象が漏れている箇所を探す。発見は必ず下記 7 型のどれかに分類し、分類できないものは報告しない(型を明示しないと「なんとなく複雑」の印象論に流れる)
- L1 依存方向の漏れ: 抽象側の module/target が具象 SDK・framework・永続化層を import している。import 文を全部列挙して洗う
- L2 語彙の漏れ: protocol の method 名 / 引数名 / 戻り型 / エラー型に特定実装の語彙が出ている(bucket, uploadId, statusCode, Database, SDK の DTO 等)。signature だけを読み「実装を知らない人が意味を取れるか」で判定する
- L3 識別子分岐:
kind == .<具象>/is XxxImpl/as? XxxConcreteで振る舞いを出し分けている。表示の出し分けは対象外(下記) - L4 capability の嘘: capability flag / optional protocol 適合の宣言と実態のズレ。(a) 宣言 true だが実装が満たさない (b) 宣言はあるが caller が誰も見ていない (c) caller が適合チェックせず全実装にその能力を仮定している。compile error にならず silent に壊れるため最優先
- L5 暗黙契約: 一部の実装だけが満たす前提(順序・冪等性・戻り値の identity・エラー種別・null の意味・上限)を契約に書かず caller が当てにしている。「実装 A では成り立つが実装 B では成り立たない」を実際の 2 実装で示す
- L6 痩せすぎ抽象: 抽象が足りず caller 側が具象知識を再実装している(呼び出し側での正規化・retry・pagination・エラー分類)。L2 の逆方向
- L7 投機的抽象: 実装が 1 つしかない / 全実装が同一挙動の抽象。間接層を足しただけで何も分離していない(削除候補)。ただしテスト seam・依存方向を切るための 1 実装 protocol は除外する
- 各件に必須: 該当(
file:symbol。行番号で pin しない)/ 発火条件(新実装を追加したときを含む)/ silent に壊れるか compile error で止まるか / 反証の試み(rules・コメント・既存 issue・test に「意図的」と書かれていないか探した結果)/ 最小の修正方向 - 偽陽性として報告しない: lint・型・exhaustive switch が既に止めている違反(壊せば CI が落ちるものは発見ではない)/ 具象 case ごとの表示名・フォームを
defaultなし switch で列挙するもの(新 case で compile error になり追従が強制されるので正当。違反は==で振る舞いを分ける方だけ)/ 行数やメソッド数の多さ / 薄い委譲 / 理由コメントがあり今も成立している例外 - 0 件なら 0 件と報告し、「攻めたが見つからなかった範囲」を残す(次の監査の起点になる)
- encapsulation: データの所有者の外へ、その内部知識に依存する振る舞い・不変条件・判定が漏れている箇所を探す。ここでの「所有者」は、その値を保持し不変条件に責任を持つコード単位(第一義は struct / class のメンバー。クラスを持たない言語では状態を持つ module・package 変数・shell のグローバル変数がこれにあたる)。DB・ファイル・外部ストレージそのものは所有者ではなく、それを束ねる型 / 関数が所有者(永続化層そのものの設計は design / responsibility の担当なので、本タイプでは扱わない)。leaky-abstraction とは漏れる向きが逆なので別タイプにしている(あちらは境界の内側へ具象が漏れる / こちらは所有者の外へ振る舞いが漏れる。偽陽性として除外する集合も別物)。発見は必ず下記 4 型のどれかに分類し、分類できないものは報告しない
- E1 帰属誤り (feature envy): 呼び出し側が所有者から値を取り出して計算・判定している。判定は「その計算に必要な入力が、ほぼ 1 つの型の内部から来ているか」。所有者に持たせれば呼び出し側は結果を受け取るだけになる
- E2 不変条件の外部維持 (貧血): 1 つの所有者が束ねている複数の値の整合(対で更新する 2 つのフィールド / キャッシュと本体 / 状態遷移の順序 / 片方が他方の部分集合)を、所有者ではなく呼び出し側が守っている。片方だけ更新しても compile は通るので silent に壊れる。最優先(
survey-receiver-guards-before-passing-new-values.md「自分が宣言した不変条件」の監査版。崩せる経路が 2 つ以上あれば違反)- 🚨 所有者へ寄せる修正を書く前に、各呼び出し側がローカルに持っている「例外」を先に列挙する
(「この条件のときだけ引き直さない」「この型のときだけ素通しする」)。例外ごと所有者へ移さないと、
寄せた瞬間に過去のレビューが塞いだ穴を自分で再導入する(実測 2026-09-13: glogx で
disk.Result.Sizeを無条件に引き直す形にしかけ、Items を持たない Result の合計が 0 になる 退行を作る手前だった)。例外が 1 つも無いと言えるときだけ、単純な導出値として寄せてよい - キャッシュ・再利用値も対の 1 つとして見る: (a) キーが中身を一意に決めるか (b) 捨てる・作り直す経路が所有者にあるか (c) 失敗・部分的な結果が本体を上書きしないか (114・172・173 がこの形)
- 🚨 所有者へ寄せる修正を書く前に、各呼び出し側がローカルに持っている「例外」を先に列挙する
(「この条件のときだけ引き直さない」「この型のときだけ素通しする」)。例外ごと所有者へ移さないと、
寄せた瞬間に過去のレビューが塞いだ穴を自分で再導入する(実測 2026-09-13: glogx で
- E3 生の値の越境: 意味を持つ値(ID・パス・期間・状態語・単位付きの数)が生の string / int のまま境界を越え、検証・正規化・書式化が各呼び出し側に散っている。同じ生の型どうしは取り違えても compile error にならない
- E4 内部表現の露出: 内部の可変コレクション・内部構造をそのまま返す / setter で不変条件を迂回できる。呼び出し側が所有者を通さずに状態を変えられる
- 各件に必須: 該当(
file:symbol。行番号で pin しない)/ 知識の正しい帰属先(どの型・どの関数へ寄せるか)/ 散在の実数と走査した母集合(この型は散在の件数が発見の中身なので、「同じ判定が 3 箇所」は母集合を機械で数えて併記する。母集合を書けないなら件数を書かない)/ 発火条件(新しい呼び出し側が増えたときに何が壊れるか)/ silent に壊れるか compile error で止まるか / 反証の試み(rules・コメント・既存 issue・test に「意図的」と書かれていないか) - 他タイプと重なったときの寄せ先: (a) 知識の持ち主が protocol / 抽象境界なら leaky-abstraction の L6、具体的な所有者(データを持つ struct / class / module)なら本タイプ (b) duplication と同じ箇所を拾ったら本タイプへ寄せる(重複は症状・帰属誤りが原因で、帰属先が決まれば重複も消える) (c) responsibility と同じ symbol に出るのは矛盾ではない(責務が多く、かつそのうち 1 つが外へ漏れている)
- 偽陽性として報告しない: wire / DTO / config 構造体が振る舞いを持たないこと(正当。外部表現の写像なので振る舞いを足す方が悪化する)/ 表示・整形を View 側が持つこと / テスト用の seam / 所有者を持たない純関数のパイプライン(shell の関数群・
func(in) outの連なり)/ 薄い委譲を 1 段増やすだけの提案(verify-design-intent-before-refactor.md: 複雑性が実際に下がらない分割はリファクタではない) - 0 件なら 0 件と報告し、「攻めたが見つからなかった範囲」を残す
- false-green: 検査・ゲート・CI・テストランナー・CLI の合否判定のうち、「判定できなかった」を「合格」として返している箇所を探す。発見は必ず下記 5 型のどれかに分類し、分類できないものは報告しない。判定基準の正本は
verify-execution-not-just-exit-code.md(ここに再掲しない)- F1 判定不能を合格に畳む:
2>/dev/null/|| true/ エラーを捨てて 0 を返す。「検査できなかった」と「違反なし」が同じ出力になる形。production の検査は判定不能 → 拒否 (fail-closed) が安全側、テストの判定は専用の第 3 の結果が安全側 (allow / deny のどちらかに丸めない) - F2 対象 0 件が合格: 抽出・走査が空を返したときに合格になる (grep 無マッチ / glob 0 件 / 収集 0 件 / 早期 return)。抽出が壊れると「違反 0 件」= 緑になるので、既知の入力で既知の答えを出す canary が本走査と同じ関数を通っているかを見る
- F3 exit code の取り違え: パイプ終端の
$?(set -o pipefail無し) / background の起動 rc を実行結果として読む /cmd | tailで結論だけ残して理由を捨てる / 対話プロンプトが非対話で「何もせず rc=0」 - F4 走っていないのに緑: skip と pass が区別できない / 検査が集約経路 (
make test等) に配線されていない / 環境変数・TTY・path filter のゲートで CI では起動しない (path filter の漏れと、skip したテストがどの workflow でも走らない形の網羅は ci の C1 が担当)。スイート全体が緑なのは「走った」の証拠にならない - F5 検査対象の集合が想定より狭い: 手書きの列挙・正規表現・母集合が実物より狭く、退行が構造的に不可視 (定義の書き方を取りこぼす正規表現 / fixture が退行から見えない場所にある / 1 単位しか見ていない)。実装は正しいが見ている集合が違う形
- 各件に必須: 該当 (
file:symbol。行番号で pin しない) / その検査が名指ししている退行 (何を守るはずか) / その退行を当てたら red になるか (実際に変異を当てたなら結果を、当てていないなら「未確認」と明記) / 走査した母集合 / 最小の修正方向 - 他タイプと重なったときの寄せ先: (a) テストコードの中の常に真のアサーション・循環テスト・実物とずれたモックは test-cleanup (b) production のエラー処理そのもの (握りつぶされた例外・リカバリ不能な障害パス) は error-handling (c) 本タイプが見るのは「合否を返す経路」だけ — 検査・gate・CI・ランナー・
--check系 CLI - 偽陽性として報告しない: 理由コメントのある best-effort (失敗してよいと明示されている後始末・通知) / gate ではない警告表示 / 「判定不能」を専用の第 3 の結果として既に出しているもの (正しい形) / 変異を当てて red になることを確認済みと記録がある検査
- 0 件なら 0 件と報告し、「攻めたが見つからなかった範囲」を残す
- F1 判定不能を合格に畳む:
- concurrency: 並行・排他・終了の扱いの不具合を探す。発見は必ず下記 4 型のどれかに分類し、分類できないものは報告しない
- K1 check-then-act: 状態を見てから動くまでの間に別の実行が状態を変えられる (lock の外で見て中で動く / lock を取り直した後に見直さない / 存在を確かめてから消す・作る)。探し方:
Stat・Lstat・[ -e ]・kill -0の直後の破壊的操作、lock の Release〜Acquire をまたいで使う値 (366・380・544) - K2 排他の持ち主の寿命: lock・排他の持ち主が守る資源より短命 / 子へ継承されて持ち主が曖昧になる (lock の fd が子に渡る、作り直される object ごとの lock)。探し方: lock を作る場所と守る資源の寿命を並べる (356・597・258)
- K3 戻らない・諦めない: 一度立てたら戻らない latch、終端の無い待ち・再試行、止まった相手を待ち続ける状態 (381・223・541・384)。探し方: 状態の遷移を列挙し、各状態から抜ける経路 (成功・失敗・timeout・相手の消失) があるかを見る
- K4 共有名前空間の衝突: 並行する実行が同じ名前を取る (固定名の一時ファイル・
$$だけの名前・番号の採番・worktree 名) (219・300・465) - 各件に必須: 該当 (
file:symbol) / 発火条件 (どの 2 つの実行がどの順で重なると壊れるか) / 走査した母集合 / 最小の修正方向。go test -raceのある言語では、それで検出されるか (検出されないなら理由) も書く - 他タイプと重なったときの寄せ先: 子孫プロセスの回収漏れ・fd・一時ファイルの解放漏れは resource-leaks / 所有者の外で対の値を更新しているだけ (並行は無関係) なら encapsulation の E2
- 偽陽性として報告しない: テスト専用の経路で、
-raceが通る (214 はテスト側の競合だった) / 単一 writer と文書や理由コメントで明示された経路 / 理由コメント付きの best-effort な kill・後始末 - 0 件なら 0 件と報告し、「攻めたが見つからなかった範囲」を残す
- K1 check-then-act: 状態を見てから動くまでの間に別の実行が状態を変えられる (lock の外で見て中で動く / lock を取り直した後に見直さない / 存在を確かめてから消す・作る)。探し方:
- ci: CI の構成を、設定の読み取りではなく実行の記録で監査する (GitHub Actions なら
gh run list/gh run view --log/gh api .../runs/<id>/jobs)。発見は下の C1〜C4 のどれかに分類し、分類できないものは報告しない- C1 走るべきなのに走らない: (a) paths filter の漏れ — workflow が使う共有の action (
.github/actions/**)・取り込む依存先・テストが読む module の外のファイルが paths に入っているか (テストが読むファイルは、repo root を求めて読むテストを grep して集める。字面の相対パスは fixture の文字列が大半で当てにならない) (b) skip の全数 — 直近の成功 run のログから丸ごと skip したテストを全部集め、別のどこかの workflow で走っているかを 1 本ずつ突き合わせる。どこでも走らないものが発見。その環境でしか成り立たない検査 (セットアップ済みのマシン前提など) は除く - C2 無駄に走る: paths filter の無い重い workflow について、
git logで直近の commit を「触ったファイルの種類」(issues だけ・文書だけ・コード) で数え、多数を占める種類の push でその workflow が要るかを確かめる。要らないと言うには、その workflow の入力が実 repo のそのファイルを読まないことを確かめる (bench の fixture が一時ディレクトリか等)。go:embed などでバイナリに埋め込まれる文書は「文書だけ」に数えない - C3 効いていないキャッシュ:
Cache hit/Cache restoredが出ている run で、その後にダウンロードやビルドが毎回出ていないかをログで見る (鍵が一致すると保存し直さない cache は、最初に保存した job の中身を使い回す。同じ鍵を複数の job が共有すると、片方に要る物が入らない)。ツールを毎回ソースからビルドしていないか (置き場が run をまたいで残るか) - C4 時間を食う step: API で step ごとの所要を取り、長い step から並べる。直す価値を言うときは、手元で同じ処理を空のキャッシュから測った値か、CI のログの時刻を添える (見積もりなら見積もりと書く)
- 各件に必須: 該当 (workflow のファイル名 + job / step 名) / 根拠 (run の ID とログの行、または API の所要) / 直し方 / 直したら何が変わるか (実測か見積もりかを明記)
- 偽陽性として報告しない: 理由のコメントがある「わざと paths に入れていない」設定 / 環境の前提で skip が正しい検査 / 打ち切り (
cancel-in-progress) で cancelled になった run
- C1 走るべきなのに走らない: (a) paths filter の漏れ — workflow が使う共有の action (
- ux: ユーザー操作フロー・エラーメッセージ・レスポンス速度・一貫性の観点で劣っている箇所を探す
- 端末 UI を持つ repo では表示幅も見る (無い repo では飛ばす): 幅を測る関数の出典が 1 本か / 幅 1..N を全部掃引しても溢れないか / 固定部分 (枠・ヒント) の幅を予算から引いているか / 書記素クラスタを割っていないか (027・053・238・589 がこの形)。全角半角の混在は
no-mixed-width-columns-in-terminal-ui.md
- 端末 UI を持つ repo では表示幅も見る (無い repo では飛ばす): 幅を測る関数の出典が 1 本か / 幅 1..N を全部掃引しても溢れないか / 固定部分 (枠・ヒント) の幅を予算から引いているか / 書記素クラスタを割っていないか (027・053・238・589 がこの形)。全角半角の混在は
- resource-leaks: ファイルハンドル・DB接続・イベントリスナー・タイマーなど、解放漏れの可能性がある箇所を探す。プロセスの寿命もここで見る: 孫・detached な子が親の終了後に残らないか (
Startの後にWaitが無い / プロセスグループ・Setpgidの扱い / trap が中断で走らない)、fd が子へ継承されていないか (105・301・477・649 がこの形) - responsibility: 行数・メソッド数の多さ「だけ」で判断しない。責務の数(変更理由の数)・凝集度の低さ・依存の広がり・状態の絡み・抽象度の不統一など複数観点でチェックし、複数の観点で責務集中が裏付けられる箇所のみを違反とする(単に大きいだけのクラスは違反ではない。
verify-design-intent-before-refactor.mdと同じ思想)。各件には分割案と、それで同 rule の「リファクタリングの目的は…」節が判断基準に挙げる問いのどれがどう良くなるかを書く。どれも良くならない分割案は報告しない。分割案は同節の「分けた後の形」も満たすこと - lint-from-done: issues/done のパターンを分析し、lint ルールとして自動検出できそうな再発防止策を探す
- broken-code: 型不整合・壊れたインポート・呼び出し側と受け側で契約 (引数・返り値・ファイル形式) が食い違っている箇所など、実行時エラーや誤動作になりうる箇所を探す。未使用・到達不能なだけのコード (動いても害が無いもの) は dead-code の担当。環境への仮定も見る: 固定の prefix (
/opt/homebrew等) /command -vが他人の shim を返す / cwd 相対のパス / gitignore 配下まで歩く列挙 (176・263・616・639 がこの形) - test-cleanup: 常に pass するアサーション・重複テスト・実装と乖離したモックなど、価値のないテストを探す。削除するなら
refuse-low-value-coverage.mdの「テストを削除するときは、失ったカバレッジを issue に起こす」節に従う - test-helpers: 複数テストファイルで繰り返されているセットアップやユーティリティを特定し、共通ヘルパーへの抽出を提案する
- general: 上記すべての観点を広く浅くカバーし、最も影響が大きい課題を優先して報告する
Step 5: commit と実行ログの記録
commit
監査完了後、発見事項を issues ディレクトリに書き出した場合は git commit してください。
実行ログの記録
issues/audit-log に以下の形式で追記してください。
ファイルが存在しない場合は新規作成してください。
YYYY-MM-DD HH:MM <audit-type-id> <mode> <output-files>
フィールドはタブ区切りです。<mode> は forge 経由なら forge-<モード名>(modes.md のモード名: Standard / Minimum+ / Maximum / Minimum / Ultra)、直接実行なら direct。例:
2026-02-15 14:30 design forge-Standard issues/design-improvements.md
2026-02-15 14:45 broken-code direct issues/broken-code-findings.md
2026-02-15 15:00 general forge-Minimum+ issues/general-issues.md
🚨 複数の監査タイプが選択された場合は、各タイプを順番に実行し、それぞれログを記録してください。
並行起動しないこと。 監査は issue ファイルを書くので、並行させると複数の書き込み体が
同じ working tree を共有することになります(parallel-write-agents-need-worktree-isolation.md 違反)。
実測 2026-09-06: この指示に反して 3 体を並行起動し、全員に同じ worktree を渡したセッションが あります。検出したのは起動側ではなくサブエージェント側(「他のプロセスがファイルを書き換えている」 と報告してきた)でした。どうしても並行させたいなら、起動前に体ごとの worktree を作って 作業根として渡し、終わったら消すこと:
root="$(git rev-parse --show-toplevel)"
for i in 1 2 3; do git worktree add --detach "$root/../wt-audit-$i" HEAD; done
# 各体へ「作業場所は <path>」と明示し、完了後に git worktree remove --force
判断基準: 1 体なら worktree を作らない(分離コストは 2 体目から)。read-only の 調査・レビュー体は分離不要。分けるのは書き込む体だけです。
🚨 監査タイプの数だけ体を並べると、file 競合の前に「予算」で死にます。
上の「順番に実行」は書き込み競合を避けるためのものですが、read-only の調査体でも同じで、
1 波の体数と 1 セッションで回す監査タイプ数の両方に上限を置いてください。
実測 2026-08-26: 18 タイプ × 9 体を並行起動して Claude の session limit で 8 体が途中死、
codex へ 4 本再投入したら codex の usage limit で 4 本とも最終回答前に停止。
30 万トークン以上を使って、結論に届いたのは 1 体・発見 1 件でした。
1 波は 2〜3 体までにし、その波が完走してから次を投げる。枠の残量が少ないときは
体数をさらに絞る(subagent-model-tiering.md の
「枠の残量が少ないときは並列数を絞る」)。
実行中にエラーが発生した場合は、そのタイプのログに error と記録し、次のタイプに進んでください。
すべてのタイプの実行が完了(またはエラー)した後、エラーがあった場合はユーザーに報告してください。
audit-log 自体も commit に含めてください。
注意事項
- issues ディレクトリが存在しない場合は作成してください
- issue ファイルの命名規則・採番は、注入される issue 運用規約 (正本
~/dotfiles/_claude/issue-rules.md) と repo 固有のissues/README.mdに従うこと。作成前に両方を読み、ファイル名の形式(番号プレフィックス等)と次の issue 番号を確認してください - どちらも存在しない場合は
issues/<audit-type-id>-<簡潔な説明>.mdをフォールバックとしてください - 既存の issue ファイルと同じカテゴリの場合、既存ファイルへの追記も検討してください
レビュー
まだレビューはありません。使ってみた感想をお寄せください。
同じリポジトリのスキル
概要と使いどころ
このセッションで行った変更をコミットする。「コミットして」「commit」「/c」で発火。push はしない/クレデンシャルは混入させない。
ディレクトリ・レイヤーごとに置いた CLAUDE.md と README.md が実体 (コード・コマンド・構成) とずれていないかを点検し、裏の取れた乖離だけを直す。引数で対象のディレクトリを任意に指定できる (省略時は repo 全体)。「CLAUDE.md を refresh して」「README が古くないか見て」「claude-md-refresh」「/claude-md-refresh」で発火。issues/ の更新漏れは issue-writeback / issue-sync の担当で、この skill は扱わない。
Codex が設計・実装を担い、Claude が要件確定・成果物の検証・反復・commit/push を管理する。「codex に書かせて」「codex メインで実装」「codex-drive」で発火。大きめの機能・移植・プロトコル実装向け。余剰トークンを厚く使う運用も選べる。
タスク着手時に codex にリードしてもらうワークフロー。codex に設計/方針を主導(リード)させ、その方針に沿って Claude が実装し、実装後は codex で設計適合・実装正当性・敵対的(red team)の 3 観点でレビューする。余っている codex トークンを積極的に消費したい時に使う。「codexにリードしてもらって」「設計から codex に任せて」「タスクを codex 主導で」「codex-lead」「/codex-lead」で発火。
codex exec review を基本に、必要なら codex exec を使ってコード変更のレビューを依頼し、指摘事項を報告する。通常 / 厳しめ (--strict) / 敵対的 (--adversarial、実装を壊しにいく red team) の 3 モードを持つ。「codexでレビューして」「codex-review」「/codex-review」「敵対的にレビューして」で発火。Codex 単体での単独レビュー用途。複数エージェント並行レビューは cross-review、差分ではなくコードベース全体の監査は audit を使う。