blog
CLAUDE.md の書き方が21項目になるまで
このサイトのリポジトリには CLAUDE.md が1つある。いま 67行・8,382文字。Claude Code がセッションの最初に必ず読むファイルだ。
そのうち21項目が「退行を出さない」という1つの節に入っている。21項目とも、実際に事故を踏んだ後に足したものだ。 先回りして書いた行は1つも無い。
書き方の話をする前に、この増え方の話から始めたい。使ってみて分かったのは、CLAUDE.md の質は「何を書くか」より「どう増やすか」で決まるということだった。
最初は、この節そのものが無かった
初版の CLAUDE.md は 41行で、原則とガードレールと参照先しか書いていなかった。「退行を出さない」という節は無い。
節ができたのは 2026-07-28 で、見出しにその日付と理由がそのまま入っている。
退行を出さない(2026-07-28 追加・実際に3回やらかした反省)
3回やらかすまで、この節は存在しなかった。 先に書いておけばよかったのかというと、たぶん違う。書いていなかったから踏んだのではなく、踏んで初めて何を書けばいいか分かったというほうが近い。
たとえば最初に足した項目はこうなっている。
置換したら適用を確認する。スクリプト(
sed/python のreplace)は対象が無くても黙って成功する。書き換えたら必ずgrepで新しい値を目視確認する。assert old in sを書いてから置換する。「変えたつもり」で変わっていないのが最頻の事故(例: 節の半径を 15 にしたつもりが 8 のままだった)。
1行で「変更したら確認する」と書くこともできた。そうしなかったのは、抽象的に書くと読む側(自分自身でもある)が毎回違う解釈をするからだ。この項目には3つ入っている。
- 具体的な動作(
grepで確認 /assertを先に書く) - なぜそうなるのか(置換は対象が無くても成功する)
- 実際に踏んだ例(半径15のつもりが8のまま)
3つ目が一番効いていると感じる。「これは起きる」ではなく「これは起きた」と書いてあると、読む側の扱いが変わる。 自分で書いた文なのに、そうなる。
いちばん極端な項目には、踏んだ回数まで書いてある。
値の意味を変えたら、その値の全参照を洗う(2026-07-29 追加・同じ穴に5回落ちた)。座標
yを「胴の中ほど」→「足元」に変えたとき、弾の発射位置・照準・当たり判定・敵弾・アイテム吸着の5箇所が順に壊れ、CK からの報告のたびに1件ずつ直していた。症状ベースで潰すと同じ原因を何度も踏む。意味を変える変更をしたら、その場で全参照を列挙して1つずつ判断する。
5回というのは誇張ではなく、報告を受けるたびに1件ずつ直していた実際の回数だ。書いてあるのは戒めではなく、記録に近い。
書いてあるだけの規約は守られない
もっと厳しい発見がある。具体的に書いても、機械が見ていない規則は結局守られない。
記事を公開する前に別系統のモデルでレビューを通す、という規約を作った。docs にはっきり書いた。守られなかった。レビューを通した後で本文に追記して、そのまま公開したことがある。
いまは台帳に記録して、検証スクリプトが照合している。レビュー時点の本文のハッシュと、公開する本文のハッシュが一致しなければ、検証が落ちる。
正確に言うと、ビルドそのものは通る。CI はビルドの後段で検証スクリプトを走らせるので、落ちるのはそこだ。ビルド成果物はできているが、ジョブが赤くなって先へ進まない。
決定ログにはこう残した。
「書いてあるだけの規約」を機械に移した。RV必須を docs に書くだけでは守られないと判断し、台帳
harness/rv-ledger.jsonとverify.pyのarticle_external_rv_*で照合するようにした。判断の根拠は自分で書いた記事(`/blog/draft-articles-had-no-gate/…
規則そのものは CLAUDE.md に残しつつ、強制は機械へ移した。この分担が今のところ一番うまくいっている。
- CLAUDE.md: なぜそうするか(判断の材料)
- 検証スクリプト: そうなっているか(機械の照合)
- docs/: 手順の詳細(長くなるもの)
CLAUDE.md に手順を全部書くと、長くなって読まれなくなる。かといって docs だけに書くと、そもそも見に行かない。判断に必要な最小限を CLAUDE.md に置き、詳細は指すだけにする。
写経しない
分担を決めた後で、別の事故を踏んだ。
docs/ にある公開方針を1つ変えたのに、それを要約していたファイルが7つ、変更前のまま残っていた。スキルの手順書、エージェントの定義、スラッシュコマンド、実行計画、採点データ——手順書だけではなかったのが厄介なところで、直すべき場所を数え上げるのに時間がかかった。結果として、司令塔の側は「出してよい」、実行の側は「出すな」という状態になった。
原因は単純で、同じ方針を7箇所に書き写していたからだ。1箇所を直しても、残り6箇所は古いままになる。
いまは CLAUDE.md にこう入っている。
方針は1箇所に置き、他所は指すだけにする(写経しない)
これも機械で見ている。古い方針の文言が残っていると、検証スクリプトが拾う。
同じ文が2箇所にあったら、片方はいつか腐る。 これは CLAUDE.md 自体にも当てはまるので、CLAUDE.md には「詳細規約は docs/ を参照(このファイルは薄く保つ)」という自己言及の行を入れてある。
「薄く保つ」は、消すことでは達成できていない
CLAUDE.md には「詳細規約は docs/ を参照(このファイルは薄く保つ)」と書いてある。では実際に薄いのか、全コミットの行数を数えてみた。
| 行数 | |
|---|---|
| 2026-07-19(最初のコミット) | 38 |
| 2026-07-19(同日3コミット目) | 41 |
| 2026-08-12 | 54 |
| 2026-08-12(同日) | 61 |
| 2026-08-24 | 62 |
| 2026-08-27 | 67 |
前のコミットより総行数が減った時点は、一度も無い。
行の削除自体は何度も起きている。数字の更新、方針の書き換え、説明の差し替え。ただしそれらは全部書き直しで、削った行の代わりに別の行が入っている。規則を1つ消して、そのぶん短くなったという形は見つからなかった。
薄さを保っているように見えるのは、増えた分を外へ出しているからだ。ガードレールの一覧は docs/destructive-ops.md に、モデルの使い分けは docs/orchestration.md に、いま何をしているかは harness/STATE.md にある。CLAUDE.md に残しているのは、その場で判断を変える文だけにしている。
ただ、それで本当に薄いと言えるのかは分からない。21項目を毎回読んでいるのか、と聞かれると自信が無い。消す判断ができていないのが今の正直なところで、この記事を書きながら初めて行数を数えた。
いま効いていると感じる形
書き方として、いま自分が守っているのはこれだけだ。
規則は事故の後にだけ足す。 先回りして書いた規則は、たいてい起きない事故に備えていて、読む側の注意を薄める。
必ず実例を添える。 何が起きたか、何回起きたかを書く。抽象的な戒めは読み飛ばされる。
強制できるものは機械へ出す。 CLAUDE.md に残すのは理由のほうで、判定はスクリプトに持たせる。人間も AI も、書いてあるだけの規約は守らない。
方針は1箇所。 他所からは指すだけにする。写した瞬間に腐り始める。
詳細は外へ出す。 CLAUDE.md には判断を変える文だけを残し、手順は docs へ送る。
5つ目を「消す」と書けないのが心残りだ。増やす規律はできたが、減らす規律はまだ無い。 いまの CLAUDE.md も、来月には項目が増えているはずだ。増えたということは、また何か壊したということでもある。
このリポジトリで動かしているブラウザゲームはKludge Worksで遊べる。21項目のうち最初の5つは、このゲームを壊しながら書いたものだ。残りは別のゲームと、サイトの運用そのもので踏んだぶんになる。