アーキテクチャ深掘り
§1でL0→L1→L2の「何がどこからどこへ流れるか」を扱ったのに対し、この節ではその流れが実際にどのように実装されているかを掘り下げる — ファイルがそのままコピーされずに再生成される理由、継承フロントマターが解釈される順序、ボイラープレート・ティア戦略が実践でどのように適用されるかの具体例、そして2つのプラットフォーム(.claude/.gemini)が構造的にずれないよう保たれる方法までを扱う。
- L2ファイルがL1をそのままコピーせず「再生成」される理由(Layout Reconstruction)
extendsフロントマターが実際に解釈される順序- LOCKED/MERGE/PRESERVE分類を実際のファイルに適用した例
- 3ティア戦略 — High/Medium/Lowの定義、frontmatter例、Tier Adjustment Rules、Tier Ceiling Rule
.claude/・.gemini/のプラットフォームパリティが強制される仕組み- 実行計画テンプレート — Design Gate(Row 0)、例外カテゴリ(E1〜E5)、実践例
Layout Reconstruction — L2がL1をそのままコピーしない理由
§1で簡単に触れたagents/pm.mdの事例をもう少し掘り下げてみよう。L0のagents/pm.mdはワークスペース全体のガバナンスを含んでおり、300行を超える。ここにはAuto-Modeの動作やライフサイクル状態フィールドのような、ワークスペースルートでのみ意味を持つセクションが混在している。L1のtemplates/common/agents/pm.mdがこれをそのままコピーすると、variant(バリアント)を新規作成するたびにプロジェクトとは無関係なワークスペース専用の内容まで一緒についてきてしまう。
そのためL1はコピーの代わりにフィルタリングされた再構成を行う — L0の原本からvariantのスキャフォールディングに実際に必要なセクションだけを選び出し、ワークスペース専用セクションを除去したうえでextends参照によって残りをつなぐ。L2に降りる際も同じ原理が繰り返される。variant固有のオーバーライド(例えばco-retailであればマーケティングドメイン特化のPMルール)をL1の上に載せて最初から作り直すのであり、L1ファイルをdiff-patch方式で修正するわけではない。その結果、L0のpm.mdが300行を超えていても、L2のpm.mdは50〜100行程度に保たれる — 「コピーして余分を削る」方式ではなく「必要なものだけを選んで新たに作る」方式だからである。
この設計が重要な理由は失敗モードにある。もしL1→L2が単純なコピーだったなら、L0でワークスペース専用セクションを1つ追加するたびにすべてのL3プロジェクトのpm.mdが不必要に膨れ上がる。Layout Reconstructionは「L0が知っていること」と「L2が知る必要があること」の間に常にフィルターを置くことで、この問題を根本から遮断している。
extends フロントマター — 継承が解釈される順序
extends: ../../../agents/pm.mdのようなフロントマターフィールドは「このファイルはあのファイルを参照する」という宣言であり、ファイルを統合するマクロではない。解釈順序は次の通りである。
- ツールがファイルを読み込む際(例えばClaude Codeが
agents/pm.mdを読み込む際)、まずfrontmatterのextendsパスを確認する。 - 参照された原本(L0またはL1)を読み込んで本文を継承するが、現在のファイルに明示的に再記述されたセクションがあれば、そのセクションのみをオーバーライドする。
- 原本にはなく現在のファイルにのみ存在するセクション(例:variant固有のルール)はそのまま追加される。
つまりextendsは「継承+選択的オーバーライド+追加」の3段階で解釈されるのであり、2つのファイルをテキストとして繋ぎ合わせるものではない。この構造のおかげで、L1のtemplates/common/agents/pm.mdは実質的な内容をほとんど持たなくても(大部分はextendsでL0を指すのみ)有効なファイルとして機能し、L0で共通ルールが変更されればextendsを使うすべての下位ファイルが次回参照時に自動的に最新内容を反映する — ただし、これは「読み込み時に解釈される」ものであり、§1で扱った「ファイル同期(SYNC_IF_NEWER)」とは異なる仕組みである。extendsはツールがファイルを開く瞬間のリアルタイム参照であり、SYNC_IF_NEWERはupgrade-project.tsを実行して初めて更新される静的なファイルコピーである。両者は同じ「継承のように見える動作」をするが、更新タイミングが異なる点を混同してはならない。
ボイラープレート戦略の実例
§1で扱ったLOCKED/MERGE/PRESERVE分類が実際のファイルにどのように適用されるかを1つずつ例で確認してみよう。
- LOCKEDの例 —
.githooks/pre-commit:このファイルはシークレットスキャンやコミットメッセージ検証といったセキュリティゲートを実行する。プロジェクトごとにこの検証を変えてしまうと組織全体のセキュリティ基準がプロジェクトごとに異なってしまうため、upgrade-project.tsはローカルの修正有無にかかわらず、このファイルを常にL1最新版で上書きする。 - MERGEの例 —
CLAUDE.md:このファイルには<!-- WORKSPACE-MANAGED -->...<!-- /WORKSPACE-MANAGED -->で囲まれた区間(例:PMゲートウェイルール)と、その外側のプロジェクト固有ルール(例:「このプロジェクトは常に韓国語でコミットメッセージを書く」)が共存している。アップグレード時にはマーカーの内側だけがL1最新版に置き換えられ、マーカー外側の韓国語コミットルールはそのまま残る。 - PRESERVEの例 —
docs/context.md:このファイルはプロジェクトが何であるかを説明する文書であるため、L1は存在確認のみを行い、内容には一切関与しない。
3つの例を並べて見ると分類基準が明確になる — 変更されるとセキュリティ・ガバナンス事故につながるか(LOCKED)、組織ルールとプロジェクトの文脈が1つのファイル内で共存すべきか(MERGE)、プロジェクトのアイデンティティそのものか(PRESERVE)。この3つの問いを順に投げかけてみれば、この分類はほとんどすぐに判断できる。
3ティア戦略の深掘り — コスト最適化を実行時に適用する
第5章で紹介したtier割り当てはagents/*.mdのfrontmatterに静的に定義される。各エージェントファイルのtierフィールドはプラットフォームごとのモデルエイリアスに変換され、実行時に適用される。
frontmatter例
--- name: pm # pm, code-writer, automation-engineer ... tier: # プラットフォームごとのモデルエイリアス(実行時に変換される) claude: high # high = claude-opus-5-0 antigravity: high # high = gemini-3.1-pro ---
この変換はmodel: inheritの裏で自動的に行われるため、agents/*.mdを書く人は具体的なモデル名をまったく知らなくてよく、「この役割がどれほど重い判断を行うか」だけを気にすればよい。
ティアの定義とモデルマッピング
| ティア | 目的 | Claude系の例 | Antigravity系の例 |
|---|---|---|---|
| High | 複雑な推論、アーキテクチャ設計、計画立案 | claude-opus-5-0 | gemini-3.1-pro |
| Medium | コードレビュー、テスト、PRレビュー、品質ゲート | claude-sonnet-5-0 | gemini-3.7-flash |
| Low | 高速で反復的なコーディング、スクリプト保守 | claude-haiku-4-5 | gemini-3.7-flash |
この静的な割り当てが基準線(ベースライン)となるが、実際の実行時にはPMがTier Adjustment Rulesを適用して動的にコストを最適化する。基準線がhighのエージェント(architect、pm)は複雑な設計判断を下す必要があるため、最も強力なモデルが必要となる。一方automation-engineerはADR-0036に基づく定型化されたスクリプトを書く役割であるため、lowティアで十分である — 「重い判断」が必要かどうかだけを見ればよいためだ。
Tier Adjustment Rules — 実行時のコスト最適化
PMが実行計画を立てる際、基準線から外れるティア調整が可能である。ルールは単純だ。
- ダウングレードは許可される — PMは単純な作業の場合、エージェントのティアを基準線より下げることができる。例えば基準線がmediumのdocs-writerが「README.mdの誤字を1つ修正する」作業を受けた場合、lowに下げてコストを削減できる。
- アップグレードは禁止される — 逆に基準線より高いティアに上げることは常に禁止される。lowのautomation-engineerをhighに上げて複雑なアーキテクチャを設計させることはガバナンス違反である。
- 失敗時の復元 — ダウングレードした作業が失敗した場合、PMは必ず該当エージェントの基準線ティアを復元して再試行しなければならない。
このルールの核心は「エージェント役割の複雑度の上限は固定だが、下限は状況に応じて調整できる」という原則である。PMはコスト削減のためにlowに下げることができるが、その作業がlowの能力を超えれば直ちに基準線に戻る。コストへの影響は第4章 §2-A P-2の実習で体感的に確認できる。
Tier Ceiling Rule
AGENTS.mdのPhase Determinationテーブル(§3.5)は、各成果物タイプに許可されたティアの上限を明示している。例えば「スクリプト実装(承認済み計画が存在する)」はPhase 4であり、担当エージェントはautomation-engineer(low)である — ここにhighを割り当てるとTier Ceiling違反となる。一方「新規ファイル設計、スキーマ定義」はPhase 1-2であり、architect(high)が担当する。
プラットフォームパリティ — .claude/・.gemini/・.agents/を構造的に同一に保つ方法
このリポジトリは3つのプラットフォームを同時にサポートする — Claude Code(.claude/)、Gemini CLI(.gemini/)、Antigravity(.agents/)。プラットフォームディレクトリが時間の経過とともにずれると(例えば.claude/agents/reviewer.mdは存在するのに.gemini/agents/reviewer.mdが欠けていると)、片方のツールを使うユーザーだけが特定の機能を使えなくなる問題が生じる。スキル層はskills/が単一の情報源(SSOT)であり、sync-skills.tsがこれを3つのプラットフォームディレクトリすべてへ配布する。構造的なずれを防ぐ仕組みがvalidate-templates.tsのプラットフォームパリティ検査である。
ただし検査のスコープには微妙な違いがある。validate-templates.tsはコマンドなどのテンプレート構造を.claude/と.gemini/の2ディレクトリに対してのみ照合し(Antigravity用の.agents/ツリーは独自の同期経路で管理される)、スキルの内容そのものはSSOTであるskills/をvalidate-skills.tsが検証する。つまり「3プラットフォームが同じ機能を提供するか」は、配布スクリプトとSSOT検証の組み合わせで保証される。第11章で扱う昇格(promote)パイプラインもパリティ検査を昇格前の必須ゲートとして含むため、一部のプラットフォーム用だけ作って他を見忘れた状態では、そもそも正式なvariant(バリアント)になれない。3つのプラットフォームが異なる実行方式を使っていても、提供する機能一覧そのものは常に同じでなければならないという原則を構造検査によって強制しているのである。
実行計画テンプレート — マルチエージェント作業の構造化された実行設計
PMが複雑な作業を複数のエージェントに分配する際、実行計画(Execution Plan)形式を使用する。この計画は「誰が何をどのティアで、どの順序で」行うかをテーブルで明示し、実行の一貫性を保証する。
標準実行計画フォーマット
| # | Task | Agent | Tier | Model | Spec |
|---|---|---|---|---|---|
| 0 | Create/update design doc → docs/designs/<spec-id>-design.md | architect | High | [model] | NEW |
| 1 | [task description] | [specialist] | High/Medium/Low | [model] | <spec-id> |
| N | /sync "type(scope): message" | pm | Medium | [model] |
Design Gate(Row 0)
Row 0はL0(ワークスペースルート)とL1(共通テンプレート)にのみ強制される。architectがまず設計文書を作成し、PMがこれを検証した後にのみ実装段階(Row 1以降)に進むことができる。L2 variantプロジェクトは自身のワークフローを管理するため、このゲートは適用されない。
Design Gate 例外カテゴリ
Row 0が負担となる単純な作業には、次の5つの例外カテゴリ(E1〜E5)のみが認められる。例外はPMが任意に作ることはできず、以下に定義されたカテゴリのみを使用しなければならない。
| ID | カテゴリ | 説明 |
|---|---|---|
| E1 | memory-log | memory/YYYY-MM-DD.mdセッションログの作成 |
| E2 | changelog | CHANGELOG.md更新のみ |
| E3 | hotfix-typo | 誤字修正、1行変更、些細な修正 |
| E4 | pure-readme | README.md本文テキストのみ(構造/設計変更なし) |
| E5 | sync-only | /sync実行のみ(ライフサイクル終了) |
例外を適用する場合、Row 0のAgent/Tier/Model列は空欄(—)で表示する。
この例外体系は文書ルールに留まらず、同期パイプラインが機械的に強制する。ADR-0055 Stage 2以降、dev-sync.tsのステップ3.9(specレジストリチェック)は、コード変更に対応するspec活動がない場合、同期をFATALでブロックする。これを回避する唯一の方法は、audit.ts --spec-exempt=E1..E5(またはSYNC_SPEC_EXEMPT環境変数)で上記カテゴリの一つを明示することであり、specはdocs/specs/registry.jsonに登録される(2026-08-24時点)。
実践例:PMが作成した実行計画
以下は「agents/pm.mdとスクリプトを更新するプラットフォームパリティ作業」の実際の実行計画例である。
| # | Task | Agent | Tier | Model | Spec |
|---|---|---|---|---|---|
| 1 | Update agents/pm.md | docs-writer | Medium | sonnet | <spec-id> |
| 2 | Update scripts/audit.ts | automation-engineer | Low | haiku | <spec-id> |
| 3 | Update CLAUDE.md §5 | docs-writer | Medium | sonnet | <spec-id> |
| 4 | Update GEMINI.md §5 | docs-writer | Medium | sonnet | <spec-id> |
| 5 | /sync "docs(agents): update pm.md and platform dispatch rules" | pm | Medium | sonnet |
実行順序:Sequential(逐次実行) — プラットフォームパリティのためにCLAUDE.mdとGEMINI.mdを一緒に更新する必要があるため、逐次実行となる。automation-engineerにlowが割り当てられているのはTier Adjustment Ruleに基づくものである。