起動しただけで1割持っていかれるので、ルールファイルの置き場所を変えた

開発claude-code-tools

起動しただけで1割持っていかれるので、ルールファイルの置き場所を変えた

朝、セッションを開くと、まだ一言も打っていないのにゲージが15%ほど埋まっている。

前から視界の端には入っていた。 まあ、今すぐ手を打つほどでもないのだけど、何がそこを占めているのかくらいは知っておきたい。 今日はそこから始めた。

実測させたら、指示文が本体だった

何が圧迫しているのかを実測してもらった。

答えはすぐ返ってきた。 最大の圧迫源は ~/.claude/rules/*.md の自動ロードだった。 19本で約43,000トークンを占めている。 tiktoken の cl100k で数えた値だ。

そこに構造上の問題も乗っていた。 CLAUDE.md は「要約だけ置いて、詳細は rules/ を見に行く」という設計で書いてある。 ところが、その参照先も起動時に全文が読み込まれる。 つまり要約と本文が二重に入っていた。 参照させるつもりで書いた行が、参照される前に丸ごと展開されていたわけだ。

このあと PC を再起動したかったので、実態を全部計画書に起こさせた。 図を2枚作らせ、Codex のレビューを5往復かけた。 ルールファイルは1バイトも触らないまま、この時点で止めている。

削除ではなくアーカイブにした

最初は「不要なものは削除でいい」と言っていた。

途中で言い直した。 削除という操作は、目的外のものまで巻き込む確率が上がる。 だから、移し先へコピーし、内容が一致することを確かめ、それからコピー元を消す。 この3手で移すことにした。 mv のような一手で移動する書き方は使わせない。 一手で消えるものは、失敗したときも一手で消える。

あわせて、変更対象のディレクトリが全部 git 管理下に入っているかを確認させた。 誤って消しても戻せる状態を先に作っておきたかった。

先に「落ちるテスト」を書かせる

対応表を文章で書いても、実行しなければ守られない。 そこで移行仕様を検証スクリプトに落とし、いま走らせると落ちることを先に確認させた。

最初は 14/138 で赤。 そこから移し先の解決、参照の書き換え、内容の保存という順に検査を足していった。

途中、サンドボックスで移行を丸ごと予行演習させたら、設計上の衝突が出た。 CLAUDE.md にすでに参照がある項目へ、移行時のトリガー行をもう1本足すと重複する。 9件の失敗が全部これで、机上では気づけなかったやつだ。

Codex はスクリプト自体の欠陥も3件出してきた。 そのうち一番効いたのが「内容が保存されているか検査していない」という指摘だった。 参照のパスさえ書き換われば通ってしまう。 本文が消えても緑になるテストは、テストの形をしただけのものだ。

検査を足して、216/216 で緑になった。 検証スクリプト3本と、実装に追随させた計画書をコミットした(b422712c)。

実測ベースラインで診断の裏を取る

推定 94.5k に対して、/context の実測は 102.8k。 Memory files が 70k で、起動時全体の 68% を占めていた。

内訳の 29 ファイルは、グローバル rules 19、プロジェクト rules 8、CLAUDE.md 2 と完全に一致する。 「起動時コンテキストの大半は指示文の全文ロード」という診断が数字で裏づけられた。

Claude Code 自身も「Memory files → save ~21k」と提案してくる。 こちらの計画はそこからもう一段踏み込んで、約38kの削減を狙う形になった。

生出力をそのまま context-before.txt に保存し、計画書を実測に較正してコミットした(db23c652)。 移行後に同じものを撮って突き合わせるためだ。

決裁フォームを立てて、退避する範囲を15本に確定した(7ed6c4a0)。

移行の途中で改行に足を取られる

グローバル側8本を移し終えたあたりで、検証が3ファイルで落ちた。

原因は内容ではなく改行コードだった。 sed -i が CRLF を LF に落としていた。

自分のルールファイルには「sed はバイト列を保つ」と書いてある。 その前提が外れていた。 Edit ツールなら CRLF を保つと確認できた。 改行を保つ置換ツールを用意し、落ちた分を巻き戻してやり直した。

置換の副作用も1件出た。 recurring-complaints.md で、パス表記のつもりで書いた置換がバッククォート外の「mdx-playground」という語まで消していた。 本文を復元して先に進んだ。

参照はどこまで探せば漏れないのか

参照の書き換えは、探索範囲を外すとそのまま漏れになる。 ここは3回取りこぼしが見つかった。

  • 監査スクリプトを走らせたら、プロジェクト側の .claude/references/ を初回の grep 範囲に入れていなかった。ついでに、そこはすでにコマンド別のリファレンス置き場として実運用されていたと分かった。移し先の方式は新規発明ではなく、既存パターンの横展開だった
  • Codex 向けのスキルミラー .agents/skills/ が範囲外だった
  • ~/.claude/assets/ の CSS と HTML が参照元になっていた。ディレクトリと拡張子の両方を外していた

Codex の指摘を受けて全リポジトリ走査を別実装で作ったら、apps/web/app/ 配下の実コードに本物の漏れが6件あった。 ページの .vueutils.ts が、移動対象のルールをコメントで指していた。

プロジェクト側5本を退避し、旧パス参照を全件書き換えてコミットした(bef22de8)。 実施記録と監査ツール、検証ベースラインも同じタイミングで入れた(c3c52482)。

検証が git checkout で自壊する

ブランチを畳んだあと、216/216 だった検証が 195/216 に落ちた。

内容は1文字も変わっていない。 git checkoutautocrlf=true で作業ツリーを CRLF に書き直しただけだった。 ベースライン側が CRLF 込みで記録されていたので、片側だけ正規化しても合わない。

ベースラインを改行非依存な形に作り直した(d5d0dad3)。 移動元の中身は git の ODB から取り直すので、内容が保存されているかという検査の意味は保たれる。

このとき別の想定外もあった。 15:05 に日次の自動バックアップが走り、私の作業ブランチの上でコミットしていた。 「このブランチ、結局これで OK なんですか」と聞いたら、OK ではなかった。 両リポジトリとも master に畳んで、ブランチを削除した。 取りこぼしはゼロだった。

移行前後の突き合わせ

移行後の /context を撮って、朝のベースラインと並べた(82963157)。

ブロック移行前 09:26移行後 16:03
起動時合計102.8k70.2k-32.6k(-31.7%)
Memory files70.0k / 29ファイル37.1k / 15ファイル-32.9k(-47.0%)
空き897.2k929.8k+32.6k

Claude Code 自身の提案は 21k 節約だった。 実測はその 1.55 倍になった。

Skills が 116 のまま増えていないのも狙いどおりだ。 同じ内容をスキルにすると description が常時ロードされるが、リファレンスに置けば1トークンも増えない。

最後に Codex へ完了レビューを投げた。 長いプロンプトだと無応答で固まるので、依頼文をファイルに書き出して自分で Codex アプリから投げる手も用意した。 CLI 側が先に返ってきた。 判定は「計画どおり完了、致命的な問題なし」。 こちらの申告を鵜呑みにせず、独自に裏を取ったうえでの結論だった(42bf83a4)。

塞ぎ忘れていた穴

作業中、別のセッションが新しいルールを rules/ に追加していた。

これは正しい行動だ。 移行の計画にも CLAUDE.md にも、「新しく作るときはどちらに置くか」が一言も書いていなかった。 既存27本を振り分ける基準はあるのに、新規作成時のガイドがない。 穴は指示の側にあった。

rules/ に置いてよいのは、どんな作業をしていても効く行動規範と、その機の環境前提の2種類だけ。 それ以外は references/ に置いて、マップに導線を1行足す。 この基準を両方の CLAUDE.md に追記した。

今日わかったこと

  • 起動時に持っていかれる分は、体感ではなく /context で撮れる。撮っておけば効果測定が突き合わせで済む
  • 参照させるつもりの文書が自動ロードされていると、要約と本文が二重に入る。置き場所を変えるだけで半分近く消える
  • 移行の検証は、パスの書き換えだけでなく内容の保存まで見ないと意味がない。本文が消えても緑になるテストは通しても安心できない
  • 改行コードは2回足を引っ張った。sed -igit checkout の両方で作業ツリーが書き換わる。検証を改行に敏感なまま作ると、内容が無傷でも赤くなる
  • 削除ではなく、コピーして一致を確かめてから消す。手間は増えるが、巻き込み事故の確率は下がる

移行そのものは終わった。残りは事後確認が4件。

#Claude Code#コンテキスト管理#運用改善#TDD