なぜゼロから組み直したのか
本連載は執筆時点のハーネス実環境 (設定ファイルの内容、実行記録、ファイル数) を素材にした記録です。ハーネス本体は公開後も改修が続いているため、引用したファイル内容や個数、手順は現在の実体と異なる場合があります。本連載の主眼は個々の値ではなく設計の考え方 (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) とclaudesettings 由来の 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 の境界と振り分けルートに分けて掘り下げます。