メインコンテンツまでスキップ

なぜゼロから組み直したのか

この連載が記述する時点

本連載は執筆時点のハーネス実環境 (設定ファイルの内容、実行記録、ファイル数) を素材にした記録です。ハーネス本体は公開後も改修が続いているため、引用したファイル内容や個数、手順は現在の実体と異なる場合があります。本連載の主眼は個々の値ではなく設計の考え方 (5 関心分離、検証ゲート、成長規律) にあります。

本章は、本連載の出発点である「なぜゼロから組み直したのか」を扱います。

再構築前、~/.claude/ は 1 年ほどかけて積み上がった、数百ファイル規模の構成でした。表面上はそれなりに動いていましたが、内側では明確に「飽和」していました。本章では、その時の症状を 4 つに整理し、なぜ部分修正でなくゼロ再構築を選んだのか、再構築にあたって決めた 4 つの設計判断を順に紹介します。

1.1. 出発点: 再構築前の構成

再構築前の ~/.claude/ は、rules/ skills/ agents/ hooks/ に加えて references/ (Anthropic 公式 doc 抜粋や業界記事のローカル保存) teams/ scripts/ commands/ learnings/ など、性質の異なるディレクトリが並存する構成でした。

内訳を見ると learnings/references/ の中身が大きな割合を占めていましたが、それらだけが膨張の原因だったわけではなく、rules / skills / agents の本体にも同じように累積がありました。

再構築前のハーネスは、見出しだけ並べると以下のような形でした。

  • CLAUDE.md: 長大なハブ。索引と規範が混在
  • rules/: git-workflow.md / commit-policy.md / verification.md / fact-check.md / interaction.md / unverified-claims.md / mcp-loading.md など、数十ファイル規模
  • skills/: /spec-design / /grill-me / /autodev / /code-review / /verify / /learn / /record-learnings / /init-repo など、こちらも数十個規模
  • agents/: architect / code-reviewer / implementer / test-strategist / auditor / ux-reviewer / general-purpose-helper など一通り揃った顔ぶれ
  • hooks/: check-suppression.sh / check-protected-files.sh 程度で、他のディレクトリと比べてアンバランスに薄い
  • references/: Anthropic 公式 doc 抜粋 / Pricing 表 / Claude Code 仕様メモ / 業界記事のローカル保存が多数

外形的にはそれらしく揃っていますが、運用していた本人の体感としては「全体像を頭の中に保持できない」「同じ規範が複数の場所に散っている」「subagent を spawn した瞬間にいくつかの規範が消える」という不協和音が常時鳴っていました。

1.2. 観測された 4 つの症状

本節は、その時に並走していた 4 つの症状を、それぞれ実例付きで整理します。

症状 1: 追加が容易・削除が困難という非対称性

最も根の深い症状はこれでした。

ハーネスを運用していて何か失敗が観測されると、典型的な対応は次のようになります。

  • git commit を勝手に実行しないでほしい」と人間 (筆者) が伝える
  • rules/git-workflow.md に「明示トリガー語が出るまで commit しない」と 1 行追記する
  • それでも何度か違反が再発する
  • 別の rule (rules/safety-gate.md のようなもの) に同じ趣旨をもう 1 行書き足す
  • さらに skills/commit/SKILL.md の手順にも「commit 前に確認を取る」と追加する

追加は失敗の都度発生するので、自然に蓄積していきます。1 つの規範を 1 ファイルに収める判断基準が曖昧なため、似た規範を複数の facet に書き分けてしまう体質ができていきます。

削除側を見るとさらに困った状況でした。

  • ある rule が本当に効いているかは、消してみないと分からない
  • 「もしかしたら他の場所で参照されているかも」「削除して再発したらどうしよう」という不安が default
  • 結果として「念のため残す」が常に勝つ
  • 30 日参照ゼロでも、半年前に追加した rule でも、消す動機が無い

入口に摩擦が無く、出口に引力も無いので、ファイル数は単調増加するしかない構造になっていました。数百ファイル規模まで膨らんだのは、1 年間この非対称性が走り続けた結果です。

症状 2: 同種の指示が複数 facet に散在

症状 1 の累積の結果として、「同じことが 3-4 か所に書かれている」状態が当たり前になっていました。

