先に結論です。指示ファイル・ルール・メモリの索引・スキルの一覧は、セッションの開始時に一度だけ、最初の user メッセージとして届きます。 その後のターンで読み直されることはなく、読み直しが起きるのは圧縮の直後と、次のセッションの開始だけです。一方で、メモリの本文・スキルの本文・下位ディレクトリの指示ファイル・パス指定のルールは、開始時には名前しか届かず、本文は「引き金」が引かれたときに会話層へ足されます。引き金のうち機械が引くのは 2 つ(パスの一致と、下位ディレクトリの走査)で、残りはモデルの判断です。本編が「足すほど薄まる」「索引だけが読まれる」「スキルを使わない」「現物が前例として効く」と書いたことは、全部、この「いつ・どの部分に・どこまで」の違いの話です。

付録 A.4 は、user メッセージとして届くものを表にしました。付録 B.3 は、圧縮で何が生き残るかを書きました。この章はその 2 つの間を埋めます。CLAUDE.md がどの順で連結されるか、4 MiB と 200 行の意味、HTML コメントと @import.claude/rules/paths:、auto memory の 4 種と 200 行 / 25KB、スキルの description の 1,536 字と一覧の予算、本文が入るときの形、context: fork、そして「途中で編集しても効かない」理由。手元の構成を実測した数字を、公式の規則の隣に並べます。読み終えたら、本編 9 回分の「置いたもの」が、読み込み時点のどこに立っているかを言い直せるはずです。

D.1 4 つの読み込み時点

flowchart LR
  subgraph S["① セッション開始時<br/>最初の user メッセージ"]
    s1["CLAUDE.md の連結<br/>管理 → ユーザー → プロジェクト → ローカル"]
    s2["paths 無しの .claude/rules/*.md"]
    s3["MEMORY.md 先頭 200 行 / 25KB"]
    s4["スキルの名前 + description<br/>1,536 字 / 予算 1%"]
  end
  subgraph T["② 引き金で<br/>会話層に足される"]
    t1["下位ディレクトリの CLAUDE.md<br/>← そこにあるファイルを読んだ"]
    t2["paths 付きルール<br/>← 一致するファイルを読んだ"]
    t3["メモリの本文<br/>← Read した"]
    t4["スキルの本文<br/>← /name か Skill ツール"]
    t5["リポジトリの現物<br/>← Read / Grep / Glob した"]
  end
  subgraph C["③ 圧縮の直後"]
    c1["①を disk から再注入<br/>(スキル一覧は除く)"]
    c2["直近 5 ファイル + その規則を再読"]
    c3["呼んだスキル本文<br/>5,000 / 25,000 トークン"]
  end
  subgraph N["④ 次のセッション"]
    n1["①をやり直す<br/>②③は残らない"]
  end
  S --> T --> C --> N

4 つの時点を、届く部分と上限で並べます。部分の分け方は付録 A.1 の 3 つです。

