AI駆動開発で精度と成果を両立する第1部 全体像第2部 SSoT第3部 ワークフロー第4部 ハーネス
AI駆動開発で精度と成果を両立するシリーズのヒーロー画像

AI駆動開発で精度と成果を両立する — このリポジトリに学ぶ3本柱

AIエージェントは“文脈ゼロだが優秀な新人”。リポジトリを整える一つの手間が、精度と成果のトレードオフを解消します。

AI駆動開発で精度と成果を両立する — このリポジトリに学ぶ3本柱

本シリーズ全4部の第1部(全体像)。

1つの土台から、精度の盾と成果の積み上げという2つの上向きの流れが伸びるイラスト
リポジトリを整えるという1つの手間が、精度(確かさ)と成果(量)の両方を同時に押し上げます。

TL;DR

1. 優秀だが文脈ゼロの新人

いま手元にいるAIコーディングエージェントは、能力だけ見れば文句なしに優秀な新人です。設計パターンを知り、テストの書き方を知り、いくつものファイルをまたいで筋を通すこともできます。ただし、この新人は入社初日にあなたの規約・アーキテクチャ・ワークフローを何ひとつ知らないまま机に座っています。どのレイヤーに何を置くか、どのブランチ戦略で動くか、どのコマンドで品質を確かめるか — そうした文脈は、リポジトリの側から渡してやらないかぎり手に入りません。

ここから本シリーズの問いが立ち上がります。あなたのリポジトリは、自走できる優秀な新人(=AIエージェント)が入ってきて、すぐ精度高く開発できる状態になっているでしょうか。この問いに「はい」と答えられるかどうかが、AI駆動開発の成否を分けます。大事なのは、その答えがプロンプトの巧みさではなく、リポジトリ側の備わり具合(repo readiness)で決まる、という点です。

2. 「両立」が前提とするトレードオフ

精度と成果がシーソーのように、片方を上げると片方が下がることを示すイラスト
素朴なやり方では、確かさを上げるほど量が落ちる、いつもの綱引きが残ります。

精度と成果は、ふつう片方を立てればもう片方が傾く関係にあります。まずはこれを中立的な事実として確かめておきます。ここで言う精度とはエラーや手戻りの少なさ、成果とはアウトプットの多さ、つまりスループットのことです。ソフトウェア開発にかぎらず、この二つは多くの場面でトレードオフになります。速く多く出そうとすれば見落としが増え、ていねいに確かめようとすれば歩みは遅くなります。経験のある書き手なら誰もが肌で知っている、ありふれた綱引きです。

AIエージェントを素朴に使う場合 — つまり強力なモデルと工夫したプロンプトだけで回す場合 — このトレードオフはそのまま表に出ます。エージェントは速いのです。だからこそ、文脈が渡されていなければ、速いペースで規約から外れ、レイヤーの依存の向きを踏み越え、いまある振る舞いを思わぬかたちで変えてしまう余地も、同じ速さで広がります。これはエージェントの力不足ではなく、文脈が渡されていないことの自然な結果です。出力の速さを上げるほど、確認と手直しに回る手間が後から積み上がっていきます。素朴な使い方のままでは、精度と成果はあちらを立てればこちらが立たずという、これまでどおりのトレードオフにとどまります。

3. リフレーミング: 準備されたリポジトリはトレードオフを解消する

あらかじめ整えた道を、新人ロボットが速く確かに進むイラスト
道をあらかじめ整えておけば、新人は速さも確かさも手放さずに進めます。

ところが、このトレードオフは動かせないものではありません。投資の向き先を「より強いモデル」や「より凝ったプロンプト」から、「新人がすぐ自走できるリポジトリ」へと移すと、関係そのものが組み替わります。

いまの素朴な使い方に対して、変えた先にあるのが準備されたリポジトリです。規約が文章になっていて、ワークフローが道案内され、コードの形が小さな編集を安全にしているリポジトリでは、エージェントは渡された文脈の上で動くので外れが減ります(精度が上がる)。同時に、人の手による細かな口出しなしで自走できるので、いくつもの作業を同時に進められます(成果が増える)。同じ一つの投資が、精度を押し上げる方向と成果を押し上げる方向の両方へ、いちどに働くのです。これが本シリーズの言う「両立」の正体です。たとえるなら、社員一人ひとりに付きっきりで教える代わりに、一度きちんとした入社ガイドを整えておけば、誰が入ってきても同じ質ですぐ動ける、というのに近いものです。提案は明快です — 次に説明する3本柱に投資すること、それだけです。

4. なぜ AIエージェント = 新人か(必要なものが同じ)

この提案が成り立つのは、AIエージェントに必要なものと、自走する人間の新人に必要なものが、ほとんどぴったり重なるからです。新人にすぐ動けるようになってほしいとき、私たちは三つのものを用意します。どう書くかを学べる場所、安全に並行して働ける方法、自分の役割に合った入口です。エージェントに渡すべきものも、まったく同じ三つに重なります。

図1は、その対応関係を示しています。

リポジトリの実体 (本シリーズの題材)

精度と成果を両立する3本柱

自走する新人 / AIエージェントに必要なもの

どう書くかを学ぶ場所

安全に並行で働く方法

エージェント向けの入口

柱1: SSoT整備とガバナンス

柱2: 開発ワークフローと環境

柱3: コーディングエージェントハーネス

CLAUDE.md / AGENTS.md / .claude/rules / docs

worktree強制 / pnpm gates / 縦横スライス

.claude/skills・agents・commands / autopilot

図1: 新人とAIエージェントに共通して必要なもの → 3本柱 → リポジトリの実体

左から右へ、「新人にもエージェントにも共通して必要なもの」が「3本柱」を通って「このリポジトリの具体的なファイルや仕組み」へと降りていきます。人間の新人をすぐ動けるようにする投資が、そのままエージェントをすぐ動けるようにする投資になる、という重なりが一目でつかめます。

5. 3本柱モデル(各柱が精度/成果のどちらに効くか)

3本の柱が土台を支え、その上で新人ロボットが精度と成果の両方を持ち上げているイラスト
3本の柱が同じ土台を支え、精度と成果の両方を一緒に押し上げます。

3本柱は、柱1がSSoT(Single Source of Truth)整備とガバナンス、柱2が開発ワークフローと開発環境、柱3がコーディングエージェントハーネスです。どの柱も、精度か成果のどちらか一方ではなく、両方に効きます。それぞれをくわしく掘り下げるのは第2部以降にゆずりますが、柱が「両立」の形をそれぞれの層でくり返している、と言い換えてもよいでしょう。

精度への寄与 成果への寄与
柱1 SSoT・ガバナンス 唯一の正しい「書き方」を提示し曖昧さをなくす always-loaded rules と AGENTS.md で立ち上がりコストを大幅に下げる
柱2 ワークフロー・環境 gate と AC 検証で回帰を防ぎ、縦レイヤーで局所的に安全な編集 worktree 並列+横 feature 小分割で複数タスクを同時進行
柱3 ハーネス SSoT をエージェントに確実にロードし外れをおさえる autopilot 自走・モデル階層・サブエージェント並列で効率化

縦に読むと精度への寄与が、横に並べると成果への寄与が見えます。たとえば柱1は、唯一の正しい書き方を示して曖昧さをなくす(精度)と同時に、常時ロードされるルールと AGENTS.md によって新人の立ち上がりコストを大幅に下げます(成果)。一つの整えが二つの効きめを生むこの形は、三つの柱すべてに共通しています。

6. 1つの投資 → 2つの成果(両立の図解)

この形を一枚に圧縮すると、図2のようになります。

リポジトリ整備への投資

精度: 手戻り・回帰・規約違反の削減

成果: 並列開発と自走によるスループット向上

精度と成果の両立

図2: 1つの投資が精度と成果の両方を生む

ここで第2節のトレードオフに立ち返ります。素朴な使い方では、精度と成果は片方を上げればもう片方が下がる関係にありました。けれども図2が示すのは、リポジトリを整えるという一つの投資が、手戻り・回帰・規約違反を減らす流れ(精度)と、並列開発と自走でスループットを上げる流れ(成果)の両方へ、同時に枝分かれして流れていく姿です。源が一つの川なら、二つの流れは互いを削り合わず、同じ水源から並んで生まれます。投資が一つだからこそ、二つの効きめはぶつからずに済むのです。トレードオフが消えるのは、精度と成果を別々に追わず、リポジトリの備わり具合という一つの上流に投資した結果にほかなりません。これが「両立」が単なるスローガンではなく、因果としてつながっている理由です。

7. このリポジトリについて

本シリーズが題材とするのは、DDD + Clean Architecture のhello-world縦切りを持つ product-agnostic な Next.js モノリスです。.claude/ の下に、AIエージェント用のハーネス — always-loadedのルール、on-demandのスキル、サブエージェント定義、スラッシュコマンドのワークフロー — を self-contained にvendorしています。なお、本シリーズで挙げる具体例は TypeScript + biome + pnpm が中心ですが、統制の戦略そのものはスタックに依存しません。各自の linter・型チェッカー・依存境界チェッカー・hooks・CI に読み替えられます。具体的な中身は第2部以降で扱いますが、ここで一つ、シリーズ全体を貫く約束をしておきます。各統制について語るとき、それが「どれだけ強く効いているか」を正直に分けて書く、という約束です。

