テストが全部緑でも検出器は死んでいる — 変異テストでテストの検出力を機械的に検定する
hook/gate などの検出器を無害化した変異体に同じテストを流し、通ってしまうテスト(=検出力なし)を摘発する。実測で34本中2本が該当。node --test の子プロセスが NODE_TEST_CONTEXT 継承で失敗を exit 0 にする罠と、sha256 台帳で未検定を止める hook まで。
約3.9万トークンの節約 (API料金換算で約59円分)。 要件定義・技術調査・試行錯誤ぶんのトークンがまるごと不要になります。※ 出品者申告とレビューに基づく推定値。モデル・タスク内容により変動します。
この巻物について
「テストが全部緑でも検出器は死んでいる — 変異テストでテストの検出力を機械的に検定する」は、AIのしつけカテゴリのAI指示書(MDファイル)です。hook/gate などの検出器を無害化した変異体に同じテストを流し、通ってしまうテスト(=検出力なし)を摘発する。実測で34本中2本が該当。node --test の子プロセスが NODE_TEST_CONTEXT 継承で失敗を exit 0 にする罠と、sha256 台帳で未検定を止める hook まで。この巻物をAIに読み込ませると、ゼロから設計・調査する場合に比べて 約3.9万トークン(API料金換算で約59円)・87%のトークンを節約できます。
- カテゴリ
- AIのしつけ
- 対応AI
- claude-code、cursor、codex-cli
- ライセンス
- 商用利用可 (再販不可)
- 価格
- 無料
- ゼロから開発時
- 約4.5万トークン
- この巻物使用時
- 約6,000トークン
- 節約量
- 約3.9万トークン (約59円)
- 更新日
- 2026-09-25
使い方 (AIに渡す3つの方法)
いちばん簡単なのはワンライナー。Claude Code のターミナルに貼るだけです。
claude "https://makimono-md.vercel.app/api/v1/files/md-7061ebbb/raw を読み込んで、この指示書どおりに実装して"
中身
テストが全部緑でも検出器は死んでいる — 変異テストでテストの検出力を機械的に検定する
AI エージェントにルールを守らせるため、hook / gate / lint などの「検出器」を何十本も書いている プロジェクト向け。検出器のテストが全部 pass していることは、その検出器が動いている証拠にならない。 テストが「壊れた検出器」と「動く検出器」を区別できるかどうかは、別に検定しないと分からない。
実測: 検出器 34 本を検定したところ、2 本のテストは検出器を無害化しても全部 pass した (片方は判定を 11 箇所ひっくり返しても誰も気付かなかった)。さらに 11 本は検定手段が無く「緑だが未検証」。 テストに検出力があると確認できたのは 21 本(62%)だけだった。
何を作るか
検出器のソースを「常に無害な判定を返す」よう書き換えた変異体を作り、同じテストスイートを流す。
- テストが落ちる →
killed(検出力あり) - テストが通る →
survived(そのテストは動く検出器と死んだ検出器を区別できない) - 変異させられない →
unmutatable(合格にしない。検定不能を合格に化けさせないため終了コードを分ける)
実装(Node.js / 依存パッケージなし)
1. 変異ルール
検出器の「判定の語彙」は驚くほど少ない。次の 4 つを潰せば実務上は足りる。
| ルール | 置換 |
|---|---|
| 判定文字列 | クォート内の完全一致 'block' 'warn' → 'pass'、'deny' → 'allow'。識別子(blocked など)は置換しない |
| 終了コード | process.exit(<非ゼロ整数>) → process.exit(0)。変数引数は対象外 |
| 真偽値の判定 | ok: false → true、blocked: true → false |
| 蓄積 | findings.push( → false && findings.push((行を消すと構文が壊れるので短絡で無効化する) |
重要: 変異体は構文として妥当なままにすること。クラッシュするとテストが落ち、
「検出力がある」と誤判定される(クラッシュを検出したのであって判定を検出したのではない)。
置換が 0 件なら unmutatable を返す。0 件を「合格」にしてはいけない。
2. 実行
- リポジトリ root ごと一時ディレクトリへコピーする(
fs.cpSync/node_modulesと.gitは除外) - コピー先でテストを 1 回流す(baseline)。落ちたら検定不能として打ち切る
- コピー先の検出器を変異体で上書きし、もう 1 回流す
- 落ちれば
killed/ 通ればsurvived
⚠️ ここで 1 回失敗する: コピー範囲を「検出器の入っているディレクトリだけ」にすると、
リポジトリ root 直下のファイルを読む検出器が起動に失敗し、baseline_failing が大量に出る。
これは偽陽性で、潰さないと本物の survived がその中に埋もれる(実際に 1 件埋もれていた)。
3. 🔴 最大の罠: テストの中から子プロセスで node --test を起動すると失敗が exit 0 になる
親のテストランナーが立てる環境変数 NODE_TEST_CONTEXT を子が継承するため。実測:
| 起動方法 | わざと落とすテストの exit code |
|---|---|
node --test fail.test.mjs | 1 |
NODE_TEST_CONTEXT=child-v8 を継承 | 0 |
失敗信号が消えるので変異体が常に生き残り、全検出器が「対照群なし」に化ける。
しかも survived を期待する側のテストは空振りで通るため、スイートは緑のまま気付けない。
spawn する側で必ず外すこと:
export function childEnv(env = process.env) {
const copy = { ...env };
delete copy.NODE_TEST_CONTEXT;
return copy;
}
spawnSync(process.execPath, ['--test', testPath], { env: childEnv(), /* ... */ });
一般化: 子プロセスの exit code で判定する計測器は、親のランナーが注入する環境変数を疑う。
4. このツール自身の対照群(これが無いと意味がない)
テストに次の 2 本を必ず入れる。片方だけでは自分自身が空振りする。
- 合成の検出器+両側を assert するテスト →
killedが返ること - 同じ検出器+正常側しか assert しないテスト →
survivedが返ること
実際にこの 1 本目が落ちたことで、上の NODE_TEST_CONTEXT の罠が見つかった。
hook として常時強制する
作っただけでは使われない。検定結果を台帳に追記し、未検定なら止める。
- 検定のたびに
{ name, sha256, verdict, at }を JSONL へ追記する。sha256は検定した時点の 検出器ソースのハッシュ - セッション終了時の hook で、作業ツリーで変更された検出器を列挙し、
現在のソースの sha256 と一致する
killedの記録が無ければ block する - ハッシュ一致を条件にするのが肝。名前だけで照合すると「昔検定したから」で素通りする (検定後にコードを 1 行足したら再び block されるのが正しい)
block のメッセージには実行すべきコマンドをそのまま書く。「検定してください」だけでは動けない。
測定限界(報告に必ず添える)
変異は判定語彙の置換に限られ、ロジックの分岐は変異させない。よって killed は
「この変異なら検出できる」であって、テストが十分である証明ではない。
unmutatable は「検定できていない」であり、緑とは違う。この 2 つを混ぜて
「全部 OK」と報告すると、この仕組みを作った意味が消える。
よくある質問
+「テストが全部緑でも検出器は死んでいる — 変異テストでテストの検出力を機械的に検定する」とは何ですか?
hook/gate などの検出器を無害化した変異体に同じテストを流し、通ってしまうテスト(=検出力なし)を摘発する。実測で34本中2本が該当。node --test の子プロセスが NODE_TEST_CONTEXT 継承で失敗を exit 0 にする罠と、sha256 台帳で未検定を止める hook まで。
+どれくらいトークン(費用)を節約できますか?
ゼロから開発すると約4.5万トークンかかりますが、この巻物を使えば約6,000トークンで済みます。差し引き約3.9万トークン(API料金換算で約59円)・87%の節約です。
+どうやって使いますか?
無料です。MDファイルを Claude Code などのAIに読み込ませるだけ。ワンライナーをターミナルに貼れば実装が始まります。要件定義や技術調査を省いて実装だけにトークンを使えます。
+どのAIツールに対応していますか?
claude-code、cursor、codex-cli に対応しています。
+商用利用できますか?
ライセンスは「商用利用可 (再販不可)」です。
🤝 自分でAIを動かすのは、まだ不安…という方へ
この巻物の内容を、AIを使うプロに丸ごと任せることもできます。姉妹サービスAI代行堂なら「LINEで頼むだけで、仕事が完成」。
関連する巻物
AI運用ルールを機械的に守らせる hook 設計 — ルール文が守られない本当の理由
チームでAIエージェントを使うと運用ルールが必ず守られなくなる。真因は「読んでいない」ではなく hook がそのマシンで登録されていない/委譲先が沈黙して壊れていること。禁止=実行前拒否・誘導=依頼時の具体コマンド注入・担保=セッション開始時の自己修復の3層、明示例外の短命トークン、warn→blockの段階昇格、BOM/サンドボックス/timeout など失敗が沈黙する罠と、環境依存で落ちないテストの作り方までを実測ベースでまとめた導入手順。
AIの応答を止める番人hookを1ランナーに統合し、書き直しを最大1回にする(誤爆率をfixtureで先に測る)
Stop hook を9本積んだら Stop の65%が書き直し・最多ゲートの91%が誤爆だった。誤爆測定→否定文除外→1プロセス合流→再試行上限統一→全PC移行→KPIで効果確認までの手順。
定額プランの最上位モデルを枯渇させずに使う「二段レーン」設計
5時間/週の枠を桁違いに食う最上位モデルを、長時間タスクと失敗時の昇格だけに自動で当て、上限に当たったら既定モデルへ退避する委譲レーンの作り方。判定は純関数・検証まで含む。
この巻物、誰かのトークンも救えます
𝕏 で節約レシートをシェア