AWS Builder Center

AI-DLC Workflow V2の複数チームConstruction: teamでUnitを分担する

1つの機能群を複数チームで同時に作りたいとき、どう分担すればいいと思いますか。V2のConstructionには、Unitごとに所有者を分けて並行開発するための`Unit Ownership: team`という仕組みがあります。この記事では、その有効化条件からclaimしてlandするまでの手順と仕組みを見ていきましょう。シリーズ第28回。

Series: AI-DLC Workflow V2の解説 (31 articles)

  1. …
  2. 28
    AI-DLC Workflow V2の複数チームConstruction: teamでUnitを分担する This article
AWS Japan, Developer Specialist SA

1. はじめに

この記事はAI-DLC Workflow V2(以降V2)解説シリーズの第28回です。
第11回のConstruction Phaseの回では、設計を動くコードにするための構造(Unit・Bolt・並列実行)を扱いました。今回はその先にある「複数チームで同じConstructionを分担して進める」やり方に踏み込みます。
この記事を読み終えると、V2で複数チームがそれぞれのUnit(Unit of Work、独立して開発できる作業単位)を並行して開発するときの仕組みと、開始から統合までの再現可能な手順が分かります。

2. 課題: なぜ複数チームで進めたいのか

では、そもそもの動機から見ていきましょう。
Construction phaseは、Inceptionで分解された複数のUnitを、依存順に段階的にコードへ変えていく工程です。既定の進め方(後述するstage-major)では、1つのステージを全Unitについて実行し、次のステージへ進みます。ここでは全体が1つの連続した流れとして進みます。
ここで重要なのは、Unit同士に依存関係がなければ、本来は同時並行で開発できるという点です。認証UnitとカタログUnitが互いに独立しているなら、別々の担当が並行して手を動かせます。1つの流れの中で全Unitを順に処理していくやり方だけでは、この並行性を担当者(チーム)の単位で活かしきれません。
複数チームでのConstructionは、この並行性を「Unitの所有権」という形でチームに割り当てる仕組みです。各チームは自分が担当するUnitだけを進め、完成したものを1つのメイン(統合先)へ順に取り込んでいきます。V2ではこれをUnit Ownership: teamというモードで表現します。

3. 前提: 並列実行の基礎(Bolt・swarm・worktree・走査順)

複数チームの話に入る前に、V2の並列実行の基礎を簡潔に整理しましょう。詳しい仕組みは第11回のConstruction Phaseの回 で扱っているので、ここでは今回の理解に必要な範囲にとどめます。
  • Bolt: Delivery Planning(2.9)で計画されるConstructionの配送スライスです。1つ以上のUnitに、完成の定義(Definition of Done)と所有者が紐づきます。実行時のUnitのまとまり(バッチ)はunit-of-work-dependency.md(2.7)から再計算されます。
  • swarm / worktree: Unitを並行してコード生成するとき、V2はUnitごとのgit worktree(1つのリポジトリから派生する独立した作業ツリー)を切り、そこで生成・検証を行う経路を持ちます。BOLT_STARTED / BOLT_COMPLETEDはこのswarm / worktree経路で記録され、既定のゲート付き実行では記録されません。
  • 走査順(stage-major と unit-major): 既定はstage-majorで、1つのステージを全Unitについて実行してから次のステージへ進み、Code Generation(3.5)が最後に全Unitについて走ります。状態ファイル(ワークフローの現在位置を記録するaidlc-state.md)の## Runtime StateにConstruction Iteration: unit-majorが記録されると、走査はunit-majorに変わります。Unitごとに、そのUnitの設計ステージ(3.1〜3.4)を経てコード生成(3.5)まで進めてから、次のUnitに移ります。最初の動くコードが、全Unitの設計を待たずに1つのUnitの設計の後に生まれるのがunit-majorです。
ここで押さえておきたいのは、複数チームのモードがunit-majorの上に成り立つという点です。次の節で見ていきます。
以下の図は、既定のstage-majorと、unit-major(team所有)の走査順の違いを示したものです。

4. 仕組み: team所有(Unit Ownership: team)

