CLAUDE.md の指示を減らしたい。でも、消した途端に同じ失敗をされるのは困る。読んで「これはもう要らないだろう」と判断するだけでは、心もとないです。

そこで、規則をわざと破ったファイルを用意し、CI が見つけるかを試しました。9 件中 5 件は止まり、4 件はビルドが通りました。通った中には、公開したくないページがそのまま出力されるケースもありました。

見逃した 4 件のうち 3 件には検査を追加できたので、対応する注意書きを指示ファイルから削りました。日本語と英語のページで内容が食い違う問題は、今回の検査では判断できず、指示を残しています。

指示を消す前に、違反を入れてみる

きっかけは「Claude Code のプロンプトの 80% を削った」と題した動画でした(説明文を 2026-08-07 に取得)。プロンプトを削り、作り直すというチャプターがあり、自分の指示も見直したくなりました。「80%」の分母や削除方法までは確認できていないので、同じ割合を削ろうという話ではありません。

手元では、失敗したときに指示を足す一方、うまくいっている間は削る理由がありません。その行が必要なのか、ほかの仕組みで防げているのかを分けてみます。

使うのは、規則違反を見つけたら CI を失敗させる自動検査です。lint でも、ビルドや出力 HTML の検査でも構いません。

規則を一つ選び、記事やコードに違反を入れて検査を実行します。指示ファイルの行を消すだけでは、違反を検出できるかは分からないので、まだ消しません。

違反を入れたときの結果 分かること
RED (失敗) その検査が違反を捕まえている
GREEN (成功) その違反を検出できていない

わざと壊したものにテストを当てる mutation testing に近い確かめ方です。終了コードだけでなく、どの検査が失敗したかもログで確認します。

公開したくないページまで、ビルドは通していた

対象は、AI エージェントの活用パターンをまとめている VitePress のリポジトリです。日本語と英語のページを対で持ち、必須見出しや引用の書き方などを 8 本の lint で検査しています。以下はこのサイト固有の規則を使った実験です。

CLAUDE.md には、機械で検査できる規則は重ねて書かず、検査がない規則を残す方針がありました。「ゲートが無い規則」という節もあったので、その区分が実際の検査と合っているかも見ました。

npm run docs:build は lint、VitePress のビルド、出力 HTML の検査を行い、1 回約 4 秒でした。次のスクリプトで違反を一つずつ入れています。未コミットの変更を破棄し、docs/notes を削除する処理があるため、試す場合は作業中のファイルがない実験用のコピーを使ってください。

P=docs/patterns/read-and-discard-isolation.md   # 違反を仕込む対象ページ

r(){ git checkout -- . >/dev/null 2>&1; rm -rf docs/notes; }   # 復元
t(){ local id=$1; r; eval "$2"
     npm run docs:build >/tmp/p-$id.log 2>&1 \
       && echo "$id GREEN" || echo "$id RED"
     r; }

t A1-forbidden-term "printf '\n設定は .chatmode.md に書く。\n' >> $P"
t B1-svg-blank-line "perl -i -pe 'print \"\n\" if \$.==38' $P"
# …以下同様に、1試行につき違反1件

$.==38 は、対象ページの SVG の子要素が並んでいる途中の行です。ファイルが違えば、この行番号も変わります。

規則の種類 入れた違反 検査結果
語彙 禁止された古い API 名を書く RED
構造 必須の見出しを一つ消す RED
リンク 存在しないページへリンクする RED
引用 引用元の一覧にない英文を引用する RED
翻訳 英文の引用に訳を添えない RED
構造 インライン SVG の途中に空行を入れる GREEN
リンク 英語ページの内部リンクから /en/ を落とす GREEN
翻訳 日本語の本文だけを変え、英語をそのままにする GREEN
公開範囲 非公開にしたいディレクトリを docs/ 直下に作る GREEN

上から 5 件を捕まえたのは、順に lint-forbidden-termslint-page-template、VitePress のデッドリンク検査、lint-brief-citationslint-quote-translations でした。

「ゲートが無い規則」の節に載っていたのは、見逃した 4 件です。同節の全 12 項目のうち、残り 8 項目は試していません。コミットやレビューの作法なども含まれていました。

出力先を開くと、非公開のつもりのページがあった

見逃したもののうち、2 件は生成物も確認しました。

$ mkdir -p docs/notes && printf '# 漏れたページ\n' > docs/notes/leak.md
$ npm run docs:build && ls docs/.vitepress/dist/notes/
leak.html
[build-output] 検査した出力ファイル: 188(正常時は 185)