何がいつどの部分に上限・切られ方圧縮後
CLAUDE.md(全階層の連結)① 開始時最初の user メッセージ1 ファイル 4 MiB を超えるとそのファイルごと読まれない。200 行未満が目安disk から再注入
.claude/rules/*.mdpaths 無し)① 開始時同上.claude/CLAUDE.md と同じ優先度disk から再注入
MEMORY.md(auto memory の索引)① 開始時同上先頭 200 行か 25KB の早いほう。後ろは載らないdisk から再注入
スキルの名前と description① 開始時同上1 件 1,536 字。一覧全体はコンテキストの 1%再注入されない
下位ディレクトリの CLAUDE.md② そのディレクトリのファイルを読んだとき会話層同 4 MiB直近 5 ファイルに紐づくものだけ再読
paths 付きルール② 一致するファイルを読んだとき会話層パターンの展開は 1,000 個 / 4 MiB まで同上
メモリの本文(topic file)② AI が Read したとき会話層(tool_result)ツール出力の上限(A.5)要約に取り込まれる
スキルの本文② 呼ばれたとき会話層(1 メッセージ)500 行以内が目安直近の呼び出しを先頭 5,000 トークンまで、合計 25,000 まで
リポジトリの現物② Read / Grep / Glob したとき会話層(tool_result)ツール出力の上限(A.5)直近 5 ファイル(5,000 トークン超はパス参照だけ)
plan mode の計画ファイル② AI が書いたとき会話層disk から再注入

表の読み方を 2 つ。①の行は「同じ 1 通の user メッセージ」に同乗しています。 順番はありますが、どれも system prompt ではなく、prefix cache の同じ一式に入ります(付録 A.4、B.4)。②の行は「引き金」が要ります。 引き金が機械(パスの一致・ディレクトリの走査)なのは 2 行だけで、残りはモデルが「開くほどの用事がある」と判断したときだけ引かれます。第 2 部 第 1 回の「索引に名前があることと、本文が読まれることは違う」は、この 2 段階の構造の言い換えです。

D.2 CLAUDE.md の階層と連結順

置き場所は 4 つの範囲に分かれ、広い範囲から順に連結されます。上書きではなく連結で、後に来るものほど「最後に読まれた指示」になります。

範囲場所誰と共有するか除外できるか
管理ポリシーmacOS /Library/Application Support/ClaudeCode/CLAUDE.md / Linux /etc/claude-code/CLAUDE.md / Windows C:\Program Files\ClaudeCode\CLAUDE.md。または managed settings の claudeMd キーそのマシンの全員できない
ユーザー~/.claude/CLAUDE.md自分の全プロジェクトclaudeMdExcludes
プロジェクト./CLAUDE.md または ./.claude/CLAUDE.mdチーム(バージョン管理)claudeMdExcludes
ローカル./CLAUDE.local.md.gitignore に入れる)自分のこの clone だけclaudeMdExcludes

ディレクトリの縦方向も連結です。foo/bar/ で起動すると foo/CLAUDE.mdfoo/bar/CLAUDE.md の順で、ファイルシステムの根から作業ディレクトリへ向かって並びます。各ディレクトリの中では CLAUDE.md の後ろに CLAUDE.local.md。起動ディレクトリよりCLAUDE.md は開始時には読まれず、そのディレクトリのファイルを AI が読んだときに会話層へ足されます(InstructionsLoadedload_reasonnested_traversal)。

flowchart TB
  M["管理ポリシー"] --> U["~/.claude/CLAUDE.md"] --> R["~/.claude/rules/*.md"]
  R --> P1["repo/CLAUDE.md"] --> P1L["repo/CLAUDE.local.md"]
  P1L --> P2["repo/.claude/rules/*.md(paths 無し)"]
  P2 --> W["repo/pkg/CLAUDE.md(起動ディレクトリまで)"]
  W -.->|"開始時には載らない"| N["repo/pkg/sub/CLAUDE.md<br/>← sub/ のファイルを読んだとき"]
  W -.->|"開始時には載らない"| G["paths 付きルール<br/>← 一致するファイルを読んだとき"]

数字は 3 つです。

  • 4 MiB。 1 ファイルがこれを超えると、切り詰められるのではなくそのファイルが丸ごと読まれません/context の Memory files に出てこないファイルは、無いか、超えているかのどちらかです
  • 200 行。 上限ではなく目安で、公式ドキュメントは「長いファイルはより多くのコンテキストを消費し、遵守率を下げる」と書いています。守らせる仕組みは無く、/doctor が checked-in の CLAUDE.md の削減案を出すだけです(v2.1.206 以降)
  • @import は 4 段階。 @path/to/file は起動時に展開され、参照先の中の @ も辿ります。相対パスはそのファイルの位置が基準で、作業ディレクトリではありません。コードスパンとコードブロックの中の @ は無視されます。`@README` と書けば文字のまま、@README なら取り込み。展開は起動時なので、分割しても読む量は減りません

HTML コメントは、ブロック単位のものが除かれてからコンテキストに入ります。コードブロックの中のコメントは残ります。ただし AI が Read ツールでその CLAUDE.md を開くと、コメントは見えます。つまり「指示ファイルにあるが AI には届いていない文」と「Read すれば見える文」が同じ行に共存します。保守者向けのメモを置く場所として公式が用意した仕様ですが、D.11 の検証 2 で両方向を踏んでおくと、境界がはっきりします。

@import の参照先が作業ディレクトリの@~/.claude/my-project-instructions.md など)にあると、プロジェクトの CLAUDE.md からの取り込みは初回に承認ダイアログが出ます。断ると以後は無効のままで、ダイアログも出ません。ユーザー範囲(~/.claude/CLAUDE.md~/.claude/rules/)からの取り込みはダイアログ無しで信頼されます。worktree をまたいで個人設定を共有したいときに公式が勧める形が、この home からの取り込みです。CLAUDE.local.md.gitignore 対象なので、作った worktree にしか存在しません。

もう 1 つ、--add-dir で足したディレクトリの CLAUDE.md は既定では読まれませんCLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 を付けたときだけ、そのディレクトリの CLAUDE.md / .claude/CLAUDE.md / .claude/rules/*.md / CLAUDE.local.md が載ります。settings の additionalDirectories で足した場合は、環境変数があっても読まれず、スキルも読まれません。

D.3 .claude/rules/paths:

.claude/rules/.md は再帰的に拾われ、paths frontmatter が無いものは開始時に .claude/CLAUDE.md と同じ優先度で載ります~/.claude/rules/ のユーザー範囲のルールはプロジェクトのルールよりに置かれ、プロジェクト側が後勝ちです。symlink は解決されて読まれ、循環は検出されます。

paths があるルールは、一致するファイルを AI が読んだときに会話層へ足されます。ツール呼び出しのたびに評価されるのではなく、Read の対象パスがパターンに一致した時点です。v2.1.198 以降は symlink 経由のパスでも一致します。

---
paths:
  - "src/api/**/*.ts"
  - "src/**/*.{ts,tsx}"
---