では、複数チームの中核であるUnit Ownership: teamを見ていきましょう。
Unit Ownership: team(以降 team所有)は、Constructionの各Unitに、それを担当するチームを割り当てるモードです。既定では全Unitを1つの流れとしてAI(developer agent)が進めますが、team所有では各Unitを担当するチームがそのUnitをclaim(取得)して独立に開発し、完成したものを1つずつ統合先へ取り込みます。担当は対等な複数チーム(たとえば認証チームとカタログチーム)に分かれ、上下関係を前提とはしません。

4.1 有効化の条件

Unit Ownership: teamは、次の条件がそろったときにだけ有効です。
  • unit-major反復順序であること: Unit Ownership: teamはunit-majorとの組み合わせでのみ妥当です。stage-majorのままでは有効になりません。
  • ワークスペースルートがソースリポジトリであること: team所有のUnitは単一リポジトリを前提とします。team所有の設定は、兄弟リポジトリが記録されたintent(複数リポジトリ構成)に対しては、状態を変更する前に拒否されます。
  • 実装対象のUnitが1つ以上あること: Units Generation(2.7)でUnitが分解され、依存関係(どのUnitがどのUnitに依存するか)が定義されている状態が前提です。Unitが1つも無い構成では有効になりません。
  • まだどのチームもUnitの作業を始めていないこと: 所有モードは、チームがUnitをclaim(担当開始)する前に設定します。すでにチームのUnit作業が始まっている状態では設定できません。

4.2 設定のタイミング

有効化は、Construction フェーズの手前にある Delivery Planning(2.9)ステージの対話を通じて記録されます。読者が自分でコマンドを打つのではなく、ステージが体制に関する質問(Construction をどう進めるか、複数チームで持つか、チェックインの頻度はどうするか)を尋ね、その回答に応じてワークフローが状態ファイル(aidlc-state.md)に設定を記録します。
記録される順序は決まっています。先に反復順序を unit-major にし、次に所有モードを team にします。Construction Iterationが正確にunit-majorのときだけ team 所有が有効になり、未設定やstage-majorのままでは有効になりません。複数チームで進める選択をしたときに、まだ unit-major でなければ、この前提への切り替えを確認したうえで両方が記録されます。
なお、team 所有を使えるのは、Units Generation と Delivery Planning を実行するスコープ(enterprise・feature・mvp・classic・workshop)です。これらのステージを実行しないスコープでは、Unit の分解や体制の設定の場面が登場しません。

4.3 ## Unit Progressテーブル

Unit Ownership: teamのモードでは、nextのたびにエンジンが## Unit ProgressテーブルをUnit DAG・成果物カバレッジ・ライフサイクル/レビューのレシート・ゲートイベントから書き直します。このテーブルはエンジンが所有する派生的な投影であり、手で編集しても上書きされ、進行の判定には使われません。ownerセルには実際のgitネイティブなclaimが反映されます。
テーブルの列はConstructionのper-unitステージと、そのUnitのゲートを表します。チェックボックスの記号は## Stage Progressと同じ語彙([ ]未着手、[-]進行中、[?]承認待ち、[R]修正中、[x]完了、[S]スキップ)を使います。Stage Progressのチェックボックスは、完了したUnit列から派生する形になります。

4.4 チーム単位ゲートのリズム(per-stage と unit-end)

team所有では、既定の(unit-majorで最後にまとめて出る5つの)遅延ゲートが、Unitごとのゲートに置き換わります。ゲートのリズムにはUnit Gate Rhythmという2つの選択肢があります。
  • per-stage(既定): 1つの(stage, Unit)の組が完了するたびに、エンジンがそのステージをgate: trueかつunit_gate: per-stageで再度出し、そのUnitが次へ進む前にゲートを開きます。
  • unit-end: すべてのper-unitの作業ビートをgate: falseのままにし、そのUnitの最後の有効・非スキップのper-unit Constructionステージの後に、unit_gate: unit-endのゲートを1回だけ出します。
Unit Gate RhythmはUnit活動が始まる前に設定します。claimの時点で--rhythm per-stageまたは--rhythm unit-endを指定してそのclaimに固定することもでき、省略するとワークフローで確定したリズムが使われます。
以下の図は、複数チームがそれぞれのUnitを並行して進める全体像です。Unit間の依存関係と、どのチームがどのUnitを担当し、完成物がmainへ取り込まれるかを示します。