統制の効き方は、本シリーズでは三段階の言葉で見ていきます。第一段階は enforced(機械的に強制) で、ツールやCIが仕組みとして必ずそうなるようにしている層です。たとえば .claude/settings.json の permissions は、.env**.key の Read、git push --force*eval *curl ... | sh といった操作をツール権限のレベルで断っており、Security NEVERsの一部をエージェントには実行できないものにしています(ここで「一部」と書くのは正確を期すためです。たとえば rm -rf /rm -rf ~ は断る対象ですが rm -rf * 一般は対象外で、worktree内での git checkout main の禁止やシークレットのコミット禁止はツール権限では縛れず、後で述べる規約や文書で支えます)。同じく .github/workflows/ci.ymlruntime → lint → typecheck → API → docs → coverage → build を走らせ、pnpm lint の中で check:architecture も実行します。Husky も pre-commit で lint/typecheck、pre-push で test/build を止めるため、ローカルとCIの両側で品質ゲートを機械的に回します。

第二段階は enforced by convention(規約・常時ロードで強制) です。.claude/rules/ に置かれた9つのファイルがalways-loadedとして扱われ、エージェントが動くたびにその文脈へ毎回読み込まれます。レイヤーモデル、コア不変条件、プラン・レビュー、バックエンド規約といったルールが、はっきりした指示がなくても常にエージェントの視界に入っている — これがこの段階の効き目のもとです。機械的に断るわけではありませんが、文脈に常駐することで規約からの外れを抑えます。

第三段階は documented / aspirational(文書化・努力目標) です。ここには、仕組みとしてはまだ出来ていない部分も正直に入れます。docs/02_architecture/adr/ というADR用のディレクトリはありますが、ADR は committed な判断記録として整備済みで、.gitkeep が置いてあるだけです。pre-commit / pre-push hooks や CI で gate を機械化することはスタックに依存せずできますが、.claude/settings.jsonhooks は空({})で、GitHub 側の branch protection / required review の強制が残っています。

documented / aspirational(文書化・これから)

GitHub branch protection

required CODEOWNERS review

enforced by convention(常時ロードで効かせる)

