この記事は playpark Blog からの転載です。
この記事で分かること
- 手動タスク分解がなぜ破綻するか(3つの限界)
- ファイル境界で分割するアプローチを選んだ判断基準
- contract branchで型整合性を担保する設計思想
背景: こういう課題があった
Claude Codeでgit worktreeを使った並列開発。小さなIssueなら1つのworktreeで十分ですが、10ファイル以上に変更が及ぶ大きなIssueに出くわしたとき、「どう分割するか」「どう合流させるか」が急に難しくなりました。
タスクの分解は手作業。マージしたらコンフリクト。型が通らない。テストが落ちる。並列にした分だけ統合コストが増えて、結局トータルで遅くなる——この壁に何度もぶつかりました。
選択肢の検討
タスク分解にはいくつかのアプローチがあります。
| アプローチ | メリット | デメリット |
|---|---|---|
| 手動分解(目視) | 柔軟、文脈を反映できる | ファイル5つ超で依存関係を見落とす |
| 機能単位で分割 | 直感的、説明しやすい | 同一ファイルが複数タスクに登場しがち |
| ファイル境界で分割 | コンフリクトが構造的にゼロ | 機能横断の変更は1タスクが大きくなる |
なぜファイル境界分解を選んだか
限界1: ファイル重複によるコンフリクト
2つのworktreeで同じファイルを触った瞬間、マージコンフリクトが確定します。人間が目視で「このファイルはこっち担当」と分けるのは、ファイル数が5を超えたあたりから怪しくなる。
ファイル境界分解なら「各ファイルは必ず1タスクに所属」というルールで、テキストレベルのコンフリクトが原理的に発生しません。
限界2: 共有型の不在
タスクAがUserDTOを定義し、タスクBが同じUserDTOを別の形で定義する。マージ後に型エラーの嵐。
この問題に対してcontract branchパターンを導入しました。共有の型定義を先にcontract branchにコミットし、各タスクはそこから分岐する。
main ─── feature/issue-42-contract ← 型定義だけコミット
├── feature/issue-42-task1
├── feature/issue-42-task2
└── feature/issue-42-task3
「実装じゃなくインターフェースに依存せよ」——SOLID原則の依存性逆転をブランチ設計に適用した形です。
限界3: 統合テストの後回し
分解に集中するあまり、統合のことを考えていない。全タスク完了後にマージしたら、テストが12件落ちていて、どのタスクが原因か追えない。
解決策は「直せる順番でマージする」こと。依存のないタスクから先にマージし、各マージ後に型チェック・テストを走らせる。問題が起きても影響範囲が限定されます。
実装例
依存グラフ:
task1: depends_on: []
task2: depends_on: [task1]
task3: depends_on: []
→ マージ順序: task1 → task3 → task2(トポロジカルソート)
まとめ: どういう場面で使うべきか
ファイル境界分解が有効なのは「10ファイル以上の変更」「複数モジュールにまたがる実装」。逆に変更ファイル4未満なら、分割のオーバーヘッドが利益を上回るため単一worktreeが速い。
「並列化ありき」ではなく、分解して速くなるときだけ分解する。 この判断自体を自動化することが、worktree並列開発を実用レベルにするポイントでした。
さらに深掘りしたい方へ
この記事ではファイル境界分解とcontract branchを選んだ理由を解説しました。
【Claude Code】worktree並列開発の自動タスク分解と統合 - dev-decomposeで「分けて、束ねる」を設計する ではさらに:
- flow.jsonによる並列パイプライン全体の状態管理設計(auto-compact耐性・単一ライター原則)
- Agent Teamsとworktree並列の使い分け判断基準(調査 vs 実装タスク)
- dev-flow --parallelの7ステップ自動オーケストレーション全体像
playpark について
playpark LLC - 業務自動化・AI活用・Web開発