5. 手順: claimからlandまで

概念を理解したところで、チームがUnitを担当してから統合先へ取り込むまでの流れを見ていきましょう。V2ではこの流れを、claim → 実装 → publish → pin → merge gate → landというライフサイクルで扱います。ここでlandとは、レビューと承認を通過したUnitの完成物を、統合先ブランチ(main)に正式に取り込んで確定する操作を指します(GitHubでいうマージに近い最終ステップです)。同様に、claimはUnitの担当を取得すること、publishは完成した候補を公開すること、pinはその候補を固定・検証することを指します。
ブランチの扱いも先に押さえておきましょう。各チームは、claimによってそのUnit専用にスコープされたチェックアウト(作業コピー)で開発を進めます。完成したらpublishで候補を公開し、統合先のmainへはlandで取り込みます。このlandはマージ戦略で行われ、pinで固定したレビュー済みコミットがそのままmainの直接の親として残ります(squashやrebaseに置き換える判断は受け付けません)。mainが先に進んで共有ファイルが衝突した場合は、チームの作業を現在のmainにrebaseして解決し、再度publish・pinをやり直します。
以下の図は、そのライフサイクルの流れです。
5.1 claim(Unitの取得)
チームは、自分が担当するUnitを取得します。/aidlc(--resumeで再開したものを含む)のセッションで、ワークフローがclaim可能・claim済み・待機中のUnitを提示するので、担当するUnitを選びます。選んだ回答を受けて、ワークフローがそのUnitの担当を記録します。担当は先着1つだけが成立し、複数チームが同じUnitを同時に選んでも、担当者は1チームに決まります。担当時に付けるチーム名は人間可読な表示ラベルで、Unitの依存や(必要な場合の)walking skeletonが完了するまで担当は取得できません。取得後、そのチェックアウトはその担当Unitだけを対象に進みます。

5.2 実装(コード生成)

担当したチェックアウトは、そのUnitの有効なper-unit Constructionステージとゲートだけを実行します。担当チームは自分のUnitの実装に集中でき、他チームのUnitには干渉しません。

5.3 publish(候補の公開)

Unitの作業が完了したら、追跡している成果物をコミットし、ワークフローに公開を指示します。公開は「このコミットが自分のUnitのマージ候補です」と登録する操作で、統合(マージ)そのものは行いません。候補コミットには、担当と実装の両方の履歴が保持されます。

5.4 pin(候補の固定・検証)

統合を司るmain側で、公開された候補を固定します。固定では、候補の正確なコミット(OID)を記録し、そのコミットから成果物・各種レシート・レビュー判定・状態などの内容を直接読み取って検証します。マージや作業ツリーの作成はこの段階では行いません。

5.5 merge gate(人間による判断)

固定の後、main側でワークフローが、固定した候補と証跡の要約を1つの承認ゲートとして提示します。あなたは/aidlcセッションのこのゲートで、承認(approve)か却下(reject)を回答します。あなたの回答を受けて、ワークフローがその正確な判断を記録します。却下なら実装に戻り、承認ならlandに進みます。

5.6 land(mainへの取り込み)

承認されたら、固定された候補を統合先(通常はmain)へ取り込みます。取り込みはトランザクションとして行われ、固定されたgitの内容を先に反映し(mainが持つメタデータは保持)、次にUnitの状態を1回畳み込み、最後に監査・確定を記録します。取り込みはマージ戦略で行われ、固定したレビュー済みコミットがそのままmainの直接の親として残ります。
共有ファイルをmainと候補の両方が変更していた場合は、自動マージがクリーンでも、結果が固定候補と一致しない限り取り込みは拒否されます。その場合は、チームの作業を現在のmainにrebaseして解決し、再度公開・固定をやり直します。統合に関わる操作は、担当の記録が参照できない間は安全側に倒して失敗します(誤った取り込みを防ぐためです)。

6. 落とし穴・注意点

続いて、複数チームのConstructionで気をつけたい点を見ていきましょう。

6.1 Team Formation(1.5)は必須の前提ではない