.claude/rules/* (9ファイル, always-loaded)

TypeScript implements + 単一 composition

enforced(機械で縛る)

settings.json の permissions

CI: runtime / lint / typecheck / API / docs / coverage / build

統制の効き方

図3: 統制の3段階 — 機械で縛る / 常時ロードで効かせる / 文書化(これから)

レイヤー依存の向きは、依存境界チェッカー(dependency-boundary checker)や linter の import 境界ルールで機械的に縛れます。実在の道具を例に挙げれば、biome の import 制限ルール、ESLint の boundaries プラグイン、import-linter(Python)、dependency-cruiser(JS/TS)、ArchUnit(JVM/.NET)などがこの役割を担います。本リポジトリでは、src/quality/import-boundary.test.tspnpm check:architecture として切り出し、さらに pnpm lint の中から実行します。always-loaded な architecture.md が毎セッションの視界に常駐し、型システムの契約(本リポジトリは TypeScript の implements)が port と adapter の型の約束を補強し、唯一の結線点 src/composition/container.ts が依存の向きを構造として固定する。その上で、逸脱は lint gate の早い段階で止まる、という位置づけです。

これらの出来ていない部分をあえて書き出すのは、煽るためでも自分を低く見せるためでもなく、読者が自分のリポジトリに同じ仕組みをつくるときの、現実に即した地図を渡すためです。どこまでが機械で守られ、どこからが規約と文書にゆだねられているかを正直に分けておけば、移すときにどの統制を先に機械化すべきかの見当がつきます。このリポジトリは完成形のショーケースではなく、reference implementation — 見ながら自分の文脈へ訳していくための土台 — として読むのがふさわしいものです。

8. 次回以降の歩き方

第1部で描いたのは、3本柱が一つの投資から精度と成果の両方を生むという全体像でした。次回以降は、その地図を柱ごとに一本ずつ、ファイルと仕組みに即して具体へ降ろしていきます。

第1部(今回): 全体像と3本柱

第2部: 柱1 SSoTとガバナンス

第3部: 柱2 ワークフローと開発環境

第4部: 柱3 エージェントハーネス

図4: シリーズの歩き方 — 今回の全体像から、次回以降は柱を1本ずつ

次回(第2部)は、柱1のSSoT整備とガバナンスを扱います。開発ナレッジをどこに単一の正として置き、権限とアカウントをどう統制するか — .claude/rules/00-core-invariants.md の「Single Source of Truth」テーブルが正の在処を一つに決めている構造と、たっぷり書かれた CLAUDE.md と最小限の AGENTS.md の役割分担を読み解きます。

第3部では、柱2の開発ワークフローと開発環境へ進みます。worktreeによる並列開発という「横」の広がりと、レイヤード・アーキテクチャという「縦」の深さ、受け入れ条件(AC)の検証を組み合わせて、いくつものタスクを安全に同時進行させる仕組みに踏み込みます。

最終の第4部では、柱3のコーディングエージェントハーネスを扱います。.claude/ の下のSkills・Agents・Commandsの連携、autopilot がPhase 0-5(Preflight / Planning / Implementation(TDD) / QA / Review / PR)の固定ループでタスクをPRまで自走させる流れ、サブエージェントのモデル階層まで、vendorされた完全なハーネスを基準に解き明かします。

想定読者は、AI駆動開発を組織やリポジトリに本気で取り入れたいエンジニアおよびテックリードです。次の第2部から、柱を一つずつ具体にしていきます。続けてお読みください。

第2部 SSoT整備とガバナンス — 開発ナレッジの唯一の正と、それを強制する仕組み

本シリーズ全4部の第2部。

新人ロボットが1冊の光る正典の手引きを読むイラスト。散らばった紙と対照的
「ここでの書き方」が1冊にまとまっていれば、新人は迷わず正しいやり方にたどり着けます。

TL;DR

0. 新人は「ここではどう書くのか」を迷わず知れるか

柱1は、文脈ゼロの新人がいちばん最初にぶつかる問いに答えます。「ここではどう書くのか」を、迷わず・一箇所で・確実に知れるか、という問いです。第1部では、AIコーディングエージェントを「優秀だが文脈ゼロの新人」として捉え、リポジトリ整備への一つの投資が精度と成果のトレードオフを解消する、という命題を立てました。本稿で扱う柱1 — SSoT(Single Source of Truth)整備とガバナンス — は、その新人の最初の問いに答える柱です。

この問いが満たされない状態を、まず中立的に見ておきます。唯一の正典(SSoT)が無いリポジトリでは、同じ関心事についての知識が複数の場所に散らばります。アーキテクチャの説明が README とコメントと古い設計メモに少しずつ書かれ、しかも互いに食い違っている、というのはよくある光景です。このとき新人 — 人間であれエージェントであれ — は、どれが今の正しい書き方なのかを決められず、たまたま目に入った古い例や我流の断片を引いてしまいます(精度の低下)。正しい記述を探すために複数の場所を当たらねばならず、その探索そのものが時間を食います(成果の低下)。知識の散らばりは、精度と成果の両方を静かに削っていきます。

裏を返せば、この柱が整っているとき、改善は精度と成果の両方に同時に効きます。

観点 この柱の寄与
精度 唯一の正典が「正しい書き方」を一つに示し、食い違い・古い例・我流をおさえる
成果 always-loaded rules と AGENTS.md で立ち上がりコストを下げ、探す時間を減らす

このリポジトリがどのように「唯一の正」を定め、それをどのくらいの強さで縛っているかを、ファイルに即して読み解いていきます。

1. SSoT テーブル — 1関心事に1つの正典

新人ロボットが、関心事ごとに区画が分かれた一つの棚の前に立つイラスト。重複した紙は脇に片付けられている
関心事ごとに置き場が一つ。探す場所が決まっていると、迷いが消えます。

出発点は .claude/rules/00-core-invariants.md の冒頭に置かれた「Single Source of Truth」テーブルです。このテーブルは、主な関心事のそれぞれについて、その正典がどこにあるかを一つに決めています。

Document Location
Architecture & process CLAUDE.md
Agent operating manual AGENTS.md
Layer model & dependency rule .claude/rules/architecture.md
DDD + Clean Architecture design docs/02_architecture/design/0001-ddd-clean-architecture-design.md
ADRs docs/02_architecture/adr/
Autonomous coding harness guide docs/03_guides/autonomous-coding-harness.md

ここにある設計思想は単純ですが強力です — 一つの関心事には、一つの正典の場所を割り当てます。アーキテクチャとプロセスを知りたければ CLAUDE.md を見ればよく、レイヤーモデルと依存方向の正確な定義が欲しければ .claude/rules/architecture.md を見ればよいでしょう。同じことが二箇所に書かれて食い違う、という事態を、そもそも構造から防いでいます。

「1関心事=1場所」が精度と成果の両方に効く理由も、この構造から導けます。精度の側では、正典が一つであれば、食い違う記述が並ぶ余地が消えます。新人が古い例や我流の断片を引く確率は、見るべき場所が一つに固定されているほど下がります。成果の側では、「どこを見ればよいか」が決まっていること自体が、探すコストを削ります。複数の候補を当たって突き合わせる作業が要らなくなり、立ち上がりが速くなります。テーブルが指すのは知識の在処であって知識そのものではない、という点も効率に効いています — 中身はそれぞれの正典にゆだね、ここでは在処だけを一つに示すことで、テーブル自身が二重管理の相手にならずに済んでいます。

2. docs の番号付き階層

正典の多くは docs/ の下に置かれます。このリポジトリの docs/ は、意思決定の層別に対応する番号付きの taxonomy を持ちます。00_process(プロセス)、01_product(プロダクト)、02_architecture(その下に adr/design/)、03_guides(運用ガイド)の四階層です。番号の昇順が、おおむね「どう進めるか → 何を作るか → どう構造化するか → どう運用するか」という意思決定の流れに対応しています。

docs/ (番号付き taxonomy)

00_process: プロセス文書

01_product: プロダクト文書 (必要に応じて追加)

02_architecture

03_guides: 運用ガイド

adr/ : 0001-0004 ADR + template

design/ : 0001-0004 設計ドキュメント

図1: docs の番号付き taxonomy と SSoT の対応

番号付きの階層が、意思決定の層別をそのままディレクトリ構造に写し取っています。新人は「これはプロセスの話か、構造の話か」を番号から見当づけられます。

この taxonomy の現状は、第1部で約束した「正直な区別」に従って書いておきます。01_product はプロダクト要求を置くための枠で、現時点では .gitkeep のみです。これは product-agnostic なテンプレートとして意図した空白であり、実プロダクトへ適用するときに PRD / FRD / 要件定義を追加する場所です。一方、02_architecture/adr/ には 0001 から 0004 までの ADR と README / template が committed されています。DDD + Clean Architecture、Next.js モノリス、worktree ベース開発、vendored agent harness の判断は、ここから辿れます。02_architecture/design/ にも 0001 から 0004 までの設計文書があり、DDD 設計、frontend governance、observability、Server Components data pattern の正典として働いています。つまり、プロダクト固有文書は空白を残しつつ、アーキテクチャ判断と設計ガイドはすでに実体を持つ、というのが正確な現状です。

3. always-loaded rules — ガバナンスの実体

新人ロボットの机に、9枚のルールカードが常に広げられているイラスト
9枚のルールは常にそこにあって、聞かなくても答えがわかります。

SSoT テーブルが「正典の在処」を定めるのに対して、ガバナンスの実体 — 日々の作業を実際に方向づける規約 — は .claude/rules/ の下に置かれています。ここには9つのファイルがあり、いずれもエージェントの文脈に毎回読み込まれる always-loaded のルールとして扱われます。本稿を書いているこのセッションでも、9ファイルすべてがセッション開始時に「project instructions」として文脈へ注入されました。はっきりした指示がなくても常にエージェントの視界に入っている — これが第1部で言う「enforced by convention(規約・常時ロードで縛る)」の段階に、この9ファイルが属する理由です。

File Purpose
architecture.md Layer model + dependency rule (DDD / Clean Architecture)
00-core-invariants.md SSoT table, non-negotiables, security NEVERs
communication-ux.md Output language, progress reporting, recommend-first
diagram.md Mermaid mandatory; ASCII box-drawing forbidden
plan-review.md Plan-before-execute; optional reviewer-agnostic review
backend.md Server/domain conventions, repository-port pattern, testing
issue-status.md Issue status labels + transition state machine
deps.md Verify dependency versions via the package manager
frontend-design-governance.md UI/design-token/brand customization checks

この常時ロードに加えて、一部のルールは適用の範囲を宣言しています。deps.mdbackend.md は frontmatter に globs を持ち、前者は package.jsonpnpm-lock.yaml といった依存関係まわりのファイルに、後者は src/domain から src/composition までのレイヤーに、適用の scope を絞り込んでいます。常時ロードされる baseline の規約に対して、「このルールが特に効くのはどのファイルを触るときか」という関連性のメタ情報を上乗せしている、と捉えるとよいでしょう。エージェントが該当ファイルを編集する場面で、その規約がいっそう前に出る設計です。

9ファイルの内訳を見ると、この柱がカバーする範囲の広さがわかります。アーキテクチャ(architecture.md)、コア不変条件とSSoT(00-core-invariants.md)、コミュニケーションの作法(communication-ux.md)、図の規約(diagram.md)、プラン・レビュー(plan-review.md)、バックエンド規約(backend.md)、issue の状態遷移(issue-status.md)、依存管理(deps.md)、フロントエンドのデザインガバナンス(frontend-design-governance.md)。「どう書くか」の問いに対する答えが、関心事ごとに分けられて常駐しています。

4. CLAUDE.md と AGENTS.md — 二層の入口

正典と規約が揃っていても、新人がどこから読み始めればよいかが曖昧では、立ち上がりは遅くなります。このリポジトリは入口を二つ用意し、読み手に応じて役割を分けています。

一方の CLAUDE.md はリッチな入口です。人間と Claude の双方に向けて書かれ、アーキテクチャの図、コマンド一覧、そして .claude/ の下のハーネス(rules・skills・agents・commands)の目録を表として持ちます。ここを読めば、リポジトリ全体の地図と各構成要素の在処が一望できます。

もう一方の AGENTS.md はミニマルな入口です。ツールに依存しない(tooling-neutral)記述で、Codex や Gemini などが参照する AGENTS.md 規約に対応します。ただし役割は「ルールを5つだけ並べる」ことではありません。現在の AGENTS.md は、agent-agnostic な薄い bootstrap として、最小限の不変条件、非 Claude エージェント向けの明示的な rule loading 手順、そして SSoT Map を持ちます。

2つの入口

CLAUDE.md (リッチ: 表・図・ハーネス目録)

AGENTS.md (薄い入口: Minimum Rules + Bootstrap + SSoT Map)

共通の不変条件: worktree / 依存方向 / gate / Conventional Commits / plan-first

人間とエージェントの作業

図2: 2つの入口と共通の不変条件

二つの入口は、同じ不変条件の上で一致しています。図2の中央に置いた項目 — worktree、依存方向、品質ゲート、Conventional Commits、plan-first — は、AGENTS.md の Minimum Rules が短く固定し、CLAUDE.md が表と図で広げている内容の核でもあります。両者が食い違わないのは、AGENTS.md が詳細なルール本文を自分の中に重複させず、CLAUDE.md.claude/rules/docs/ へ辿る導線を持つからです。第1節のSSoT テーブルが AGENTS.md を「Agent operating manual」の正典として挙げていたことと、ここで符合します — AGENTS.md はエージェント共通の起動手順と索引の正典であり、詳細な判断材料はそれぞれの SSoT にゆずります。リッチとミニマルという質の違いはあっても、二つの入口は同じ一つの不変条件へと集まっていきます。

5. ガバナンスの強制 — 3段階で正直に

ここまで見てきた SSoT と規約が、実際にどれだけの強さで効いているか。第1部で約束した三段階の言葉 — enforced / enforced by convention / documented・aspirational — で、この柱の統制を率直に格付けしておきます。

documented / aspirational

GitHub branch protection

required CODEOWNERS review

enforced by convention: 常時ロード

.claude/rules/* 9ファイル (always-loaded)

enforced: 機械強制

settings.json の deny / allow

CI: runtime / lint / typecheck / API / docs / coverage / build

ガバナンス全体

図3: ガバナンス強制の3段階

三段階が、それぞれ違う強さでガバナンス全体を支えています。どこまでが機械で守られ、どこからが規約と文書にゆだねられているかを、層として分けられます。

enforced(機械強制)。 いちばん強い層は、ツール権限、Husky、CIによる機械的な縛りです。.claude/settings.jsonpermissions.deny は、Security NEVERs の一部をツール権限のレベルで断ります。具体的には、.env**.key*.pem*.p12 などの Read 拒否、git push --force*git push -f *git reset --hard*rm -rf /rm -rf ~curl * | shcurl * | bash、そして eval * がここに含まれます。反対に allow の側では、pnpm * 系のスクリプト、git worktree*gh pr *、そして lscatgrep といった読み取り系コマンドのカテゴリを事前に許可し、安全な操作の friction を下げています。.github/workflows/ci.yml は runtime・lint・typecheck・API契約・docs・coverage・build を走らせ、pnpm lint の中で check:architecture も実行します。.husky/pre-commit は lint/typecheck、.husky/pre-push は test/build を止めるローカル側の防波堤です。

ただし、この機械的な縛りは正直に「一部」と書くべきものです。rm -rf * のような一般形は deny の対象に入っておらず、worktree 内での git checkout main の禁止や、シークレットのコミット禁止も、ツール権限では縛れません。これらは .claude/rules/00-core-invariants.md の Security NEVERs として規約で支えています。機械で止められる範囲と、規約で約束する範囲の境目を、ここではっきりさせておきます。

enforced by convention(規約・常時ロード)。 次の層が、第3節で見た .claude/rules/ の9ファイルです。機械的に断るわけではありませんが、文脈に常駐することで規約からの外れをおさえます。

documented / aspirational(文書化・努力目標)。 いちばん弱い層には、GitHub 側の branch protection や required CODEOWNERS review のように、リポジトリ設定として有効化が必要なものがあります。一方で、ADR は docs/02_architecture/adr/ に committed な判断記録として置かれ、レイヤーの依存方向は src/quality/import-boundary.test.tspnpm check:architecture によって lint gate の早い段階で検出されます。残る努力目標は「どの設定が GitHub 側の強制で、どの設定がリポジトリ内のコードで強制されているか」を継続的に同期することです。

6. 権限とアカウント

初日の新人ロボットに、渡す鍵と渡さない鍵が分けられた鍵束が手渡されるイラスト
渡す鍵と渡さない鍵を、入る日にあらかじめ決めておく。これが permissions です。

いちばん強い層である permissions の設計を、別の角度から見ておきます。これは、新人に渡す鍵束のようなものです。何を開けてよく、何を開けてはならないかを、入社時にあらかじめ束ねて手渡します。

settings.jsonpermissions がしていることは、まさにこの鍵束の設計に対応します。安全な操作の allow を絞って事前に許可し、危ない操作を deny で塞ぎます。この最小権限的な発想は、人間の新人にアカウントを渡すときの考え方と同じ形です。リポジトリの権限、CIへのアクセス、gh の権限 — 人間にはこれらを役割に応じて絞って渡します。エージェントにとっての「アカウント付与」にあたるのが、許可されたツール権限の集まりです。どちらも、必要なものは渡し、危ないものは渡さない、という同じ原理で設計されています。

ただし、ここで層を取り違えないように注意します。settings.jsonpermissions が扱うのは、あくまでリポジトリレベルの allow / deny です。組織の SSO や secrets 管理とは別の層です。secrets について deny がしているのは「読ませない」方針を支えることであって、実際の認証情報を渡したり入れ替えたりするのは、このファイルの外 — 組織の権限基盤の役目 — に属します。鍵束のたとえで言えば、permissions は「どの鍵を束に入れるか」を決めますが、鍵そのものを発行し管理するのは別の仕組みです。

7. この柱が精度と成果を両立する理由

最後に、柱1がなぜ精度と成果の両方に効くのかを、ここまでの話からまとめておきます。

精度の側では、唯一の正典が「正しい書き方」を一つに示し、それが常時ロードによってエージェントの視界に常駐します。SSoT テーブルが正典の在処を一つに定め、9つの always-loaded rules が日々の規約を文脈に常駐させ、二つの入口が同じ不変条件へ集まる。この三重の仕組みが、食い違う記述や古い例、我流の断片といった「誤った書き方」を引く余地を、構造から狭めていきます。

成果の側では、同じ仕組みが探すコストを削り、ramp time を縮めます。「どこを見ればよいか」が一つに決まっていること、規約を探さずとも常に手元にあること、入口がリッチ版とミニマル版に整理されていること — これらはいずれも、新人が正しい書き方にたどり着くまでの時間を縮めます。立ち上がりが速い新人は、早く自走に入れます。

第1部で立てた命題のとおり、これは別々の二つの投資の結果ではありません。SSoT を整え、規約を常時ロードし、入口を整理するという一つの整備が、誤りをおさえる経路(精度)と立ち上がりを速める経路(成果)の両方へ同時に流れていきます。柱1は、その「両立」をガバナンスの層で形にしたものです。

一つの整え

SSoTテーブル

always-loaded rules

2つの入口 (CLAUDE.md / AGENTS.md)

精度: 誤りや食い違いをなくす

成果: 探す手間と ramp time を減らす

図4: SSoT整備という一つの手間が、精度と成果の両方へ届く

次回(第3部)は、柱2「開発ワークフローと開発環境」を見ていきます。worktree による並行という「横」の切り分けと、レイヤードアーキテクチャという「縦」の切り分けが主題です。整った正典の上で、受け入れ条件をどう確かめるかも、あわせて見ていきます。

第3部 開発ワークフローと開発環境 — 横に小さく、縦に薄く、必ず確かめる

本シリーズ全4部の第3部(柱2: 開発ワークフローと開発環境)。

分かれた作業机(横の並列)と積み上がったレイヤー(縦)、検証ゲートを通すイラスト
横に小さく分けて並行で、縦に薄いレイヤーで重ねる。仕上げる前に必ずゲートで確かめます。

TL;DR

0. 問い: 新人は、他者の作業を壊さず、自分の変更が正しいと確かめられるか

この第3部の問いは一つです。優秀だが文脈ゼロの新人が、他者の作業を壊さず安全に並行して動き、しかも自分の変更が正しいと自分で確かめられるか。第1部の問いを、この柱の具体に降ろすとここに行き着きます。能力の高いエージェントほど、速く多くのファイルに手を入れます。だからこそ、その速さが他人のブランチを巻き込まず、規約や既存の振る舞いを思わぬかたちで変えず、変更の正しさが本人の手で確かめられる仕組みが要るのです。

この柱は、その仕組みを「縦」と「横」という二つの切り口で渡します。とは、feature 単位で作業を小さく切り、worktree で並列に進めること。とは、レイヤード・アーキテクチャでコードを薄く切り、テスタブルで疎結合に保つこと。その両方を支えるのが、受け入れ条件(AC)の検証 — quality gate と自動テストで、変更の正しさを機械的に確かめる工程です。横を机に、縦を持ち場にたとえると分かりやすいかもしれません。机を分ければ隣の人とぶつからずに作業でき、持ち場を分ければ料理を仕込み・調理・配膳のように受け渡せます。

第1部で確認したとおり、どの柱も精度と成果の片方ではなく両方に効きます。この柱も例外ではありません。

観点 この柱の寄与
精度 隔離(worktree)・型・gate・AC 検証で回帰と規約違反を防ぐ。縦レイヤーで編集の影響を局所化する
成果 worktree 並列+feature 小分割で複数タスクを同時進行。決定論的な拡張レシピで速い

縦に読めば精度への寄与が、横に読めば成果への寄与が並びます。隔離と検証が手戻りを減らし(精度)、並列と小分割が同時進行を可能にします(成果)。同じ一つの整備が二つの方向に同時に効くこの形は、第1部で示した「両立」の因果を、ワークフローと環境の層でもう一度なぞったものです。以下、横・縦・検証の順に見ていきます。

1. 横の分割 — feature 単位で小さく、worktree で並列

横の起点は、このリポジトリの非交渉事項(Non-Negotiables)の筆頭にあります。.claude/rules/00-core-invariants.md はこう定めています。

Worktree-based development — The repository root stays on main. Do NOT run git checkout <branch> at the root. Do all work in an isolated worktree (e.g. under .claude/worktrees/) and integrate via PR.

リポジトリのルートは常に main に置いたまま、作業はすべて隔離された worktree で行い、PR で統合します。ルートで git checkout <branch> を走らせることは、はっきり禁じられています。この規約を実際の操作に落とし込むのが .claude/commands/kickoff.md のスラッシュコマンドです。kickoff は issue を読み、git worktree add で隔離された worktree とブランチを作り、spec とプラン(あれば)を読み、受け入れ条件からタスクリストを組んで着手準備を整えます。「worktree で作業せよ」という規約が、コマンド一つで再現できる手順になっているわけです。

この記事自身が、その証しです。いま読んでいる第3部の原稿は、リポジトリのルートではなく .claude/worktrees/ 配下の隔離された worktree の中で書かれています。規約を説く文章が規約どおりの場所で書かれているという dogfooding が、横の分割が空論ではないことを示しています。

横が並列であるとき、避けられない問いが「複数の作業が同じ issue を取り合わないか」です。これに答えるのが .claude/rules/issue-status.md の重複作業ガード(duplicate-work guard)です。status:in-progress のラベルが付いた issue は、すでに誰か(人間またはエージェント)が着手中であることを意味し、他のエージェントはそれに手を出してはなりません。着手前に必ずステータスを確かめ、status:in-progress であれば原則として手を引く — この一線が、並列で走る複数のエージェント同士のぶつかり合いを防いでいます。

ステータスの遷移は図1のとおりです。

issue作成

plan/spec完成

着手

PR作成

PRマージ

blocker発生

blocker解消

即時着手 (kickoff / autopilot)

backlog

ready

in_progress

in_review

done

blocked

図1: issue ステータスの状態遷移(重複作業ガード)

backlog から readyin_progressin_reviewdone へと一方向に流れ、blocker が出れば blocked へ退避し、解消すれば in_progress へ戻ります。kickoff や autopilot による即時着手は、backlog から in_progress へ直行する経路として用意されています。ステータスという単一の共有状態が、誰がどの issue を握っているかを一つに表し、取り合いを起こしません。

ここに横の二つの核があります。成果の核は、複数の作業がぶつからず同時に進められること — worktree で物理的に隔離され、ステータスで論理的に排他されるからこそ、新人を何人並べても互いを踏みません。精度の核は、各作業が main から隔離され PR を通して統合されること — ルートの main は常にクリーンなまま保たれ、未完成の変更が直接混ざりません。並列性と隔離性が同じ worktree という仕組みから同時に出てくる点が、横の分割が成果と精度の両方に効く理由です。

2. 縦の分割 — レイヤードでテスタブル・疎結合に

横が「どこで作業するか」を整えるのに対し、縦は「コードをどう積むか」を整えます。このリポジトリは domain / application / infrastructure / composition / app の5層に分かれ、内側の層は外側の層を知らないという依存方向を守ります。.claude/rules/architecture.md の層テーブルが、各層のパスと許される import を一つに定めています。

Layer Path Imports allowed
domain src/domain nothing (pure TypeScript)
application src/application domain only
infrastructure src/infrastructure domain only (implements ports)
composition src/composition application + infrastructure
presentation src/app composition (+ React/Next)

同じルールが二つの非交渉事項として明記されています。

Inner layers MUST NOT import outer layers.

domain/ must contain no framework or infrastructure imports.

内側は外側を import してはならず、domain/ は framework や infrastructure の import を一切持たない純粋な TypeScript に保たれます。依存の矢印は外から内へ一方向に流れ、逆流しません。これを図にすると図2のようになります。

app (presentation)

composition

application (use cases)

domain (entities + ports)

infrastructure (adapters)

図2: レイヤーの依存方向(内側は外側を知らない)

appcomposition に依存し、compositionapplication を、applicationdomain を指します。infrastructure もまた domain だけを指します。すべての矢印の終点が domain に向かっていることが、依存方向が一方向であることを表しています。domain は何にも依存しないため最もテストしやすく、外側の層ほど具体的な技術(React や Next、I/O クライアント)に近づきます。この薄い層構造が、次節で見る「一機能が全層を貫く」縦切りと、編集の影響を層の内に閉じ込める疎結合の土台になります。

3. greeting 縦切り — 1機能が全層を貫く worked example

抽象的な層テーブルだけでは、縦の薄さは体感しにくいものです。このリポジトリには greeting という最小の feature が縦切りの worked example として置かれています。一つの機能が、各層をごく薄く貫いている様子を順に見ていきます。

まず domain 層です。エンティティ Greeting は public なコンストラクタを持たず、不変条件を確かめる factory method create 経由でのみ生成されます。src/domain/greeting/greeting.ts:

export class Greeting {
  private constructor(private readonly value: string) {}

  static create(message: string): Greeting {
    const trimmed = message.trim();
    if (trimmed.length === 0) {
      throw new Error('Greeting message must not be empty');
    }
    return new Greeting(trimmed);
  }

  get message(): string {
    return this.value;
  }
}

同じ domain 層に、リポジトリのインターフェース(port)が置かれます。実装ではなく契約だけがここにあります。src/domain/greeting/greeting-repository.ts:

import type { Greeting } from '~/domain/greeting/greeting';

export interface GreetingRepository {
  findDefault(): Promise<Greeting>;
}

次に application 層のユースケースです。execute 一つを持つ小さなクラスで、port にのみ依存し、戻り値はドメインオブジェクトではなくプレーンな DTO です。src/application/get-greeting-usecase.ts:

import type { GreetingRepository } from '~/domain/greeting/greeting-repository';

export interface GreetingDto {
  message: string;
}

export class GetGreetingUseCase {
  constructor(private readonly repository: GreetingRepository) {}

  async execute(): Promise<GreetingDto> {
    const greeting = await this.repository.findDefault();
    return { message: greeting.message };
  }
}

そして具体的な adapter とユースケースを結びつける唯一の結線点が composition 層です。ここで初めて具体実装 InMemoryGreetingRepository が new され、ユースケースに注入されます。src/composition/container.ts:

import { GetGreetingUseCase } from '~/application/get-greeting-usecase';
import { InMemoryGreetingRepository } from '~/infrastructure/in-memory-greeting-repository';

const greetingRepository = new InMemoryGreetingRepository();
export const getGreetingUseCase = new GetGreetingUseCase(greetingRepository);

ここまでが各層を貫く実体です。presentation 層(app/page.tsx の Server Component と app/api/greeting/route.ts の API ルート)は、この composition から getGreetingUseCase を import して execute() を呼ぶだけで、ビジネスロジックを持ちません。呼び出しがどう層を貫くかを図3に示します。

InMemoryGreetingRepositoryGreetingRepository (port)GetGreetingUseCasecomposition/container.tsapp/page.tsxInMemoryGreetingRepositoryGreetingRepository (port)GetGreetingUseCasecomposition/container.tsapp/page.tsximport getGreetingUseCasenew GetGreetingUseCase(repo)findDefault()findDefault()GreetingGreetingDto { message }
図3: greeting が全層を貫く呼び出しの流れ

page.tsxcomposition から組み立て済みのユースケースを受け取り、ユースケースは port 越しに findDefault() を呼びます。実際にそれを処理するのは InMemoryGreetingRepository ですが、ユースケースはその具体型を知りません — port という契約だけを見ています。最後に Greeting が DTO に変わり、{ message } として presentation へ返ります。

この縦切りは、新機能を足すときの手順としてそのまま一般化できます。docs/02_architecture/design/0001-ddd-clean-architecture-design.md の「How to Extend」は、新しい capability(例として farewell)を加える手順を、内から外への6ステップとして定めています。(1) domain に entity/VO と repository port を足す → (2) application に port へ依存するユースケースを足す → (3) infrastructure に port を実装する adapter を足す → (4) composition で adapter をユースケースに結線する → (5) presentation のページ/ルートからユースケースを呼ぶ → (6) tests(domain の単体 + stub を使ったユースケース + adapter)を書く。文脈ゼロのエージェントにとって、これは「新機能をどう足すか」の決定論的なレシピになります。どの層に何を、どの順で置けばよいかが手順として決まっているため、構造を毎回設計し直す必要がありません。

疎結合の payoff も、この縦切りから直接出てきます。同じ design doc が明記するとおり、既存 capability の backing store を差し替えるときは、step 3(同じ port を実装する新しい adapter を書く)と step 4(composition の向き先を変える)だけで済み、domain とユースケースは一切変わりません。in-memory から database や remote API へ store を載せ替えても、port という契約が同じである限り内側の層は不変です。この差し替えやすさこそが、依存方向を守ることの見返りです。

4. なぜ縦横がエージェントの精度を上げるか

新人ロボットが、大きな冷蔵庫ではなく小さな箱(stub)から味見しているイラスト
本物の冷蔵庫を運ばなくても、小さな箱一つで味見できます。ポートという約束さえ守れば、それで十分です。

縦と横が揃うと、エージェントの編集が局所的で・安全で・確かめやすくなります。横の隔離は他者の作業との干渉を断ち、縦の層分割は一つの変更の影響範囲を層の内に閉じ込めます。文脈ゼロの新人にとって決め手になるのは、「どこを触れば良く、どこを触ってはいけないか」が構造そのものから読み取れることです。port を変えれば契約が変わると分かり、adapter を差し替えても domain は無傷だと構造が保証してくれます。

port パターンの恩恵は、テストの書きやすさにそのまま現れます。ユースケースは port にしか依存しないため、その単体テストに mock ライブラリは要りません。port を満たすインラインの object literal を stub として渡すだけで足ります。たとえるなら、本物の冷蔵庫を運び込まなくても、「中身を一つ返すだけ」の小さな箱を一つ手渡せば味見ができる、という具合です。実際に src/application/get-greeting-usecase.test.ts はこう書かれています。

const stub: GreetingRepository = { findDefault: async () => Greeting.create('Hi there') };
const useCase = new GetGreetingUseCase(stub);
expect(await useCase.execute()).toEqual({ message: 'Hi there' });

mock のセットアップも特別な道具立てもなく、契約を満たす最小のオブジェクトを一行で渡すだけで、ユースケースを隔離して確かめられます。これは port が domain 側の契約として独立しているからこそ成り立ちます。変更の影響範囲が層で限られ、テストが軽く書けるという二つの性質が、文脈ゼロのエージェントでも安全に・確信を持って編集を進められる土台になります。精度は、賢いプロンプトからではなく、こうした構造から生まれます。

5. AC 検証 — 自分で正しさを確かめる仕組み

縦横で安全な編集が用意できたら、最後は変更の正しさを本人が確かめる工程です。このリポジトリは受け入れ条件(AC)の検証を、決まった順序の quality gate として持っています。順序の考え方はスタックに依存しません — runtime → 整形 → lint → 型チェック → アーキテクチャ境界 → API契約 → テスト → ビルド → docs という段階で並べ、本リポジトリではこれを pnpm スクリプトで実行します。.claude/skills/quality-gates が定める順序は check:runtime → format → lint → typecheck → check:architecture → check:api → test → build → check:docs で、fail-fast — 最初に失敗した category で止まり、直し、その gate から再実行する — を原則とします。順序には理由があります。runtime と compilation 系のチェックは安く走り、環境 drift やよくあるミスを捕まえるため先に置きます。テストと build はコストが高いので後に回します。これを図にすると図4になります。

fail

該当gateから再実行

format

lint

typecheck

test

build

完了可

停止して修正

図4: quality gate の fail-fast パイプライン

format から build へ一直線に進み、いずれかの gate が失敗したらそこで止まって直し、その gate から再実行します。安いチェックを前に、高いチェックを後に並べることで、ありがちな失敗を最小コストで早く弾く作りです。

この gate がローカルだけのものでないことが大事です。.github/workflows/ci.ymlpnpm install --frozen-lockfile のあと pnpm lintpnpm typecheckpnpm testpnpm build を順に実行しており、ローカルの gate 順序とそろっています。つまりローカルでゲートが通れば、おおむね CI も通ります。ただし正直に分けておくと、format は CI のステップには含まれず(ローカルでの自動整形が前提です)、後述の a11y / visual テストも CI の外にあります。CI が機械的に守るのは runtime・lint・typecheck・API・docs・coverage・build の7つで、それ以外はローカル実行に委ねられています。

テストは層に応じて高度を変えます。.claude/rules/backend.md の方針は次のとおりです。

新しい振る舞いを足すときの流れは、tdd-workflow スキルが定める Red → Green → Refactor です。先に失敗するテストを書き(Red)、最小の実装で通し(Green)、それから整えます(Refactor)。テストを先に書くことが、AC を「あとで確かめるもの」ではなく「最初に決めておく契約」に変えます。

frontend にも AC の自動検証があります。tests/e2e/responsive-home.spec.ts/ を mobile 360px / tablet 834px / desktop 1070px の3つの viewport で撮影し、baseline の screenshot と比べます(pnpm test:visual で実行する Playwright のレスポンシブ snapshot 検証です)。tests/e2e/accessibility-home.spec.ts は axe-core で / を検査し、WCAG 2.0/2.1 の A/AA に対する明白な違反を、actionable な違反リストとして失敗させます。同じ spec は、すべての focusable な要素について keyboard focus が当たること(focus() 後に toBeFocused)と、44px 目安の touch target を満たすことを確かめます(pnpm test:a11y)。.claude/commands/pr-check.md の pr-check は、標準ゲート列(check:runtime → format → lint → typecheck → check:architecture → check:api → test → build → check:docs)を PR 前確認の基準にし、いずれか失敗すれば PR 作成に進みません。pnpm lint の中でも check:architecture が走るため、レイヤー違反は早い段階で検出されます。Traefik で worktree ごとの E2E 環境を使う場合は、BASE_URL=http://<branch-name>.<app-name>.localhost を付けて Playwright の対象を明示します。

ここで第1部から引き継いだ正直さを、この柱の統制にも当てはめておきます。統制の効き方は三段階で分けられます。

第一段階は enforced(機械的に強制) です。quality gate のローカル実行と CI(ci.yml)の lint・typecheck・test・build は、ツールとパイプラインが仕組みとして走らせます。ここは機械が守る層です。

第二段階は enforced by convention / documented(規約・常時ロードで強制) に位置づくものがあります。レイヤーの依存方向がそれです。依存方向は、依存境界チェッカー(dependency-boundary checker)や linter の import 境界ルールで機械的に縛れます — 例として biome の import 制限ルール、ESLint の boundaries プラグイン、import-linter(Python)、dependency-cruiser(JS/TS)、ArchUnit(JVM/.NET)などがあります。ただし実際に biome.json を確かめると、import の境界を縛る lint ルールは設定されておらず、本リポジトリでは pnpm check:architecturepnpm lint で検出します。これはドキュメント(.claude/rules/architecture.md の層テーブルと非交渉事項)と型システムの契約(本リポジトリは TypeScript の implements)、そして唯一の結線点である src/composition/container.ts によって支えられています。機械的な拒否ではなく、文書と型と単一の結線点による convention 段階の統制です。test:a11y / test:visual が CI の外にあり、ローカル実行に委ねられている点も、同じく convention 段階にとどまります。

第三段階は documented・aspirational(文書化・努力目標) です。pre-commit / pre-push hooks や CI で gate を機械化する手段はスタックに依存しませんが、.claude/settings.jsonhooks は空({})で、GitHub 側の branch protection / required review の強制が残っています。どこまでが機械で守られ、どこからが規約と文書に委ねられているかを正直に分けておくことが、このリポジトリを自分の文脈へ移すときの、現実に即した地図になります。

6. この柱の両立まとめ + 次部への橋渡し

柱2は、横と縦と検証を一つに束ねることで、精度と成果を同時に押し上げます。精度は、隔離(worktree)と gate と型と test から来ます — 各作業が main から切り離され、変更の正しさが機械的に確かめられ、層が編集の影響を閉じ込めます。成果は、並列(worktree)と小分割(feature 単位)と決定論的レシピ(How to Extend の6ステップ)から来ます — 複数のタスクがぶつからず同時に進み、新機能の追加手順が決まっているから速いのです。同じ縦横の整備が、精度の方向と成果の方向へ同時に枝分かれする — これが第1部で示した「両立」の因果を、ワークフローと環境の層でもう一度なぞった姿です。横・縦・検証がそれぞれ精度と成果へ効くようすを図5にまとめます。

横: worktree 並列

精度

縦: レイヤード

検証: gate + test

成果

図5: 横・縦・検証が、精度と成果の両方を同時に押し上げる

ここまでで、新人が安全に並行して動き、自分の変更を自分で確かめる仕組みは揃いました。残る問いは、これらの仕組みをエージェントに自走させる枠組みです。次回はいよいよ最終の第4部、柱3「コーディングエージェントハーネス」です。ここまで整えた SSoT とワークフローを、エージェントが自分で実行できる形にどう翻訳していくのか、連載の締めくくりとして、いちばん面白いところをじっくり見ていきます。

第4部 コーディングエージェントハーネス — 知識とワークフローを、エージェントが実行できる形に

本シリーズ全4部の第4部(最終部)。

手引きと道具箱、大きさの違う専門家ロボット、レールの先に届いた成果物のイラスト
手引きと道具箱、仕事の重さで替わる専門家チーム、そしてレール。新人はこれで自走して仕上げまで運びます。

TL;DR

知識とワークフローを、エージェントは「自分で」実行できるか

第2部では開発ナレッジをどこに単一の正として置くか(柱1: SSoT)を、第3部では複数タスクをどう安全に並行で作るか(柱2: ワークフローと環境)を扱ってきました。ただ、そこで整えた知識とワークフローは、まだ人間が読むための文書として置かれているだけです。最後に残る問いはこうです。これまでの2部で整えた知識とワークフローを、エージェントが自分でロードして実行できるでしょうか。

人が書いた手引きが、歯車を通してエージェントが走れるレールと道具に変わるイラスト
ハーネスは、人が読む手引きを、エージェントが自分で実行できる形に翻訳します。

この第4部が扱う柱3、コーディングエージェントハーネスは、その問いに答えるレイヤーです。ハーネスとは、柱1のSSoT・ルールと柱2のワークフローを、エージェントが自分でロードして実行できる形に訳しなおす仕組みのことです。人間の新人にたとえるなら、初日に渡すオンボーディング資料と、その日から乗って走れる実行レールを兼ねたものにあたります。資料があるだけでは動けませんし、レールがあっても何を守るべきか知らなければ脱線します。ハーネスはその両方を、エージェントが取り込める形で同じ場所に置きます。

この柱は、シリーズを貫く「精度と成果の両立」の両側に効きます。

観点 この柱の寄与
精度 SSoT・ルールをエージェントに確実にロードし、gate と敵対的レビューで外れを抑える
成果 autopilot の自走、モデル階層、サブエージェント並列でタスクあたりのコストと人手を減らす

精度の側では、第2部で整えたSSoTとルールを「確実にロードする」経路と、第3部の品質ゲートに加えて敵対的なレビューを別レーンに置く仕組みが、外れを抑えます。成果の側では、後で述べる autopilot の自走、タスクの重さに応じたモデル階層、サブエージェントの並列が、タスクあたりにかかるコストと人手を減らします。一つのハーネス整備が、ここでも二つの効果へ同時に枝分かれしていきます。

1. オンボーディング — エージェントの「初日の必読」

起動するたびに、必読のルールが自動で新人ロボットに届くイラスト
起動と同時に「初日の必読」が自動で届きます。毎回、誰の手も借りずに。

人間の新人が初日にまず目を通すべき文書があるように、エージェントにも最初に読む文書群があります。このリポジトリでは、それが AGENTS.mdCLAUDE.md、そして .claude/rules/ 配下に置かれた always-loaded なルール群です。

柱1で扱ったとおり、これらが「何を・どう書くか」の正を持っています。ここで第4部として強調したいのは、その文書群をエージェントがどう取り込むかという見方です。.claude/rules/00-core-invariants.md の Single Source of Truth テーブルが、アーキテクチャとプロセスを CLAUDE.md に、エージェント運用マニュアルを AGENTS.md に、レイヤーモデルを .claude/rules/architecture.md に、というかたちで正の在処を一つに指しています。エージェントは、まずこの索引から自分が立つべき文脈の全体像をつかみます。

オンボーディングの核心は、.claude/rules/ が always-loaded として扱われる点にあります。always-loaded とは、はっきり「これを読め」と指示しなくても、エージェントが動くたびにその中身が毎セッション自動で文脈に入る、という意味です。レイヤーモデル(architecture.md)、コア不変条件(00-core-invariants.md)、プラン・レビュー(plan-review.md)、バックエンド規約(backend.md)といった規約が、指示を待たず常にエージェントの視界に居続けます。人間の新人なら入社後しばらく規約を体に入れるまで時間がかかりますが、エージェントにとっての「初日の必読」は、毎回の起動とともに自動で配られます。立ち上がりコストが大きく下がるのは、この常時ロードの結果です。

2. vendored ハーネスの全体像

オンボーディング文書の先に、エージェントが実際に手順とツールを取り出す本体があります。それが .claude/ 配下のハーネスです。このリポジトリは、ルール(9)、スキル(10)、サブエージェント定義(5)、スラッシュコマンドのワークフロー(5)を、外部の install を参照することなく、self-contained にリポジトリへ vendor しています。CLAUDE.md の Harness 節はこれを次のように明言します。

This repo vendors a self-contained AI-agent harness under .claude/: always-loaded rules, on-demand skills, sub-agent definitions, and slash-command workflows are all checked into the repository (not referenced from an external install).

self-contained に vendor することの意味は、柱の独立性そのものです。誰がクローンしても、外部ツールのインストール状態によらず、同じハーネスがそこにあります。エージェントの振る舞いを決める手順が、コードと同じリポジトリの中で版管理され、PR でレビューされ、誰の環境でも同じように再現されます。

図1は、この self-contained なハーネスと、エージェントがそれをどう取り込むかを示しています。

.claude/ : self-contained / vendored

CLAUDE.md / AGENTS.md (入口)

rules/ : 9 (always-loaded)

skills/ : 10 (on-demand)

agents/ : 5 (sub-agents)

commands/ : 5 (slash)

コーディングエージェント

src/ 実装 と PR

図1: self-contained な .claude ハーネスとその取り込み

入口の CLAUDE.md / AGENTS.md がハーネス全体への参照を張り、その中の rules・skills・agents・commands がそれぞれエージェントへ渡されます。rules は常時ロードで、skills/agents/commands は必要に応じて呼び出されます。最後にエージェントは src/ の実装と PR を生み出します。索引(入口)から手順(ハーネス)を経て成果(実装・PR)へ、という一方向の流れが一目で見て取れます。

ここで一点、ドキュメント間の書きぶりをそろえておきます。harness guide(docs/03_guides/autonomous-coding-harness.md)には「この skeleton では .claude/rules/* のみが checked in で、skills・agents・commands は周囲のハーネスから渡される」という趣旨の記述があります。これは最小の skeleton 版を想定した説明であり、本リポジトリはそれと食い違うわけではありません——本リポジトリは skills・agents・commands までを含む完全版を実際に vendor している、という関係です。第1部で「ガイドはより最小の skeleton 版を説明しており、本シリーズは実際にvendorされた完全なハーネスを基準に読み解く」と約束したとおり、ここでも基準は実体のハーネスに置きます。

3. Skills(10・on-demand)— 知識とワークフローの手順書

棚から必要な一冊だけを取り出す新人ロボットのイラスト
必要なときだけ、その手順書を一冊取り出す。これが on-demand のスキルです。

Skills は、エージェントが必要なときに呼び出す手順書です。always-loaded なルールが「常に守るべき決まりごと」だとすれば、Skills は「ある作業をするときに開く手順書」です。常時ロードしておくには重すぎる手順を on-demand に切り出すことで、エージェントの文脈を必要なときだけ厚くできます。.claude/skills/ 配下の10件は次のとおりです。

Skill Purpose
autopilot Autonomous task → PR loop (plan, implement, verify, open a PR)
quality-gates Local gate sequence + fix order before opening a PR
tdd-workflow Red → Green → Refactor cycle with the pnpm gates
ddd-clean-architecture DDD + Clean Architecture layer patterns and persistence boundaries
ci-debug Triage and fix CI failures via gh run and local reproduction
pr-creation PR conventions, body template, and pre-PR checklist
issue-creation Turn feedback into well-structured GitHub issues
context-optimization Keep working context lean during long sessions
gh-cli GitHub CLI reference for issues, PRs, Actions
mermaid-diagram-designer Information design for Mermaid diagrams

これらは柱1(書き方)と柱2(ワークフロー)を訳しなおしたものとして整理できます。ddd-clean-architecture はレイヤーパターンと永続化境界を、tdd-workflowquality-gates は品質の作り方とゲートの順序を、pr-creationissue-creation は GitHub 上の規約を、それぞれエージェントが実行できる手順に落としています。筆頭の autopilot が、それらを束ねてタスクからPRまでを一気に動かす自走ループです。次の節でこのループをくわしく見ます。

4. autopilot ループ(Phase 0-5)— 自走の中核

autopilot skill(.claude/skills/autopilot/SKILL.md)は、一つの十分に切り分けられたタスクを、idea から pull request まで、決められた6つのフェーズで動かします。フェーズは順番に進め、QAゲート(Phase 3)を飛ばすことは決してなく、ゲートが一つでも落ちている間は最終PRを開きません。

図2は、その Phase 0-5 のループを示しています。

fail

reject

Phase 0: Preflight (worktree)

Phase 1: Plan + review

Phase 2: Implement (TDD)

Phase 3: QA gates (必須)

Phase 4: Review (任意)

Phase 5: PR

図2: autopilot の Phase 0-5 ループ

左から右へ Phase 0 から 5 が進み、Phase 3 のゲート失敗と Phase 4 のレビュー却下は、どちらも実装フェーズ(Phase 2)へ点線で戻ります。前進は一直線ですが、品質が満たないときだけ実装へ巻き戻る、という流れです。各フェーズの中身は次のとおりです。

このループの成果の核は、idea から PR までの人手の介在を減らすことにあります。タスクを渡せば、計画・実装・確認・PR作成までが一つの自走ループで進み、人間がフェーズごとに細かく口を出す必要がありません。

精度の核は、その自走を「安全に」成り立たせる三つの境界です。第一に、Phase 3 のゲートが必須であり、落ちている間は完了を宣言できません。第二に、Phase 1 の plan-review が、実装の前に致命的な前提崩れやアーキテクチャ違反を捕まえる機会を置きます。第三に、worktree 境界です。autopilot の Hard Boundaries は「Never implement directly on main from the repository root」とはっきり書き、作業を必ず隔離された worktree とフィーチャーブランチに閉じ込めます。速く自走するからこそ、これらの境界がなければ速いペースで脱線します——ゲートとレビューと worktree は、その脱線を構造として抑える仕組みです。

5. Agents(5・サブエージェント)とモデル階層 — 専門家チーム

autopilot が一つのループだとすれば、Agents はそのループの中で呼び出せる専門家チームです。.claude/agents/ には5つのサブエージェントが定義され、それぞれにモデルと使えるツールが割り当てられています。割り当ての勘所は、タスクの重さに応じてモデルを使い分ける階層の形です。仕事の重さで担当を替える、というのに近いものです。軽い調べごとは身軽な担当に任せ、重い判断は腕の立つ担当に回す、という分け方です。

Agent Model Tools(要約) Role
implementer sonnet Read/Write/Edit/Bash/Grep/Glob/Agent 実装(spec→plan→TDD→gates→commit)
repo-explorer haiku Read/Grep/Glob/git log,diff,show 読み取り専用の調査
test-runner haiku Bash/Read テスト実行・pass/fail報告
architecture-reviewer opus Read/Grep/Glob/git log,diff DDD+Clean Architecture の敵対的レビュー
security-reviewer opus Read/Grep/Glob/git log,diff secrets/OWASP 等のセキュリティ監査

図3は、このモデル階層と役割の対応を示しています。

opus: 敵対的レビュー

architecture-reviewer

security-reviewer

sonnet: 実装・書き込み

implementer

haiku: 高速・読み取り

repo-explorer

test-runner

タスクの重さで選択

図3: サブエージェントのモデル階層と役割

設計の狙いは二つの軸に整理できます。一つはモデル階層です。コードベースの調査(repo-explorer)やテスト実行(test-runner)のように速く回せばよい作業には身軽な haiku を、機能を組み立てる実装(implementer)には sonnet を、設計やセキュリティの判断を要する敵対的レビュー(architecture-reviewersecurity-reviewer)には重い opus を割り当てます。作業の重さにモデルの重さを合わせる right-sized cost の考え方であり、軽い作業に重いモデルを使って無駄にすることも、重い判断を軽いモデルに任せて精度を落とすことも、どちらも避けます。

もう一つの軸は、役割とツールスコープを分けることです。repo-explorer は読み取り専用で、ファイルを書き換えずテストも走らせません。implementer は書き込みとコマンド実行ができます。architecture-reviewersecurity-reviewer はレビューに徹し、読み取りと git の差分参照だけを持ちます。それぞれが自分の役割に要るツールだけを持つ、最小権限の形になっています。

この分けかたは精度と成果の両方に効きます。成果の側では、right-sized なモデル選びでタスクあたりのコストを抑えつつ、独立した作業を並列に走らせられます。精度の側では、敵対的なレビュー(DDD+Clean Architecture の境界違反を疑う architecture-reviewer、secrets や OWASP を疑う security-reviewer)を実装とは別レーンに置くことで、書いた本人がその場で自分を通してしまう事態を避けます。書く者とそれを疑う者を分ける——これは柱2で見たゲートの考え方を、エージェントのチーム編成としてもう一度かたちにしたものです。

6. Commands(5・slash workflow)

Commands は、エージェントを起動するための薄い入口です。スラッシュコマンドとして呼び出され、中身の手順は対応する skill に任せます。.claude/commands/ の5件は次のとおりです。

Command Purpose
autopilot Autonomous task-to-PR loop entrypoint
kickoff Start a new task — create a worktree, branch, read the spec
pr-check Pre-PR quality check — run pnpm gates and prepare a PR description
design-review Frontend/UI PR audit — tokens, narrative UI, responsive/a11y evidence
deps-audit Audit dependencies for vulnerabilities and updates

委譲

実行

/コマンド

commands/ (薄い入口)

skills/ (手順の本体)

実装 / PR / 監査

図4: コマンドは薄い入口に徹し、手順はスキルに渡す

たとえば autopilot コマンド(.claude/commands/autopilot.md)は、引数のタスクを読みとって autopilot skill に loop を任せるだけの薄い層です。コマンドは入口の体裁を整え、手順そのものは skill が持つ、という役割分担になっています。

このうち design-review には触れておきます。これはフロントエンド/UIのPR監査——デザイントークン、ナラティブUI、レスポンシブやアクセシビリティの evidence——を担うコマンドで、UI・デザイントークン・レスポンシブ挙動・アクセシビリティ・ナラティブUI・ビジュアル回帰・ブランドパッケージのいずれかを変更した場合に、PRを開く前の実行が強く求められます。大事なのは、その監査基準がコマンドとしてリポジトリに vendor されていることです。PRのレビュー基準がリポジトリと一緒に移動するので、誰がどの環境でUIを変更しても、同じ基準で監査されます。基準が個人の頭の中ではなくリポジトリに置かれていること——これが、UI品質を再現できる形に保つ鍵です。

7. 外部プラグイン層(OMC等)— self-contained を保ちつつ増幅する

ここまでのハーネスはすべてリポジトリに vendor されたものでした。一方で、率直に位置づけておくべき層がもう一つあります。oh-my-claudecode(OMC)のような、有志が公開している開発ガイド系のプラグインです。これらはリポジトリの中には参照が無く、ユーザーのグローバル設定に属する外部層です。各自が後から足す自分用の道具、と言い換えてもよいでしょう。

その証跡は、リポジトリ側の守りの設定に見て取れます。tsconfig.jsonexclude.claude.agents.codex.omc を並べています。これは、TypeScript のソースではないディレクトリや、外部ツールが生成物を書き出す場所を、TSのビルド対象から外しておくための衛生的な配慮です(.claude は vendor されたハーネス自身、.omc / .codex / .agents は外部ツールの出力先にあたります)。あくまで外部ツールの生成物をTSビルドに混ぜないための配慮であって、リポジトリがOMCを取り込んでいることを意味するわけではありません。実際、リポジトリの中にOMCへの機能的な参照はありません。

ここで役割分担をはっきりさせておきます。

この分けかたが効いているおかげで、二つのことが同時に成り立ちます。リポジトリは誰がクローンしても同じハーネスの状態を再現でき、その一方で各自は好みのプラグインで自分の生産性をさらに増幅できます。チームの再現性と個人の自由度が、互いを侵さずに両立します。

互いを侵さない

個人の上乗せ (外部・任意)

外部プラグイン (OMC 等)

チームの正典 (リポジトリ内・vendored)

rules / skills / agents / commands

誰が clone しても同じ状態を再現

各自の生産性を増幅

図5: リポジトリ内蔵の正典(チーム)と外部プラグイン(個人)は、互いを侵さず両立する

図6は、これまでの3本柱がどう噛み合うかを、シリーズ統合の見方で示しています。

常時ロード

gate / test

柱1: SSoT・ガバナンス (何を・どう書くか)

柱2: ワークフロー・環境 (どう安全に並行で作るか)

柱3: ハーネス (エージェントがどう自走するか)

精度と成果の両立

図6: 3本柱の統合と両立

柱1(何を・どう書くか)が柱2(どう安全に並行で作るか)の前提となり、柱2が柱3(エージェントがどう自走するか)へ流れ込み、柱3が精度と成果の両立を生み出します。点線が示すように、柱1のSSoT・ルールは常時ロードとして柱3に渡され、柱2のゲートとテストは柱3の自走ループに組み込まれます。三つの柱は直列に並ぶだけでなく、上流の柱が下流のハーネスへ常に流れ込む形になっています。

8. 3本柱の統合 + 実践チェックリスト

三つの柱の噛み合わせを、一段落でまとめます。柱1で開発ナレッジを単一の正として置き(SSoT)、柱2でその正の上に worktree 並列とレイヤード・アーキテクチャと品質ゲートを組み(ワークフロー・環境)、柱3でそれらをエージェントが自分でロードして実行できるハーネスへ訳しなおします。SSoT がルールとして常時ロードされ、ワークフローがゲートとして自走ループに組み込まれ、ハーネスがその全体を一気通貫で動かす——この連なりが成り立ったとき、第1部で立てた問いの答えは「はい」になります。三つの柱はそれぞれ精度と成果の両方に効きますが、つながることで、その効果は一本の流れとして増幅されます。リポジトリ整備という一つの投資が精度と成果の双方を同時に押し上げる、というシリーズの中心の主張が、ここで一つの仕組みとして閉じます。

これを自分のリポジトリに入れたい読者のために、現実的な順序で導入チェックリストを示します。考え方は、機械的に縛れるもの(enforced)から始め、規約・常時ロードで縛るもの(enforced by convention)を重ね、最後に文書化・努力目標(documented / aspirational)として残りを置く、という三段階の順序です。

  1. SSoT を決めるCLAUDE.mdAGENTS.md.claude/rules/docs/ の役割を分け、関心事ごとに「正はここ」を一つに決めます。
  2. agent-agnostic な入口を置くAGENTS.md は薄い bootstrap と SSoT Map に徹し、非 Claude エージェントが読むべきルールを明示します。
  3. 常時ロードされる不変条件を作る — worktree、依存方向、Security NEVERs、plan-first、issue status、frontend governance などを rule files に分けます。
  4. worktree と issue status で並列性を守る — root の main を統合専用に保ち、status:in-progress を重複作業ガードにします。
  5. 標準ゲートをローカルと CI に通すcheck:runtime → format → lint → typecheck → check:architecture → check:api → test → build → check:docs を標準順にし、pnpm lint でも architecture boundary を検出します。
  6. ハーネスを repo-vendored にする — rules、skills、sub-agents、commands をリポジトリ内に置き、PR でレビューできるチームの正典にします。
  7. 自走ループを PR で閉じる — autopilot 的な Preflight → Plan → Implement → QA → Review → PR を定義し、外部プラグインは正典の外側に置いて個人の増幅レイヤーとして扱います。

シリーズ全体を一文で締めくくります。優秀だが文脈ゼロの新人=AIエージェントが、すぐ精度高く自走できるリポジトリは、人間の新人にとっても最高のオンボーディング環境です。エージェントのために整えた索引・ワークフロー・ハーネスは、そのまま人間が迷わず立ち上がるための地図になります。精度と成果の両立は、特別なAIのための特別な投資ではなく、誰が来ても同じ場所から走り出せるリポジトリを準備する、という当たり前の投資の帰結なのです。

全4部にわたりお付き合いいただきありがとうございました。