---
title: "AIの意見を聞かない技術 第5回：自動テストを書かない技術"
author: garplab
publisher: TypingTube
license: CC BY 4.0
license_url: https://creativecommons.org/licenses/by/4.0/
license_scope: 「CC BY 4.0」の印から始まる節（仕組み・検証手順・コード）。印の無い本文は著作権を留保
canonical: https://typing-tube.net/articles/kikanai-05-machine-check
series: "AIの意見を聞かない技術"
language: ja
---


> この記事は、連載「AIの意見を聞かない技術」の第 5 回です。各回はファイルやスクリプトを一つ置けば完結します。連載の全体像と各回の一覧は[序論](https://typing-tube.net/articles/kikanai-intro)にあります。

今回は、自動テストや hook を書いていない禁止事項の話です。禁止事項というのは、開発のときに許さないと決めたルールの一覧です。私の一覧は 17 件あります。そのうち、自動テストが見ていると言い切れるのは 4 件で、**残りの 13 件は、自動テストに載せ切れていません。**

前作「読まない技術」の[第 6 回](https://typing-tube.net/articles/569d598941c00f)で、**ルールを、破られたら落ちる自動テストに置き換える**と書きました。ただし、置き換えられるのは機械が真偽を決められるルールだけです。今回は、置き換えられなかったほうの禁止を、どう扱っているかの話です。

まず一つだけ、確かめてみてください。あなたの禁止事項を 1 つ選んで、**それが今この瞬間に破られていたら、何が起きるか**を答えます。テストが落ちるでしょうか。CI が止まるでしょうか。誰かが気づくでしょうか。どれでもなければ、その禁止は書いてあるだけです。

## 書いてあるだけの禁止は、破られても分かりません

私の手元の本番プロジェクト——[typingtube](https://typingtube.net) という、YouTube の音楽動画でタイピング練習ができる Web サービスです——には、こういう行動ルールがありました。「fallback で済ませず、全 locale に翻訳を追加する」。十数言語で提供しているサービスなので、当然の方針です。文面に曖昧さはなく、AI にもずっと渡していました。

自動テストが無かったので、AI に破られていても誰も気づきませんでした。私が数えてみたら、**5,525 件の翻訳が欠けていました**（2026-08-31 実測）。755 ある翻訳ファイルのうち 241 に欠落があり、ファイルがまるごと無いものも 2 つ。そのうち 31 件は、翻訳が無いとキーの名前がそのまま画面に出る場所でした。

数え直して一番こたえたのは、内訳のほうです。**日本語と英語だけ揃っている箇所が多かった**。文言を追加するたびに 2 言語で止めた形が、何度も繰り返されていたということです。

ルールが AI に読まれていなかったわけではありません。読まれた上で、AI が翻訳を足すその瞬間に一番強かったのが「まず日本語と英語を通す」だっただけです。書いてあるルールは、決める瞬間に、その場の他の全部と強さを競っています。一度きりの不注意なら気づけますが、**毎回わずかに負ける**ものは、誰にも気づかれずに積み上がります。

この 1 件は、私が pre-commit hook に移しました。翻訳のキーが言語ごとに揃っているかどうかは、機械が数えられるからです。

## 全部を自動テストにしようとして、できませんでした

それなら、全部を自動テストにすればいい。私もそう思って、17 件の禁止事項を一つずつ見ていきました。**自動テストにできたのは 4 件でした。**

残りに並んでいるのは、サービスの収益構造の方針、キャラクターの経済バランス、レベルの推薦をしないという判断、SEO のテキストを変えるときに根拠を要求すること。どれも**機械が真偽を決められません**。「このコピーは強い訴求か」は行単位の検索で拾えますが、「この経済バランスは意図どおりか」は拾えない。

つまり、半分以上の禁止は、自動テストにできないまま残ります。そして自動テストの無い禁止は、上で見たとおり、破られても分かりません。**書いてあるだけの禁止が、半分以上残る計算です。**

理解したことは一文にできます。

> **自動テストの無い禁止は、正しく書いてあっても積み上がる。だが半分以上は自動テストにできない。だから、自動テストにしないと決めたことを、禁止の隣に書いておく。**

## 仕組み: 禁止事項の一覧に「機械検証」の見出しを足す

増やすのは見出し 1 つです。禁止事項を書いてある文書——私の場合は「やらないことリスト」1 枚——のどの項目にも、決まった見出しを並べます。

```markdown
### NG3 ユーザー投稿物に名前フィールドを持たせない

**結論**: キャラクター・ドット絵・背景などの投稿物は、名前の列を持たない。
識別はビジュアルと設定で行う。

**理由**: （なぜ禁止なのか。ここは第 2 回の主題）

**適用範囲**: 対象 4 モデルへの `name` / `title` / `nickname` 等の列追加を禁止

**関連 memory**: `feedback_no_naming_for_ugc.md`

**機械検証**: あり。`a1_name_field_absence_test.rb` が、その 4 モデルに
該当する列が無いことをスキーマの側から検査する
```

最後の 1 行です。自動テストがあるものには、どの自動テストかを書きます。自動テストの無いものには、こう書きます。

```markdown
**機械検証**: なし（推薦 UI の機械検知は実装ドメイン横断のためレビューで担保）
**機械検証**: なし（プロセスルール、レビューで担保）
**機械検証**: なし（条文の書き方なので、追加・改訂時のレビューで見る）
```

**何も書かないことと、「なし」と書くことは違います。** 何も書いていない項目は、「まだ検討していない」と「検討して、機械には無理だと決めた」を区別できません。区別が付かないと、その項目は永久に宙に浮きます——誰かが思い出したときだけ「そういえば自動テストを書けるのでは」と再検討され、たいてい誰も思い出しません。「なし」と理由を書いた瞬間に、それは**決着済みの項目**になります。決着済みの項目は、人が見ると決めた項目です。書いてあるだけの禁止ではなくなります。

私の一覧は 17 項目で、内訳はこうです。**「あり」が 4 件、「なし」が 10 件。** ただし「なし」の 1 件には、テストの名前が書いてあります——[第 3 回](https://typing-tube.net/articles/kikanai-03-scope)で扱った 3 軸の禁止です。境界を見る自動テストはありますが、その禁止の全部を機械が持てているわけではないので、「なし」の側に置いています。2 件は、テストが部分的に見ているだけで、あり／なしを言い切れていません。そして残る 1 件は、見出しごとありません。最後の 1 件は、この回を書きながら数えて初めて気づきました。書く場所を決めると、まだ書けていない所まで見えるようになります。

半分以上が「なし」になるのは、サボった結果ではありません。機械に持てるものを機械に持たせた結果、残ったのが判断だけになった——その状態を、見出しが見えるようにしているだけです。

「なし」と書くときに、もう一つ決めることがあります。**その禁止を残すかどうか**です。基準は「AI がまだそのガードを必要としているか」ではなく、**その失敗が今も再現するか**。前者で考えると、何も消せません——書いてあること自体は害ではないので、全部が残ります。

## 読み直さなくなったもの

禁止事項の一覧そのものです。「今どこまで機械が持っていて、どこから人間が見ているのか」を知るために全文を読み直す作業が、その見出しを見るだけになりました。項目が増えても、読むのはその 1 行だけです。

## 注意: 自動テストは「落ちない」方向に壊れる

両側に壊れ方があります。

**「あり」は、空回りする方向に壊れます。** 走査対象をパスの指定でまとめて集める自動テストは、そのパスを打ち間違えると 0 件を走査して、**永遠に通ったまま**になります。「走査対象が N 件以上あった」を必ず併置してください（詳しくは前作の[第 6 回](https://typing-tube.net/articles/569d598941c00f)に書きました）。

**「なし」は、逃げ道になる方向に壊れます。** 書くのが面倒な自動テストを「なし（レビューで担保）」で流せてしまう。線引きは単純で、**機械が真偽を決められるか**だけです。決められるのに「なし」と書いたなら、それは分類ではなく先送りで、半年後の自分にはもう区別が付きません。その場で書いてしまうほうが、結局は安上がりでした。

## 検証手順: 破って、落ちることを確かめる

**前提**

- 禁止事項の一覧に「機械検証」の見出しを足し、**「あり」と書いた項目が 1 つ以上ある**こと
- 作業中の変更が無い状態（`git status` が空）から始めること

**所要時間**: 10 分

**手順**

1. **あなたが**、「機械検証: あり」と書いた項目を 1 つ選び、そこに名前が書いてある自動テストを開きます。⚠️ **名前が書かれていない**なら、確かめる前にそこが問題です。どの自動テストが見ているのかを、まず項目に書いてください
2. **あなたが**、その禁止への違反をわざと 1 つ作ります。自動テストが走査している範囲の中に書きます
3. **あなたが**、その自動テストを走らせます

**合格条件**（すべて満たすこと）

- 自動テストが**落ちる**
- メッセージに、**手順 2 であなたが書いた違反の場所**が出ている

**合格しなかったとき**

- **落ちなかった** —— ⚠️ **その項目の「あり」は嘘です。** 「機械検証: なし（レビューで担保）」へ直すか、自動テストの走査の範囲を広げるか、どちらかをその場で決めます
- **落ちたが、場所が出ない** —— 直す側（AI でも、あなたでも）が、毎回探すことになります。メッセージに違反箇所を含める形へ直します

**後始末**

- 手順 2 で書いた違反を消し、合格に戻ることと `git diff` が空になることを確かめます

破ったのに落ちない自動テストは、無い自動テストより悪いです。**AI は「機械検証: あり」の 1 行を、そこが機械に守られている証拠として読み、その禁止を自分で確かめ直しません。** この回が置いたのは、一覧を読み直さずに済ませるための 1 行でした。**その 1 行が嘘なら、読み直さないという判断のほうが先に壊れています。**

---

次回は「AIの確認依頼を断る技術」。**AI に「画面を開いて目視で確認してください」と言われても、私は開きません。**それでも、壊れたまま先へ進むことはありません。

---

**連載「AIの意見を聞かない技術」**

- ← 前回: [第 4 回 サブエージェントの入力だけは、確かめろ](https://typing-tube.net/articles/kikanai-04-subagent-input)
- → 次回: [第 6 回 AIの確認依頼を断る技術](https://typing-tube.net/articles/kikanai-06-production)
- 全回の一覧: [序論 断ったはずの提案が、また来る](https://typing-tube.net/articles/kikanai-intro)