複数チームで進めるなら、まずIdeationのTeam Formation(1.5)ステージを実行しなければならない、と考えたくなります。しかし、Unit Ownership: teamが要求するのはunit-majorであること・単一リポジトリであること・非空のUnit DAGがあること・チームUnit活動が未開始であることであって、Team Formationの実行ではありません。
これはスコープのステージ所属からも確認できます。workshop・mvp・classicの各スコープは、Unitを分解するunits-generationとDelivery Planning(delivery-planning)を実行(EXECUTE)する一方で、team-formationはスキップ(SKIP)します。つまり、Team Formationを走らせないスコープでも、Unit DAGは生成され、team所有の前提を満たせます。team所有はUnitの所有権とゲートの仕組みであって、チーム編成ステージの成果物に依存しません。

6.2 マルチリポジトリのintentでは使えない

前述のとおり、team所有の設定は兄弟リポジトリが記録されたintentを、状態を変更する前に拒否します。複数リポジトリ構成での運用そのものは、この記事の対象外です。team所有を使うintentは、ワークスペースルートがソースリポジトリである単一リポジトリの構成にしておきます。
この可否は「intentに兄弟リポジトリが記録されているかどうか」で判定されます。したがって、repos.jsonなどで複数リポジトリ構成にしたintentでは、事前に設定していてもteam所有は使えません。マルチリポジトリを扱うintentはsoloのままにし、team所有を使いたいintentは単一リポジトリの構成にします。
自分の構成がどちらかは、次の基準で判断できます。判定の対象は「ワークスペースルートの直下に、.gitを持つコードリポジトリのサブディレクトリが複数横並びになっているか」です。aidlc/や.kiro/のようなAI-DLC側の管理ツリーは、この判定には数えません。したがって、ワークスペースルート自体が唯一のソースリポジトリで、その中にAI-DLCの記録や設定が置かれているだけの構成は「単一リポジトリ」扱いとなり、team所有を使えます。一方、ルート直下に別のコードリポジトリが横並びに存在する構成は「マルチリポジトリ」扱いとなり、使えません。

6.3 ## Unit Progressは手編集しない

## Unit Progressテーブルはエンジンがnextのたびに書き直す派生投影です。手で書き換えても上書きされ、進行やルーティングの判定には使われません。進行状況を変えたいときは、テーブルを直接編集するのではなく、claim・publish・land といった正規のライフサイクルとゲートを通します。

6.4 claimの整合はclaim時点のスタンプが基準

スコープ付きのルーティングとレシートの書き込みはオフラインファースト(claim時点のスタンプが権威)です。レジストリの生存確認はfork/releaseのようなclaim-sensitiveな境界でのみ再確認されます。リモートが利用できないときは警告してスタンプから続行しますが、オンラインで陳腐化・release済みのattemptは拒否されます。担当の解除(release)はmain側から行い、refを削除せずに世代を進めるtombstone(削除済みを表す墓標的なref)を残します。

7. まとめ

複数チームでのConstructionは、V2のUnit Ownership: teamモードで実現します。要点を整理しましょう。
  • 前提: team所有はunit-majorの上に成り立ち、単一リポジトリ・実装対象のUnitが1つ以上あること・まだどのチームもUnitの作業を始めていないことを要求します。設定はDelivery Planningの対話を通じて、反復順序をunit-majorにしたうえでteam所有として記録されます。
  • 仕組み: nextのたびに## Unit Progressが派生投影として書き直され、ownerにgitネイティブなclaimが反映されます。ゲートのリズムはper-stage(既定)とunit-endから選べます。
  • 手順: 各チームはUnitをclaimし、実装し、publish → pin → merge gate → landの順で統合先へ取り込みます。共有ファイルの衝突はcandidate-exact(固定候補と一致するかどうか)で判定され、一致しなければrebaseと再publishが必要です。
  • 設計上の注意: Team Formation(1.5)はteam所有の必須前提ではありません。workshop・mvp・classicのようにunits-generationを実行してteam-formationをスキップするスコープでも、team所有の前提は満たせます。
依存のないUnitを別々のチームが同時に進め、完成したものを1つずつmainへ取り込む。これが、V2が複数チームのConstructionを調整する形です。

Series: AI-DLC Workflow V2の解説 (31 articles)

  1. …
  2. 28
    AI-DLC Workflow V2の複数チームConstruction: teamでUnitを分担する This article
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article