例として「git commit は明示トリガー語が出るまで実行しない」という規範を取ると、再構築前は次の 4 箇所に書かれていました (実物は退避済み、当時の内容を要点だけ再現)。

  • CLAUDE.md 冒頭の「主要規範」section: 「commit / push は人間の明示指示時のみ実行」
  • rules/git-workflow.md: 「git commit 実行時は直近 user turn にトリガー語があるか確認」
  • rules/safety-gate.md: 「破壊的操作 (commit / push / 削除) は人間ゲートを通す」
  • skills/commit/SKILL.md: 「Step 0: 直近 user message にトリガー語があるか確認、無ければ AskUserQuestion」

書き手 (筆者) の頭の中では「微妙に観点が違うから別ファイル」「rules/git-workflow.md は git 操作全般、rules/safety-gate.md は破壊性、CLAUDE.md は要約、SKILL.md は手順」のような言い分けがありました。読み手 (= 走っている Claude 自身) の挙動は次のようになっていました。

  • 4 箇所のうちロードされた箇所だけが効く (常時ロードと on-demand Read が混在しているため probabilistic)
  • 4 箇所が微妙に文言が違うので、Claude がどれを base に判断しているかが分からない
  • 1 箇所だけ書き換えても、他 3 箇所の古い文言が引きずり続ける
  • 改修するたびに「全部見つけて全部修正する」コストが上がる

これは facet の境界が曖昧だったことが直接の原因でした。Persona / Policy / Instruction の境界が運用判断に任されていて、書き手が毎回「これは Policy か Instruction か」を決め直していたので、最初の置き場が場当たり的になりました。

症状 3: subagent に届かない context

3 つ目の症状は subagent に context が届かない問題でした。

Claude Code の subagent (= Agent tool で spawn する独立コンテキスト) は、起動した瞬間に main agent の context から切り離されます。具体的には、

  • main agent が CLAUDE.md / rules/ で持っていた規範は subagent には自動で渡らない
  • subagent には subagent 自身の system prompt (= agents/<name>.md の body) と claude settings 由来の path-scoped rule のみが届く
  • main agent が読んでいた per-repo CLAUDE.md (~/.claude/repos/<repo>/CLAUDE.md) も渡らない (これは workspace 外)

再構築前は subagent を 7 種類用意していて、それぞれが「自分用の規範」を agents/<name>.md 本体に書いていました。例えば agents/implementer.md には commit 規律と verification 規律が main agent の rules/ と別文言で書かれており、agents/code-reviewer.md には fact-check 規律の独自版があり、agents/auditor.md には evidence-based 監査の規律が…と、規範の重複が subagent ごとに繰り返される構造になっていました。

これは典型的な spawning 経路の context loss 問題で、本質的には Claude Code の仕様に由来します。ただし当時のハーネスでは、これを subagent ごとの規範をコピー という素朴な方法で対応していたため、

  • 同じ規範が main + subagent 7 種で 8 重に書かれることがある
  • 改修時に整合性を保つコストが指数的に上がる
  • subagent 種別が増えると更に倍々で増える
  • ファイル数増加と規範重複が正のフィードバックで走る

という二次的な問題を抱えていました。全体のかなりの割合が、この経路で増えていたものでした。

症状 4: silent drop

4 つ目は silent drop (静かな脱落) と呼ぶ症状でした。これはハーネスエンジニアリングの文脈で広く使われる用語で、LLM が指示の一部を確率的に読み逃すが、何ごともなかったように応答してしまう現象を指します。

これは特定の運用パターンで起きていました。再構築前のいくつかの SKILL.md には、次のような書き方がありました。

## 関連 skill との連携
本 skill は実行時に以下を Read で読み込んで合成する:
- `~/.claude/skills/verify-loop/SKILL.md`
- `~/.claude/skills/spec-design/SKILL.md`
- `~/.claude/rules/git-workflow.md`

設計意図は「他 SKILL や rules の本体を都度 Read することで、本 SKILL の責務を絞りつつ、必要な規範を全部届ける」というものでした。理論上は綺麗な合成戦略です。

実際に走らせると、次のようなことが起きていました。

  • Claude は SKILL を起動すると最初に SKILL.md 本文を読む
  • 「関連 skill との連携」section に列挙された Read 対象は、本文を読み終わるまで認識されない
  • 本文の解釈と並行して Read 列挙を確率的に省略する (context 窓圧迫 + 優先度判断)
  • 結果として、列挙された関連 skill の半分しか Read されない、ということがしばしば起きる
  • しかも Claude 自身は「何ごともなかったように」応答するので、人間側からは drop が見えない

これは Inferential Guide (= LLM に向けた指示) で書いた「他 SKILL を Read してね」が、確率的に効かない典型的な silent failure でした。Computational に強制する経路 (hook / settings) を持たない指示は、信頼性を構造で担保できないという、ハーネスエンジニアリングの本質的な教訓でした。