ブレース {ts,tsx} は展開されて数えられ、1 ルールの paths 全体で1,000 パターン / 4 MiB の予算を共有します。超えるパターンは展開されず、文字どおりの { として何にも一致しません(v2.1.217 より前は起動が止まりました)。[ は bracket expression の始まりとして読まれ、閉じられないパターンは無効で何にも一致しません(v2.1.207 より前は Read が失敗しました)。文字どおりの [\[ と書きます。

届く部分が違うので、圧縮での扱いも違います。paths 無しのルールは①の一式にいるので disk から再注入され、paths 付きは会話層にいるので要約に取り込まれます。 圧縮の直後に Claude Code が直近 5 ファイルを読み直すとき、そのファイルに一致するルールだけが戻ります。「必ず残したいルール」は paths を外すか、CLAUDE.md へ移す、が公式の指針です。

paths 付きルールと下位ディレクトリの CLAUDE.md は、どちらも「一部のファイルにだけ効く指示」ですが、置き場所が違います。ルールはリポジトリの根の .claude/ に集まり、下位の CLAUDE.md はそのコードの隣に置かれてディレクトリの所有者が保守します。monorepo で他チームの CLAUDE.md が拾われるなら claudeMdExcludes(絶対パスに対する glob。全 settings 層で配列がマージされる。symlink は実体とリンクのどちらのパスでも除外できる。v2.1.239 以降)で外します。管理ポリシーの CLAUDE.md だけは除外できません。

私の手元には .claude/rules/ がありません(プロジェクトにもホームにも)。第 1 部 第 6 回で「機械に持てるものを機械に持たせる」を通した結果、CLAUDE.md 1 枚(102 行)と、走査テストとラチェットで足りています。paths 付きルールは「ファイルの種類ごとに読ませたい方針」がある場合の道具で、方針を読ませる回数を減らす方向の本編とは、向きが逆です。使うなら、「そのディレクトリのファイルを読んだときだけ載る」= 読む量を増やさずに指示を増やせる、という点で本編の「足すほど薄まる」の外側に立てる道具だと理解しておいてください。

D.4 auto memory —— 4 種・200 行 / 25KB・worktree の共有

auto memory は Claude Code が AI に代わって書くメモで、CLAUDE.md と対になる仕組みです。公式ドキュメントは両方を「context であって enforced configuration ではない」と言い、止めたいなら PreToolUse hook を使えと書いています(付録 C)。

保存されるのは 4 種で、frontmatter の type に記録されます。

type何を保存しないもの
userあなたの役割・専門・作業の好みコードから導けること(構成・パス・デバッグの直し方)
feedbackあなたが与えた訂正と、確認した進め方CLAUDE.md にもう書いてあること
project進行中の作業・期限・コードや git 履歴から導けない判断
reference外にある情報の場所(issue tracker・dashboard)

置き場所は ~/.claude/projects/<project>/memory/ で、<project>git リポジトリから導かれます。なので同じリポジトリの worktree とサブディレクトリは 1 つの memory ディレクトリを共有し、git の外では起動ディレクトリが使われます。autoMemoryDirectory で別の場所を指せ(絶対パスか ~/。project / local の settings に書くと hook と同じ workspace trust の規則に従う)、CLAUDE_CODE_PROJECT_DIR_NAMECLAUDE_CONFIG_DIR を組めば複数リポジトリで 1 つを共有できます(v2.1.234 以降)。

ディレクトリの中は MEMORY.md(索引。1 行 1 件)と topic file です。読み込みの規則が、この章で一番はっきりした数字です。

  • MEMORY.md の先頭 200 行か 25KB の早いほうが、毎セッションの開始時に載ります。それより後ろは載りません
  • topic file は開始時に載りません。 AI が必要だと判断して Read したときだけ、tool_result として会話層に入ります
  • AI が MEMORY.md を書くたびに、Claude Code が 200 行と 25KB に対して測ります。近づくと「1 行 1 件にせよ、詳細は topic file へ、古い項目は統合か削除」の注意が返り、超えると書き込みは成功したうえで「rewrite the index」のエラーが返ります。次の起動で切られるからです(エラー文: this write left the memory index at MEMORY.md at ..., over its ... read limit
  • frontmatter のある memory file を AI が書くと、modified に ISO 8601 の書き込み時刻が記録されます(v2.1.214 以降。frontmatter の無いファイルには付きません)
  • サブエージェントには親の auto memory が載りません。 fork だけが例外です。サブエージェント自身の memory(frontmatter の memory: user | project | local)は別ディレクトリで、こちらは MEMORY.md の先頭 200 行 / 25KB がsystem prompt に入ります(付録 E)
  • 切るのは /memory の toggle(~/.claude/settings.jsonautoMemoryEnabled)、プロジェクトの settings、CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 のどれか
  • cleanupPeriodDays の transcript 掃除から memory ディレクトリは除外されます。消えるのはあなたか AI が消したときだけです

保存を促すのは製品の側です。何を残すかは AI が「将来の会話で役に立つか」で決め、毎セッション保存するわけではない、と公式は書きます。その判断を促す指示は system prompt に入っていて文面は公開されていません(あとがきの線引き)。観測できるのは、画面の「Saved N memories」「Recalled N memories」と、索引が上限に近づいたときの注意だけです。第 1 部 第 2 回の「AI が保存したがる」は、学習された振る舞いに製品の指示が重なった結果で、autoMemoryEnabled: false にすると後者だけが消えます。

MEMORY.md の上限が「200 行」と「25KB」の二重なのは、1 行が長い索引を止めるためです。25KB を 200 行で割ると 1 行 125 バイト、日本語なら 40 字前後です。第 1 部 第 2 回の「索引に 1 行足す」が 1 行に説明を詰め込む形になると、200 行より先に 25KB に当たります。

手元の構成は、製品の auto memory ではありません

ここで、私の手元を正直に書いておきます。本編は「メモリの一覧が毎セッション読み込まれる」と書きましたが、それを成立させているのは製品の auto memory ではなく、UserPromptSubmit の hook が MEMORY.mdcat している経路です(~/.claude/settings.json"autoMemoryEnabled": false)。違いは 3 つあります。

第一に、上限が違います。 製品の索引は 200 行 / 25KB で切られますが、hook の平文 stdout は 10,000 字で切られ、超えた分はファイルに退避されて先頭 2KB の抜粋とパスだけが届きます(付録 C.11 で見つけた抜け穴)。私の索引はどちらの上限も超えていて、hook の経路では先頭の 2KB しか載っていませんでした。

第二に、clone は memory を共有しません。 worktree は git リポジトリが同じなので 1 つの memory ディレクトリを共有しますが、git clone は別のリポジトリなので <project> の名前が変わります。私は並列実行のために clone(multi_clones/)を使っているので、memory ディレクトリが 2 つあります。第 1 部 第 7 回の「並列実行するセッションが共有するメモリ」は worktree の話で、clone では逆に「共有されない」が問題になります。hook で元リポジトリの索引を流し、監査の glob を projects/*/memory/ に広げているのは、この分断を手で埋めているからです。

第三に、手書きの memory は製品の 4 種の外にいます。 Write / Edit で書いた普通のファイルなので typemodified も付かず、上限超過の注意も返りません。製品の auto memory に戻すなら、索引の上限・modified・保存を促す機構が製品側から付いてきて、本編の hook 群のいくつかは要らなくなるか、二重になります。

本編を読んで「メモリの索引」を置いた読者の多くは、製品の auto memory を使っているはずです。その場合、本編の第 1 部 第 2 回と第 7 回の仕組みは、hook の経路を製品の機構に読み替えて使ってください。索引の上限は 200 行 / 25KB、保存の瞬間に走る hook は PostToolUseWrite|Edit(auto memory も同じツールで書きます)、差分の監査先は ~/.claude/projects/<project>/memory/ です。

D.5 スキル —— 一覧は開始時、本文は呼ばれたとき

スキルは <場所>/skills/<name>/SKILL.md の形で置きます。ディレクトリと SKILL.md が要り、skills/ 直下の .md はスキルではありません。

場所パス名前が衝突したとき
Enterprisemanaged settings のディレクトリ最優先
Personal~/.claude/skills/<name>/SKILL.mdproject より優先
Project.claude/skills/<name>/SKILL.md最下位。ただし bundled skill は上書きできる(alias は不可)
Plugin<plugin>/skills/<name>/SKILL.mdplugin:name の名前空間なので衝突しない
下位ディレクトリpkg/.claude/skills/<name>/SKILL.mdpkg:name で両方残る。そのディレクトリのファイルを読んだときに載る
.claude/commands/*.md同じ名前なら skill が勝つfrontmatter の namepaths は無視される

開始時に載るのは、名前と description

セッションの開始時に載るのは、全スキルの名前と、description(と when_to_useです。数字は 2 つ。

  • 1 件 1,536 字。 description + when_to_use の合計で切られます。先頭が残るので、使う場面を先に書け、が公式の指針です。skillListingMaxDescChars で変えられます
  • 一覧全体はコンテキストの 1%。 200K の窓なら約 2,000 トークン。溢れると呼ばれた回数の少ないスキルから description が落ち、名前だけになります。skillListingBudgetFraction0.02 = 2%)か SLASH_COMMAND_TOOL_CHAR_BUDGET(固定の文字数)で増やせ、skillOverrides"name-only" / "off" にして予算を空けられます。/context の Skills 行は予算適用後の量(v2.1.196 以降)

frontmatter の 2 つの欄が、この一覧に載るかどうかを決めます。

frontmatterあなたが呼べるAI が呼べるいつ載るか
既定はいはいdescription は常に。本文は呼ばれたとき
disable-model-invocation: trueはいいいえdescription も載らない。 本文はあなたが /name を打ったとき。サブエージェントへの preload も、scheduled task からの起動もされない
user-invocable: falseいいえはいdescription は常に。本文は AI が呼んだとき

AI が disable-model-invocation: true のスキルを呼ぼうとすると、Claude Code は呼び出しを止め、別の方法で同じ手順を再現しないよう指示します。第 1 部 第 4 回が「選ばせるのではなく、使う前に読ませる」と書いたのは、この欄で「AI が選ぶ経路」を切り、hook で「間違った入り方をしたときだけ案内する」に置き換えた形です。description を書かない = 一覧に載せない = 予算を食わない、が本編の 84 本 / 1 個の内訳です。

本文は 1 メッセージとして入り、読み直されない

呼ばれると、SKILL.md の本文がレンダリングされて 1 つのメッセージとして会話に入り、以後のターンでもそこに残ります。レンダリングは $ARGUMENTS / $0 / ${CLAUDE_SKILL_DIR} などの置換と、!`command` の実行(AI に送る前に走り、出力が置き換わる。2 分の timeout。disableSkillShellExecution で無効化できる)です。

  • Claude Code は以後のターンで SKILL.md を読み直しません。 一度きりの手順ではなく、作業の間じゅう効く常設の指示として書け、が公式の指針です
  • 同じスキルをもう一度呼んで、レンダリング結果が同一なら「もう載っている」の短い注記だけ、違えば(引数が変わった、動的コマンドの出力が変わった)全文がもう一度入ります
  • allowed-tools の許可はその呼び出しのターンだけで、次にあなたが何か打つと消えます。本文の指示は残り、権限は残らない、という非対称です
  • 圧縮後は直近の呼び出しが先頭 5,000 トークンまで、全スキル合計 25,000 トークンまで再注入されます。新しく呼んだものから埋め、古いものは丸ごと落ちます。一覧(名前と description)は再注入されません(付録 B.3)
  • SKILL.md の本文の編集は、~/.claude/skills/ / .claude/skills/ / --add-dir.claude/skills/ で監視され、再起動無しに反映されます。ただし反映されるのは「次に呼ばれたときのレンダリング」で、既に会話に入っている本文は変わりません。起動時に無かった最上位の skills/ ディレクトリは、作ってから再起動が要ります。--add-dir で足したディレクトリの中の .claude/commands/.claude/agents/ は監視されません(プロジェクトと ~/.claude/agents/ は監視されます。付録 E.8)

context: fork —— 本文が task prompt になる

context: fork を付けると、スキルの本文はサブエージェントへの task promptになります。会話の履歴は渡りません。agentExplore / Plan / general-purpose(既定)/ .claude/agents/ の自前のものを選べ、ExplorePlan は CLAUDE.md と git status を読みません(付録 E)。既定は background で、background: false(v2.1.218 以降)にするとそのターンで待ちます。-p と Agent SDK では常に待ちます。

「スキル本文 = system prompt に足される」と誤解されがちなので、線を引いておきます。通常のスキル本文は会話層の 1 メッセージ(付録 A.4 の表)で、fork のスキル本文はサブエージェントの task promptで、どちらも system prompt ではありません。起動時のコンテキストに最初から入るのは、サブエージェントの skills: 欄で preload した本文だけです(付録 E)。

手元の実測

観測(2026-09-05)
プロジェクトのスキル1 個(screenshot)。description 226 字
~/.claude/skills/measure-*.md が 6 本、直下に置かれている<name>/SKILL.md の形ではないので読まれていない。このセッションの一覧に無い
一覧に載っている bundled skill17 個(code-review / simplify / loop / run など)
disable-model-invocation使っていない。screenshot は AI が選べる

~/.claude/skills/ 直下の 6 本は、旧い形式のカスタムコマンドを置き場所だけ移したもので、少なくとも今の版では載っていません(ファイルの日付は 2026-02)。第 1 部 第 4 回の「登録した数より使われた数がずっと少ない」の一部は、そもそも登録できていなかった数です。数えるときは /context か、AI に「使えるスキルを名前だけ列挙して」と頼んで、ファイル数と突き合わせてください(D.11 の検証 5)。

D.6 リポジトリの現物が前例として効く

第 3 部 第 4 回は、「計画書を書け」の指示が 0 件でも AI が計画書を書き、根拠として同じ体裁の計画書 200 本を挙げたことを、サブエージェント 2 体で測りました。この章で引き受けるのは、その挙動の機構です。測り方は付録 E に譲ります。

現物が届く部分は、指示ファイルより後ろです。AI が着手の前に docs/plan/ を Glob し、数本を Read すると、その本文は tool_result として会話層に積まれます(付録 A.4)。この時点で AI の入力には、①開始時の CLAUDE.md(「docs/plan/ - 機能計画」の 1 行)と、②直近に読んだ計画書の全文が並んでいます。②のほうが新しく、量も桁違いに多く、しかも形が揃っています## 0. 先に結論、判断待ちの表、記録の節)。同じ形の実例が数本並ぶと、次に書くものの形はそれに引きずられます。指示ファイルの 1 行は「そこに置け」しか言わず、実例は「こう書け」を言っています。

なぜ実例のほうが強いかは、2 つに分けて考えます。

  • 部分と鮮度。 同じ user メッセージ層でも、開始時に 1 度届いた指示ファイルより、直前のターンで届いた tool_result のほうが近くにいます。付録 A.4 と I が扱う「最新のターンが優先される」性質と同じ向きです
  • 文脈内学習。 揃った形の実例が並ぶと、モデルは次も同じ形で書きます。「1 本目が 2 本目を呼ぶ」という第 3 部 第 4 回の言い方は、この性質の観察です。出典は付録 I に置きます(帰属は人が検証)

Claude Code の plan mode は、これとは別の機構です。 plan mode は permission mode の 1 つで(Shift+Tab / /plan / --permission-mode plan / settings の defaultMode: plan)、AI はファイルを読み、探索のコマンドを走らせ、計画をファイルに書き、承認されるまで編集は止まります。この計画ファイルは圧縮後に disk から再注入されます(付録 B.3 の表)。EnterPlanMode / ExitPlanMode はツールで、AI が自分で plan mode に入ることもできます。私の計画書 200 本は、plan mode の計画ファイルではなく docs/plan/ にコミットされた Markdown で、圧縮後に戻るのは「直近 5 ファイル」に入っていたときだけです。第 3 部 第 4 回の「計画書」は、製品の plan mode を使っていません。 使っているなら、その計画は ~/.claude/ の側に書かれ、リポジトリの現物にはならず、次のセッションの前例にもなりません。前例として効かせたいなら、リポジトリに置く、が結論です。

もう一つ、現物は悪い体裁も複製します。2 本目が 1 本目を呼ぶなら、1 本目の癖は 200 本に広がります。第 3 部 第 4 回の 538 箇所の「ユーザー確定」は、私が書いた判断の痕跡ですが、計画書の形式の側に私が意図していない癖が混ざっていても、同じ強さで複製されます。前例の drift を見る自動テストは持っていません。持つなら、付録 F の「走査 + 下限」で、計画書の見出しの型を数える形になります。

D.7 索引と本文 —— on-demand の引き金

第 2 部 第 1 回の測定を、この章の言葉で言い直します。AI は MEMORY.md の索引(①の部分)を持って起動し、13 体の起動(transcript の 631〜990 行目)の間、止めるはずだった memo の本文(②の部分)を一度も Read しなかった。本文の語が初めて出るのは 1042 行目、索引にあるファイル名は起動前に 15 回出ていた。名前は届いていて、引き金は引かれなかった。

②の部分に入るものの引き金を、機械が引くか、モデルが引くかで分けます。

②に入るもの引き金誰が引くか
paths 付きルールRead の対象パスが glob に一致機械
下位ディレクトリの CLAUDE.mdそのディレクトリのファイルを Read機械(Read 自体はモデルの判断)
下位ディレクトリのスキル同上機械(載るのは一覧まで。本文は下の行)
スキルの本文/name を打つ、または AI が Skill ツールを呼ぶあなた、またはモデル
メモリの本文(topic file)AI が Read するモデル
リポジトリの現物AI が Read / Grep / Glob するモデル
計画ファイル(plan mode)AI が書くモデル

機械が引く行は、条件が決まっていて再現します。モデルが引く行は「開くほどの用事がある」という関連性の判断で、公式ドキュメントは "Claude reads them on demand using its standard file tools when it needs the information" とだけ書きます。判断の中身は公開されておらず、手元で観測できるのは transcript の tool_use の順序だけです(D.11 の検証 8)。

この構造で、本編の 3 つの回が同じ形になります。

  • 第 2 部 第 1 回「却下の一覧」: 散らばった memo は「開くほどの用事」に見えない大きさなので、1 箇所に集めて、索引の 1 行が「相談の語」と意味的に一致するようにした。引き金をモデルが引きやすくする設計
  • 第 1 部 第 2 回「保存の直前にだけ読ませる」: チェックリストは②の部分に置き、CLAUDE.md の 1 行(①の部分)が「保存の前に Read せよ」と引き金の条件を書く。条件が明示された on-demand
  • 第 1 部 第 4 回「使う前に読ませる」: スキルの description(①)を置かず、hook が止めた瞬間の案内文(tool_result の隣)で読むべき 1 枚を名指しする。引き金を hook が引く

公式ドキュメントはこの設計を "progressive disclosure" と呼び、スキルの本文・topic file・下位の CLAUDE.md・paths 付きルールを全部この形で作っています。名前を①に、本文を②に。本編がやったのは、製品が用意した 2 段階の構造に、自分の memo と却下の一覧と道具を同じ形で載せ直したことです。

D.8 途中で編集しても効かない理由

セッションの途中で CLAUDE.md を直しても、そのセッションの AI には届きません。理由は 3 つの部分で違います。

直したもの効く時点なぜ
CLAUDE.md / paths 無しルール圧縮の直後load_reason: compact)か、次のセッション①の一式は開始時に 1 度作られ、ターンごとに読み直されない。読み直せば prefix cache が壊れる(付録 B.4)
MEMORY.md(製品の auto memory)同上同上
MEMORY.md(hook で流している場合)次のターンUserPromptSubmit は毎ターン走り、その stdout は会話層に足される。cache は壊れず、読む量は増える
SKILL.md の本文次に呼ばれたとき監視されて再レンダリングされるが、既に会話にある本文は残る
SKILL.md の description次のセッション一覧は①の一式(圧縮後も再注入されない)
paths 付きルール / 下位 CLAUDE.md次に一致するファイルを読んだとき引き金のたびに disk から読む
.claude/settings.json の hookv2.1.260 では ConfigChange イベントが走る付録 C

第 1 部 序論の「ルールを足しても守られない」の一部は、この表で説明が付きます。会話の途中で CLAUDE.md に 1 行足して「守られない」と判断していたなら、その 1 行はまだ届いていません。届くのは圧縮の後か次のセッションで、そこで初めて「薄まる」の側の話になります。本編の測定(第 1 部 第 6 回の probe、第 2 部 第 1 回の transcript)が別起動のサブエージェントで行われているのは、自セッションが古い①の一式を持っているからです(付録 E)。

私の hook の経路が「次のターン」で効くのは、便利さと引き換えに、毎ターン索引の分だけ読む量を増やしているからです(第 1 部 序論の「約 26KB がコンテキストに入る」はこの経路の話で、今の版では 10,000 字で切られます。D.4)。製品の auto memory は開始時に 1 度で、圧縮まで固定です。どちらが良いかではなく、「途中で直したメモが次のターンに効く」のは hook の性質で、製品の索引は効かない、と知っておいてください。

D.9 本編との対応

本編読み込み時点の側から言い直すと
第 1 部 序論・第 6 回「足すほど薄まる」「文脈であって強制ではない」①の一式は同じ 1 通の user メッセージ。system prompt ではなく、hook と自動テストの外にいる
第 1 部 第 2 回・第 7 回「索引 1 枚」「保存の直前にだけ読ませる」索引は①(200 行 / 25KB か hook の 10,000 字)、本文とチェックリストは②。手元は製品の auto memory ではなく hook の経路
第 1 部 第 4 回「スキルを使わない」description を書かない = ①に載せない。disable-model-invocation が同じ効果を欄で持つ
第 2 部 第 1・8 回「一覧」「3 つの階層」一覧は②で、索引の 1 行が引き金。階層の件数は①に載る行数の話ではなく、②に置かれた本文の件数
第 3 部 第 4 回「計画書 200 本」現物は②の tool_result で、①の 1 行より新しく多い。plan mode の計画ファイルとは別物

D.10 本編が言っていない注意

索引の上限は、経路で違います。 製品の auto memory は 200 行 / 25KB、hook の平文 stdout は 10,000 字。私の索引は後者の経路で 2KB しか届いていませんでした(D.4、付録 C.11)。第 1 部 序論の「約 26KB がコンテキストに入る」は 2026-08 時点の観測で、2.1.260 では同じ hook が 10,000 字で切ります。本編の数字を再現しようとして届かなくても、それは hook の上限です。

clone は memory を共有せず、worktree は共有します。 <project> は git リポジトリから導かれます。並列実行に clone を使うと memory ディレクトリが分かれ、worktree を使うと同じディレクトリに複数セッションが書きます。第 1 部 第 7 回の並列実行の競合は worktree の側、私の手元の「hook で元の索引を流す」は clone の側の対処です。どちらを使っているかを先に確かめてください(ls ~/.claude/projects/)。

手書きの memory は、製品の 4 種の外にいます。 typemodified も付かず、上限超過のエラーも保存の注意も返りません。製品の機構を使いたいなら autoMemoryEnabled を戻す。使わないなら、本編の hook 群がその代わりです。両方を同時に動かすと、索引が 2 回載ります。

skills/ 直下の .md は読まれません。 <name>/SKILL.md の形だけがスキルです。旧 .claude/commands/*.md は動きますが、~/.claude/skills/*.md は動きません。私の 6 本がそれでした。

bundled skill が一覧の予算を食います。 私の一覧はプロジェクトのスキル 1 個に対して bundled が 17 個で、description の予算 1% の大半は製品側が使っています。disableBundledSkills/doctor を除く。v2.1.205 以降)か skillOverrides"off" にできます。第 1 部 第 4 回の「登録は 1 個」は自前の話で、一覧そのものは 18 個です。

paths 付きルールと下位 CLAUDE.md は、圧縮で消えます。 戻るのは直近 5 ファイルに紐づく分だけです。「毎セッション必ず」の指示を paths 付きで書くと、長いセッションの後半で消えます。

@import で分割しても、読む量は減りません。 起動時に展開されて①の一式に入ります。減らしたいなら paths 付きルールかスキルへ移す、が公式の指針です。参照先が作業ディレクトリの外にあると承認ダイアログが出て、断ると以後は黙って無効です。/context で確かめてください。

HTML コメントは、AI に届かず、Read すれば見えます。 「指示ファイルにこう書いてある」と AI に言わせる検証で、AI が Read してからコメントの文を引いてきたなら、それは届いた指示ではなく読んだファイルです。

--add-dir の CLAUDE.md は既定で読まれません。 環境変数 CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 が要ります。

前例は悪い体裁も複製します。 第 3 部 第 4 回の波及です。1 本目の癖は 200 本に広がり、直すなら 200 本を直します。採番の競合(並列実行する作業場所が同じ番号を取る)は付録 G。

バージョン依存。 上の挙動は 2026-09-05 に Claude Code 2.1.260 のドキュメントと手元で確認したものです。modified は v2.1.214、paths のブレース予算は v2.1.217、[ の扱いは v2.1.207、symlink 経由の一致は v2.1.198、claudeMdExcludes の symlink は v2.1.239、/context の Skills 行の数え方は v2.1.196、CLAUDE_CODE_PROJECT_DIR_NAME は v2.1.234、background: false は v2.1.218 です。1,536 字、1%、200 行、25KB、4 MiB、4 段階、5,000 / 25,000 トークン、直近 5 ファイルは、どれも版で変わりうる値です。

D.11 検証手順

本編と同じ型です。止まるべきものが止まり、通るべきものが通ることを、両方向で見ます。マーカーは MARKER_ で始まる語にして、AI に「ファイルを開かずに、見えている MARKER_ の語を全部書き出して」と頼みます。AI が Read してから答えたら、その検証は無効です(D.10 の HTML コメントの注意)。transcript の tool_use で Read が無いことを確かめてください。

1. 何がいつ載ったかを、hook で記録する。 InstructionsLoaded は CLAUDE.md と .claude/rules/*.md の読み込みごとに走り、load_reason を持ちます。止められない観測専用のイベントです(付録 C)。

mkdir -p .claude/hooks tmp
cat > .claude/hooks/log_instructions_loaded.sh <<'EOF'
#!/bin/bash
python3 -c '
import json, sys, datetime
d = json.load(sys.stdin)
row = {k: d.get(k) for k in ("load_reason", "memory_type", "file_path", "trigger_file_path", "parent_file_path", "globs")}
row["at"] = datetime.datetime.now().isoformat(timespec="seconds")
print(json.dumps(row, ensure_ascii=False))
' >> "${CLAUDE_PROJECT_DIR:-.}/tmp/instructions_loaded.jsonl"
exit 0
EOF
chmod +x .claude/hooks/log_instructions_loaded.sh

.claude/settings.jsonhooks に足します(既に hooks があれば、その中に InstructionsLoaded の鍵を足す)。

{
  "hooks": {
    "InstructionsLoaded": [
      { "hooks": [ { "type": "command", "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/log_instructions_loaded.sh" } ] }
    ]
  }
}

新しいセッションを起動すると load_reason: "session_start" の行が、①の一式に入ったファイルの数だけ並びます。~/.claude/CLAUDE.mdmemory_type: "User")、./CLAUDE.md"Project")、CLAUDE.local.md"Local")の順を見てください。次に、CLAUDE.md を持つ下位ディレクトリを作り、AI にそこのファイルを 1 つ読ませると "nested_traversal"trigger_file_path が出ます。paths 付きルールを置いて一致するファイルを読ませると "path_glob_match"globs@import を 1 つ足すと "include"parent_file_path。最後に /compact を打つと "compact" の行が、session_start と同じファイルの数だけ出ます。この hook は MEMORY.md とスキルの一覧には走りません。出なければ正常です。

2. HTML コメントは届かない。 CLAUDE.md の末尾に 2 行足します。

MARKER_PLAIN_7f3a
<!-- MARKER_HTML_7f3a -->

新しいセッションで「ファイルを開かずに、指示ファイルの MARKER_ の語を書き出して」。MARKER_PLAIN_7f3a は出て、MARKER_HTML_7f3a は出ません。次に「CLAUDE.md を Read して同じことを」。両方出ます。同じ行が「届く / 届かない」と「見える」に分かれることを、一度は目で見ておく手順です。コードブロックの中に <!-- MARKER_CODE_7f3a --> を置くと、こちらは届きます。

3. @import は 4 段階まで。 6 本を鎖にします。

for i in 1 2 3 4 5 6; do
  n=$((i+1))
  printf 'MARKER_IMPORT_%d\n@docs/probe_import_%d.md\n' "$i" "$n" > "docs/probe_import_$i.md"
done
echo '@docs/probe_import_1.md' >> CLAUDE.md

新しいセッションで MARKER_IMPORT_ の語を数えさせます。届いた最大の番号が、あなたの版の段数です(公式は 4 hops)。検証 1 の hook を入れておくと、"include" の行が届いた本数だけ出て、parent_file_path で鎖が追えます。終わったら probe_import_*.md と CLAUDE.md の 1 行を消します。

4. 索引の上限を、経路ごとに踏む。 製品の auto memory を使っている場合(autoMemoryEnabledfalse でない)は、MEMORY.md を退避してから 250 行の索引を置きます。

M=~/.claude/projects/$(ls ~/.claude/projects/ | grep "$(basename "$(git rev-parse --show-toplevel)")" | head -1)/memory
cp "$M/MEMORY.md" "$M/MEMORY.md.bak"
for i in $(seq -w 1 250); do echo "- MARKER_LINE_$i probe"; done > "$M/MEMORY.md"

新しいセッションで「ファイルを開かずに、メモリの索引で見えている MARKER_LINE_ の最大の番号は」。200 です。次に AI に「索引の末尾に 1 行足して」と頼むと、書き込みは成功したうえで over its ... read limit のエラーが返ります。エラーが返らなければ、あなたの版は上限超過を通知していません。戻すのは mv "$M/MEMORY.md.bak" "$M/MEMORY.md"

hook で流している構成なら、上限は 10,000 字です。付録 C.12 の 3(先頭と末尾に目印を持つ 12,000 字を流す)で踏めます。透過的に読ませたいなら、索引を 10,000 字の内側に保つか、hook が head -c 9000 で切って末尾に「続きは Read せよ」の 1 行を足す形にします。

5. スキルの description の 1,536 字と、一覧に載らない欄。 2,000 字の description を持つスキルを置きます。

mkdir -p .claude/skills/probe-desc
python3 - <<'EOF'
body = "MARKER_DESC_HEAD " + ("probe " * 330) + "MARKER_DESC_TAIL"
open(".claude/skills/probe-desc/SKILL.md", "w").write(
    f"---\nname: probe-desc\ndescription: {body}\n---\nMARKER_BODY_V1\n")
print(len(body))
EOF

新しいセッションで「ファイルを開かずに、probe-desc の description にある MARKER_ の語を書き出して」。MARKER_DESC_HEAD は出て、MARKER_DESC_TAIL は出ません(切られるのは末尾)。MARKER_BODY_V1 も出ません(本文は呼ばれるまで載らない)。次に frontmatter に disable-model-invocation: true を足して新しいセッションを起動し、「使えるスキルを名前だけ列挙して」。probe-desc は無く、/probe-desc を打つと MARKER_BODY_V1 が届きます。逆向きに、user-invocable: false にすると /probe-desc は効かず、AI に「probe-desc を使って」と頼むと本文が届きます。

同じ手順で、あなたの ~/.claude/skills/ にディレクトリでない .md があれば、それが列挙に出ないことを見ます。私の 6 本は出ませんでした。

6. 本文は読み直されない。 検証 5 のスキルを /probe-desc で呼んだ後、同じセッションのまま本文を MARKER_BODY_V2 に書き換え、「見えている MARKER_BODY_ の語は」。V1 です。もう一度 /probe-desc を打つと、レンダリング結果が変わったので全文が入り直し、V2 が届きます。書き換えずに 2 回目を打つと「already loaded」の注記だけで本文は 2 度入りません。transcript の user 行の文字数で確かめられます。

7. 途中の編集は圧縮まで届かない。 セッションを起動してから、CLAUDE.md に MARKER_MID_7f3a の 1 行を足します。「ファイルを開かずに MARKER_MID_ は見えるか」。見えません。/compact を打ってから同じ問い。見えます。検証 1 の hook があれば、"compact" の行がその瞬間に出ています。逆向きに、hook で流している MEMORY.mdMARKER_MEM_7f3a を足すと、次のターンで見えます。同じ「途中の編集」でも、経路で効く時点が違うことを、1 つのセッションの中で見ておく手順です。

8. 索引と本文の引き金を、transcript で数える。 第 2 部 第 1 回の測定を、あなたの transcript で再現します。索引にあるファイル名が「見えていた」行と、本文を Read した行の番号を並べます。

python3 - "$(ls -t ~/.claude/projects/*/*.jsonl | head -1)" feedback_ <<'EOF'
import json, sys
path, prefix = sys.argv[1], sys.argv[2]
seen, read = [], []
for n, line in enumerate(open(path), 1):
    try: d = json.loads(line)
    except json.JSONDecodeError: continue
    s = json.dumps(d, ensure_ascii=False)
    if prefix in s: seen.append(n)
    for c in (d.get("message") or {}).get("content") or []:
        if isinstance(c, dict) and c.get("type") == "tool_use" and c.get("name") == "Read":
            if prefix in (c.get("input") or {}).get("file_path", ""): read.append(n)
print(f"name seen at lines: {seen[:10]}{' ...' if len(seen) > 10 else ''} ({len(seen)} times)")
print(f"body Read at lines: {read or 'never'}")
EOF

第 2 引数は索引に載っているファイル名の一部です。name seen が何度も出て body Readnever なら、そのセッションで本文は一度も開かれていません。逆に Read の行があれば、その直前の user 行に何があったか(相談の語、hook の案内文、CLAUDE.md の 1 行)が、引き金です。

9. worktree は共有し、clone は共有しない。 MEMORY.mdMARKER_SHARE_7f3a の 1 行を足してから、2 つの作業場所を作ります。

git worktree add ../probe-wt -b probe-wt
git clone . ../probe-clone

../probe-wt で起動して「メモリの索引に MARKER_SHARE_ はあるか」。あります。../probe-clone で起動して同じ問い。ありません(ls ~/.claude/projects/ に新しいディレクトリが増えています)。hook で索引を流している構成なら、hook の cat のパスが固定なので clone でも「あります」になります。それが私の手元です。終わったら git worktree remove ../probe-wt && git branch -D probe-wt && rm -rf ../probe-clone と、増えた ~/.claude/projects/ のディレクトリを消します。

D.12 出典(2026-09-05 確認)

  • How Claude remembers your project —— CLAUDE.md の 4 つの範囲と連結順、下位ディレクトリの遅延読み込み、200 行の目安、4 MiB、HTML コメントの除去、@import の 4 段階と外部参照の承認、.claude/rules/paths の予算(1,000 パターン / 4 MiB)、claudeMdExcludes--add-dir の環境変数、auto memory の 4 種・置き場所・200 行 / 25KB・書き込み時の注意とエラー・modified・サブエージェントに載らないこと、「user メッセージとして届く」の一文、/compact 後の再読
  • Explore the context window —— 起動時に載るものの内訳、What survives compaction の表(CLAUDE.md・auto memory・plan file は disk から再注入、paths 付きルールと下位 CLAUDE.md は直近 5 ファイルに紐づく分だけ、スキル本文 5,000 / 25,000、スキル一覧は再注入されない、5,000 トークン超のファイルはパス参照)
  • Extend Claude Code —— 機能ごとの「いつ載るか・何が載るか・コスト」の表、CLAUDE.md / rules / skill の比較、disable-model-invocationskillOverrides の位置づけ、settings の置き場所ごとの上書き規則(skill は managed > user > project)
  • Skills —— 置き場所と優先順、下位ディレクトリのスキル、frontmatter の全欄、1,536 字、一覧の予算 1% と落ちる順、skillListingBudgetFraction / SLASH_COMMAND_TOOL_CHAR_BUDGET / skillListingMaxDescChars、本文が 1 メッセージとして入り読み直されないこと、同一なら注記だけ、allowed-tools の寿命、圧縮後の再注入、context: fork!`command`、監視と再起動の条件
  • Subagents —— サブエージェントに載るもの(CLAUDE.md の全階層、auto memory は載らない、fork の例外)、memory 欄と system prompt に入る 200 行 / 25KB、disable-model-invocation のスキルは preload できないこと
  • Hooks reference —— InstructionsLoaded の入力欄(file_path / memory_type / load_reason / globs / trigger_file_path / parent_file_path)と load_reason の 5 値、決定制御が無いこと、hook 出力の 10,000 字の上限
  • Monorepos and large repos —— 起動ディレクトリで変わる読み込み、per-directory CLAUDE.md と paths 付きルールの比較表、additionalDirectories--add-dir の違い、下位のスキル、plan file が圧縮後に再注入されること
  • Choose a permission mode —— plan mode の入り方と承認の流れ、defaultMode: plan
  • Errors —— this write left the memory index at MEMORY.md at ..., over its ... read limit
  • 手元の実測 —— autoMemoryEnabled: false の構成で、索引を hook で流す経路の上限(D.4)、~/.claude/skills/*.md が一覧に出ないこと、bundled skill の数(2026-09-05)