docs/notes に置いたページが、実際に leak.html として出力されました。出力ファイルの数は正常時の 185 から 188 に増えましたが、検査は数を表示するだけで、増加をエラーにしていませんでした。

SVG の途中に空行を入れた場合も、ビルドは通りました。

$ npm run docs:build && grep -o '<pre[^>]*>' docs/.vitepress/dist/patterns/read-and-discard-isolation.html
<pre>

正常時にはない <pre> が出ています。Markdown の HTML ブロックが空行で終わり、続く 4 スペースのインデントがコードブロックとして解釈されていました。図の一部がマークアップのまま表示されます。

ただし、<svg …> の直後に空行を入れたときは壊れず、&lt; の数も正常時と同じ 0 でした。今回壊れたのは、インデントされた子要素の間に空行を入れた場合です。

3 件は検査を追加できた

見逃した 4 件について、コードで条件を書けるか考えました。

見逃した違反 追加した検査 結果
SVG の空行 出力に &lt;rect&lt;text&lt;path などが出ていないか 日英 2 ページとも RED
/en/ の欠落 docs/en/** の内部リンクが /en/ で始まるか 9 件を検出して RED
docs/ 直下の新ディレクトリ 直下のディレクトリ一覧が、公開対象の一覧と一致するか RED
日英の内容の食い違い 同じ意味かどうかの判定 今回は書けなかった

SVG の検査では、コードブロックを除外すると見逃します。既存の検査には誤検出を避けるため <pre><code> を除くものがありましたが、壊れた図はちょうどその中に入っていました。

ディレクトリの検査も、禁止名を列挙するだけでは未知の名前を捕まえられませんでした。公開するディレクトリを一覧にして、それと実際の構成を比べる形にしました。

日英の内容の一致は、今回の検査では判断できませんでした。片方だけ変えたコミットに注意を出す方法は考えられますが、同じ意味かどうかは本文を読んで確かめます。

規則違反を 9 件試した結果 既存の検査で検出できた:5 件 検査を追加して検出できた:3 件 内容を読んで確認する:1 件

新しく作った 3 本は、違反を入れると失敗し、正常な状態では通ることを確認しました。そのうえで CLAUDE.md から 3 件の記述を削除しました。2 件は項目ごと、1 件は項目の該当部分だけです。既存の検査で捕まった 5 件と合わせると、9 件中 8 件を検査で確認できる状態になりました。

最初の 2 試行はやり直した

引用の違反を入れた最初のファイルは、検査対象から除外されていました。lint-brief-citations.mjs:56 を読んで分かり、対象ファイルを変えてやり直しています。

日英の食い違いでは、最初に h2 見出しを変えたら失敗しました。ただし落ちたのは見出しの定型を調べる lint です。本文だけを変えてやり直すと、検査は通りました。

終了コードだけ見ていたら、引用は「検出できない」、日英の食い違いは「検出できる」と、両方とも逆に記録していたところでした。自分で作った実験も、そのまま信用はできませんでした。

よく間違える規則は指示にも残す

検査で捕まるからといって、全部の指示を消すわけではありません。違反を出してから直す回数が多ければ、最初に指示しておいたほうが手戻りを減らせます。

今回削った SVG の空行、/en/ の欠落、新しいディレクトリは、手元では数十セッションに一度あるかという頻度でした。一方、文体や使ってはいけない語は記事を書くたびに関係するため、検査と指示の両方を残します。

指示は読み込むたびにコンテキストを使います。検査は実行するたびに時間がかかり、違反したときには修正と再実行も必要です。今回の 3 本はパスと行番号が出るので直しやすかったですが、手戻りの費用までは測っていません。

このブログにも検査を一つ足した

執筆中、このブログでも太字の記号がそのまま見える不具合を踏みました。日本語の約物と ** の位置関係によって、強調として解釈されないことがあります。対応するはずの記号が別の箇所と組になり、無関係な文が太字になる場合もありました。ビルドだけでは分かりません。

そこで、出力 HTML の可視テキストに、コード表記以外の生の ** が残っていないかを調べる検査を加えました。当時の旧記事で見つかっていた 23 ページは許容リストに入れ、実際の検出結果と一致することも確かめています。

検出用の正規表現をわざと壊すと、既知の 23 ページが検出されなくなり、一覧との不一致で検査が落ちました。既知の不具合が、検出処理そのものを確かめる材料にもなりました。

今回の 3 件は、違反したファイルで検査が失敗するところまで確かめてから削れました。次に注意書きを足したくなったら、同じ失敗をコマンドで見つけられるかを考えます。毎回読ませる一行を減らせるかどうかも、その結果を見て決められます。