silent drop は規範重複 (症状 2) と subagent context loss (症状 3) の両方を悪化させる方向にも働きます。「他 SKILL を Read で繋ぐから本 SKILL では書かなくていい」という設計判断は、Read が走らなければ規範がそもそも届かないことになります。

4 症状の関係

ここまでの 4 症状は独立に発生していたのではなく、互いに増幅し合う関係でした。

症状 1 が累積の動力源で、症状 2 / 3 / 4 がそれを増幅していました。この規模まで膨らんだのは、この 4 症状のフィードバックループが 1 年間走り続けた帰結です。

1.3. 部分修正でなくゼロ再構築を選んだ理由

ここまでの症状をリストアップしただけなら、部分修正で対応する選択肢もありました。

  • 重複規範を 1 ファイルに集約する
  • 30 日参照ゼロの rule を月次で消す
  • silent drop している SKILL の Read 列挙を inline に展開する
  • subagent への規範注入経路を見直す

実際、5 月の中旬から下旬にかけて、こうした部分修正を試みていました。ただし数日試したところで、次のことに気づきました。

  • 部分修正は個別症状の対応で終わり、根である「facet 境界の曖昧さ」「合成戦略の未設計」には触れない
  • 改修ごとに肥大化した全体を棚卸しする手間がかかり、改修速度より追加速度が勝つ
  • 「どこに何があるか」の認知地図が回復しない (= 改修判断の前提が成立しない)
  • 一部だけ整理しても、整理されていない領域から新しい飽和が再発する

部分修正で根を抜くには、結局全体の facet 境界を引き直す必要がありました。境界を引き直す作業を肥大化した全体を抱えたままやるより、一度全部退避してから空のディレクトリで境界を引き直す方が、認知負荷も整合性のリスクも小さいという判断に至りました。

ある時点で、それまでの構成全体を退避し、空の ~/.claude/ から組み直しを始めました。これが本連載の起点です。

ゼロ再構築の前提

「全部消して空から書く」という判断は、相当な分量の retained knowledge を意図的に手放す決断です。実際には、退避先から個別ファイルを参照する経路は残しつつ、新ハーネスに何を残すかを能動的に選ぶ形にしました。残す側に挙証責任を置くプロセス (= 後述する反転承認の原型) は、この再構築期に生まれています。

1.4. 再構築の 4 つの設計判断

ゼロから書くにあたって、最初に決めた設計判断を 4 つ紹介します。

判断 1: 思想を 1 つに絞る

最初に決めたのは「5 つの関心で全てを分類し切る」ことでした。

何を Persona、何を Policy、何を Instruction、何を Knowledge、何を Output Contract にするか。この 5 つで全てを置き切れば、「迷ったらどこに置くか」のコストが消えます。

詳細は次章 (02. Faceted Prompting)で扱いますが、要点は次のとおりです。

  • Persona は (= 振る舞いの主体)
  • Policy は how (= 規範、こうあってほしい)
  • Instruction は what to do (= 手順)
  • Knowledge は what is (= 記述的知識)
  • Output Contract は what comes out (= 成果物テンプレート)

5 つに絞れば、「どれにも当てはまらない」場合は facet 化しなくていい、という消極判断もできます。再構築前は、置き場が無い指示でも「とりあえず rules/ か skills/ に入れる」運用だったため、本来 facet 化不要な指示まで膨張に寄与していました。

判断 2: 合成は明示的に設計する

2 つ目は「Claude Code に composer は無い」という前提から出発することでした。

再構築前のハーネスは、全 facet を Read で繋いで合成しようとしていました (症状 4 の silent drop の元)。これは「composer がある」という前提に立った設計でした。

新ハーネスでは、Composer が無い前提を直視して、次の 3 段の配信方式を分けます。

  • gating facet (ループ合否を左右する規範) → agent body に inline で deterministic に強制
  • Instruction (手順) → subagent には story.md / spawn prompt への合成・embed で届ける (main agent 自身は SKILL.md をそのまま読む)
  • Knowledge / 記述的 Policy → 索引からの参照 + on-demand Read (本文コピー禁止はこの層のみ)

詳細は第 4 章 (04. ディレクトリ構成と合成規約)で扱いますが、ここで重要なのは「合成は確率的経路 (Read) に任せず、重要度別に決定論経路を設計する」という方針転換です。

判断 3: 入口に摩擦・出口に引力

3 つ目は 非対称性を逆向きに付け替えることでした。

