メインコンテンツへスキップ
← 記事一覧に戻る
·運用·10 min read

CLAUDE.mdにNEVERと書いても3回目に破られた—hookだけが機能する理由を実測した設計ログ

Claude CodeCLAUDE.mdHooks個人開発AI設計
CLAUDE.mdにNEVERと書いても3回目に破られた—hookだけが機能する理由を実測した設計ログ

「CLAUDE.mdにNEVER delete files in productionと書いたのに、また消された」——Claude Codeを長く使っていると、必ずこの局面が来ます。

一度は守られます。二度目も守られることが多い。でも三度目、四度目、コンテキストが長くなってきたタイミングで、ルールがすり抜けることがある。

これは「Claudeが言うことを聞かない」のではありません。**CLAUDE.mdのルールは構造的に「ソフトウォール」**なのです。そしてこの問題の唯一の解決策が、hookでした。


結論

仕組みどう機能するか信頼性
CLAUDE.md のルール記述LLMがコンテキストとして読む → 確率的に従うソフトウォール(長いコンテキストで抜けやすい)
hook(UserPromptSubmit / Stop等)Claude Codeハーネスが実行する → 必ず動くハードウォール(LLMの判断と独立)

CLAUDE.mdは「してほしいこと」の定義場所。hookは「必ずさせること」の実装場所。 この役割分担を設計に組み込むことで、「また破られた」が止まります。


この記事の前提(自分の状況・スタック・実験条件)

  • 運用構成: masatoman.net(記事200本規模)をClaude Code + hooks + CLAUDE.md で自動化運用中
  • hook実装済み: UserPromptSubmit hook(git contextを自動注入)、Stop hook(作業後のgit status可視化)、PreCompact hook(圧縮前ログ保存)の3種を運用
  • 発見契機: settings.jsonにhookを追加した同セッション内で即座に発火した事実から、hookとCLAUDE.mdの「強制力の違い」を体感として理解した
  • CLAUDE.md規模: 4,696文字・115行(

    トークン実測記事参照


読者のよくある詰まり(「それ俺だ」ポイント)

「CLAUDE.mdに禁止事項を書いたのに、セッションが長くなると守られなくなる」

具体的にこんな経験はないでしょうか。

  • NEVER push directly to main と書いたのに、長い作業の後半で直接pushされた
  • 必ずlintを通してからcommitすること と書いたのに、lint未実行でcommitされた
  • 同じ禁止事項を3回書き直したが、毎回どこかで抜けが出る

これは「どう書けばより守ってもらえるか」を試行錯誤する問題ではありません。CLAUDE.mdの仕組み上、これは構造的な限界です。


実際に起きたこと:hookを実装した日の発見

2026年5月、CLAUDE.mdの指示だけで運用していた私が、はじめてhookを実装しました。

Stop hook、PreCompact hook、UserPromptSubmit hookの3種類を settings.json に追加した直後のことです。

「hookは次のセッションから反映される」と思い込んでいました。ところが、同じセッションの後半で、UserPromptSubmit hookが即座に発火しましたsettings.json のhot reloadが効いたのです。

この瞬間に気づいたのは、hookとCLAUDE.mdの決定的な違いです。

  • CLAUDE.mdを書き換えた直後: Claudeはそのセッション内のコンテキストに既に読み込み済みの古いバージョンを参照する
  • settings.jsonのhookを書き換えた直後: ハーネスが即座に新しい設定を読み込み、次のフックポイントで実行する

「ルールを更新したのに効いていない」という場合の多くは、この仕組みの違いに起因しています。


原因分析:「ソフトウォール」と「ハードウォール」

CLAUDE.mdが「ソフトウォール」である理由

CLAUDE.mdに書いたルールは、Claudeへのコンテキスト注入として機能します。Claudeはそれを読み、プロンプトとして解釈し、「できる限り従おうとします」。

しかし、これは以下の条件で崩れます。

  1. コンテキストウィンドウが長くなる: 会話が長くなるにつれ、CLAUDE.mdの内容が相対的に薄まります。後半の会話の方が、LLMにとって「直近の文脈」として重く扱われます
  2. ルールの量が多い: 禁止事項が10個あると、12個目の判断が必要な場面で8番目の禁止事項が見落とされやすくなります(

    CLAUDE.mdの肥大化問題

  3. 矛盾する指示がある: 「素早く実行せよ」と「必ず確認を取れ」が共存すると、文脈によってどちらかが選ばれます
  4. 強調語の効力消失: NEVERMUST NOTCRITICAL を多用すると、すべての記述が同じ重みになります

hookが「ハードウォール」である理由

hookは、Claudeのコンテキストに依存しません。Claude Codeのハーネスが、定義されたライフサイクルポイントで実行します。

// settings.json の例
{
  "hooks": {
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "bash /path/to/git-context-inject.sh"
          }
        ]
      }
    ]
  }
}