再構築前は「追加が容易、削除が困難」という非対称性で膨張しました。新ハーネスはこの非対称性を意図的に逆向きにします。

  • 入口 (= 追加): 人間 (筆者) 承認必須、サイズ上限、usage-driven (2 回手で出してから検討)
  • 出口 (= 削除): 月次 /harness-prune で 30 日参照ゼロ・サイズ超過・orphan hook・参照切れを検出し、反転承認 (残す理由を問う) で削除

反転承認は特に効きます。「これ消していい?」と問うと「念のため残す」が default になりますが、「これを残す理由は?」と問うと、挙証責任が残す側に移ります。「いつか使うかも」では残せない構造です。

詳細は第 7 章 (07. 成長規律と逆 ratchet)で扱います。

判断 4: subagent への規範注入を構造化する

4 つ目は subagent ごとに規範をコピー という素朴な経路を捨て、構造的に解決することでした。

具体的には:

  • subagent 到達必須の Policy (verification.md / git.md など) は paths: を持たせず常時ロードにする
  • per-repo 知識 (CLAUDE.md / CONTEXT.md / handoff) は orchestrator が spawn prompt に絶対パスで明示注入する (workspace root の外なので自動到達しない)
  • gating な出力契約 (VERDICT: PASS|FAIL) は agent body に inline + grep 経路で fail-closed 分岐する

これにより、subagent 種別が増えても規範の重複は増えない構造を持てます。詳細は第 5 章 (05. facet 詳解)第 6 章 (06. autodev フロー)で扱います。

1.5. ゼロ再構築が実際にたどった形

ここまでの 4 つの設計判断で組み直した結果、~/.claude/ の構成は大きく様変わりしました。重要なのは、これが「一度小さくして終わり」ではなかった点です。

ゼロ再構築は、まず全体を大きく圧縮する act でした。references/ teams/ scripts/ commands/ のような、性質が曖昧なまま溜まっていたディレクトリは廃止し、5 facet (rules/ skills/ agents/ に加えて新設した output-contracts/ knowledge/) だけに絞り込みました。CLAUDE.md 自体も、規範を混在させた索引から「索引と思想だけ」に絞り、大幅に短くなりました。

ただし、圧縮した直後の状態で運用を止めたわけではありません。bootstrap 後は、運用の中で「同じ指摘を手で 2 回出した」事象が立ち上がるたびに facet 化する規律 (= usage-driven 追加、第 7 章) に従って、rules / skills が必要な分だけ再び増えていきました。ゼロ再構築が意味を持つのは、「圧縮して終わり」ではなく「圧縮した後の成長が、圧縮前と同じ野放図さに戻らず、同じ規律の下で進んだかどうか」にあります。

hook だけは、bootstrap の早い段階から他の facet より先に増えました。これは「Inferential Guide (rule) で書いた規範のうち、本当に外せないものを Computational Sensor で deterministic に止める」という方針への切り替えの結果です。具体的には、コミットゲート (check-git-commit-gate.sh) や平文質問検出 (check-plain-question.sh) のように、確率的失敗が実害につながる規範を hook 化しました。Edit / Write / MultiEdit 前の未 Read を観測する log-only の Computational Sensor も、運用の中で後から追加されています。

output-contracts/ が新設されたのも今回の変化の象徴です。これは subagent の出力フォーマットをテンプレート化して、main agent が機械的に grep / parse できるようにする層で、後述する autodev フロー (検証ゲートループ) を成立させる土台になります。

1.6. 本章のまとめ

要点
  • 再構築前の数百ファイル規模の構成は、4 症状 (追加容易・削除困難 / 同種指示の複数 facet 散在 / subagent context loss / silent drop) の相互増幅で膨張した結果でした
  • 4 症状は独立でなく、フィードバックループを成していました。部分修正では根を抜けない構造でした
  • ゼロ再構築は、退避先から個別ファイルを参照する経路を残しつつ、残す側に挙証責任を置く能動選択として実施しました
  • 設計判断は 4 つ: (1) 5 関心で分類し切る (2) 合成を明示設計する (composer は無い前提) (3) 入口摩擦・出口引力 (4) subagent への規範注入を構造化
  • ゼロ再構築は「圧縮して終わり」ではなく、その後も usage-driven 追加で規律を保ったまま再成長するプロセスとして機能しました。hook だけは早期に他の facet より先行して増え、Inferential Guide を Computational Sensor で deterministic に止める方針への転換が反映されています

次章は、再構築の中心思想である Faceted Prompting (5 関心分離) を、各 facet の境界と振り分けルートに分けて掘り下げます。