このスクリプトは、Claudeが「実行するかどうか判断する」のではなく、ハーネスが強制的に呼び出します。LLMの判断が介在しません。

git status を毎ターン表示するStop hookを実装した日、私のリポジトリに untracked ファイルが84件 存在することが一瞬で判明しました。CLAUDE.mdに「gitを常に意識せよ」と書いていても、この可視化は起きていませんでした。


判断基準:CLAUDE.mdに書くこと vs hookに移すこと

では、具体的にどう分けるか。私の現在の運用ルールを共有します。

CLAUDE.mdに書く(LLMに「理解してほしいこと」)

種別
プロジェクトの文脈定義「このサイトのターゲットは個人開発者・副業者」
高レベルの方針「記事執筆は失敗ログ優先、成功談は控える」
役割とスコープ「コード変更はsrcディレクトリ以外触らない」
推奨パターン「コンポーネントは既存ライブラリを再利用する」

これらは「Claudeがどんな判断軸を持つべきか」を定義するもの。コンテキストとして理解させるのが目的で、厳密な強制力は求めません。

hookに移す(「必ず起こさなければならないこと」)

タイミングhook種別用途
毎プロンプト前UserPromptSubmitgit contextの自動注入、lintチェック
作業完了後Stopgit statusの可視化、未pushの警告
コンテキスト圧縮前PreCompact状態スナップショットの保存

判断の基準はシンプルです: 「1回でも抜けたら困るルール」は全部hookへ移す。

# Stop hookの例(git-status-check.sh)
#!/bin/bash
STATUS=$(git status --short)
UNTRACKED=$(git ls-files --others --exclude-standard | wc -l)

if [ -n "$STATUS" ] || [ "$UNTRACKED" -gt 5 ]; then
  echo "⚠️  作業後の状態確認"
  echo "変更: $(echo "$STATUS" | wc -l)件 / untracked: ${UNTRACKED}件"
  git status --short | head -20
fi

このスクリプトは、Claudeが忘れてもハーネスが実行します。


今日やること(3つ)

  1. 自分のCLAUDE.mdを開いて「NEVER/MUST NOT/CRITICAL」でgrepする — 出てきたルールは「本当にhookで強制すべきか」を再評価する
  2. 最低1つのStop hookを実装するgit status 表示のみでも十分。未push/untrackedの可視化だけで運用が変わります(

    hook実装の基礎はこちら

  3. CLAUDE.mdのルールを「コンテキスト定義」と「強制事項」に色分けする — 後者はhookへの移植候補リストとして管理する

masatoman のメルマガ — 毎週月曜の朝に手紙を 1 通

masatoman.net の今週の記事 1 本を、読者目線で深掘りした手紙が毎週月曜 9:00 に届きます。「これ自分のことだ」が見つかる予告編。登録特典に「個人開発の収益化チェックリスト 15 項目」。

masatoman のメルマガ — 毎週月曜の朝に 1 通

masatoman.net で今週公開した記事の中から 1 本を、読者目線で深掘りした手紙が届きます。「自分も同じことやってる」「ここで詰まってた」が見つかる予告編。

シェア

コメント

投稿にはログインが必要です(メールアドレスのみ・パスワード不要)。入力内容は保持され、ログイン後そのまま投稿されます。