基本概念

CodeDAG の仕組み

ワークフローとして書いた一連のタスクを、CodeDAG がどのようにキューに並べて実行し、エージェントに任せ、結果を手元に返すのか。

プライベートベータはまもなく開始します。CodeDAG はまだインストールできません。ウェイトリストに登録しておくと、招待を順次メールでお送りします。
GitHubで編集

依存関係のある一連の開発タスクをワークフローファイルに書いて CodeDAG に投入すると、あとは CodeDAG が手元のコンピューターのバックグラウンドで実行を進めます。依存関係に従って、タスクごとに新しい Claude Code または Codex のセッションを起動し、デフォルトではタスクごとのブランチで作業させます。タスクの結果はレビューを通ると下流に渡され、最後に 1 本の統合ブランチにマージされます。メインブランチは変更されません。レビューはデフォルトで自動的に通るため、予定どおりに進むかぎり、人の手が必要になるのは、自分で設定した手動レビューと、最後のメインブランチへのマージだけです。1 つのプロジェクトで同時に実行されるワークフローは 1 つだけで、あとから投入したものはキューで待ちます。

ワークフロー

目標が、1 つのエージェントセッションではうまくやり遂げられないほど大きい場合は、いくつかのタスクに分け、それぞれを 1 つのセッションに任せることになります。ただ、これらのタスクには依存関係があるため、手作業で順番にセッションを起動していくと、その間ずっと張り付いていなければなりません。そこで CodeDAG では、タスクと依存関係をあらかじめ 1 つのファイルに書いておき、依存関係に従った各タスクの起動は CodeDAG に任せます。このように 1 つのファイルに記述された一連のタスクが、ワークフローです。タスクをどの大きさまで分けるかは、タスクを分割する理由と、分割の目安を参照してください。

「ワークフロー」という言葉は、場面によって指すものが違います。よくあるのは、1 つのタスクをやり遂げるための一連の手順を指す使い方で、多くの場合、その手順はプロンプトやスキルのドキュメントに書かれています。こうした手順はたいてい順番に実行され、同じセッションの中で最後まで進むことが多く、手順同士は分離されていません。CodeDAG のワークフローは、これと 2 つの点で異なります。1 つは、粒度がより粗いことです。そうしたワークフロー全体でこなすタスクが、CodeDAG のワークフローでは 1 つのノードにすぎません。タスクの中で具体的にどう進めるか、どのツールを呼び出すかは、ワークフローの構造には現れず、そのタスクを実行するエージェントが自分で決めます。もう 1 つは、タスクを並列に実行でき、しかも互いに分離されていることです。どのタスクも新しいセッションであり、デフォルトではタスクごとのブランチで作業します。これは、前後に続けて実行されるタスクでも同じです。

タスクと依存関係は、有向非巡回グラフ(Directed Acyclic Graph、DAG)を形作ります。製品名の CodeDAG も、コマンドに出てくる dag も、ここから来ています。ドキュメントでは「ワークフロー」と呼び、コマンドでは dag と書きますが、どちらも同じものを指しています。

次の図は、よくあるダイヤモンド型のワークフローです。タスク 1 は仕様書を読み、実装するモジュールとインターフェースを契約としてまとめます。タスク 2 とタスク 3 はどちらもタスク 1 に依存し、一方は契約に沿ってテストを書き、もう一方は契約に沿って実装します。タスク 4 は両方が完了するのを待ってテストを実行し、すべて通るまで修正します。

flowchart LR  t1["タスク 1<br/>インターフェース契約を起草"] --> t2["タスク 2<br/>契約に沿ってテストを書く"]  t1 --> t3["タスク 3<br/>契約に沿って実装する"]  t2 --> t4["タスク 4<br/>テストを通す"]  t3 --> t4

ワークフローファイルにすると、次のようになります。

.codedag/dags/spec-to-code.yaml
tasks:
  - id: 1
    title: インターフェース契約を起草
    prompt: docs/spec.md を読み、実装するモジュールとインターフェースを docs/contract.md にまとめてください。
  - id: 2
    title: 契約に沿ってテストを書く
    dependencies: [1]
    prompt: docs/contract.md に沿って、各インターフェースのテストを書いてください。
  - id: 3
    title: 契約に沿って実装する
    dependencies: [1]
    prompt: docs/contract.md に沿って、これらのモジュールを実装してください。
  - id: 4
    title: テストを通す
    dependencies: [2, 3]
    prompt: すべてのテストを実行し、すべて通るまで失敗を修正してください。

この図には、一直線に並べるだけでは表せない段取りが含まれています。タスク 2 とタスク 3 が共有しているのはタスク 1 の契約だけで、互いには関係がありません。そのため、空いているワークスペースがあれば同時に実行できます。ワークスペースとは、タスクの実行場所になるコードのチェックアウトのことです。一方、タスク 4 は両方が完了するまで待たなければなりません。

誰が何を担当するか

ワークフローを投入したあとは、CodeDAG が実行を進め、タスクエージェントが各タスクをこなし、Git がすべての結果を保存します。予定どおりに進むかぎり、人が関わる必要があるのは 2 か所だけです。確認のために止めるよう自分で設定したノードと、最後のメインブランチへのマージです。無人実行が成り立つのは、このように役割分担がはっきりしているからです。

  • ユーザー:何をするかを決め、どのノードで止めて人が確認するかを決め、最後に結果をメインブランチにマージするかどうかを決めます。
  • オーケストレーター:cdg を操作する側で、ワークフローの作成、投入、進捗の追跡、レビューを担当します。オーケストレーターはユーザー自身でもかまいませんし、CodeDAG Guide プラグインを入れた Claude Code や Codex でもかまいません。後者は、ユーザーから目標の説明を受けて、代わりに cdg を操作します。この場合のオーケストレーターをオーケストレーションエージェントと呼びます。オーケストレーションエージェントが担うのはオーケストレーションであり、ワークフロー内のコードを書くのは、この場合もタスクエージェントです。方法はエージェントにオーケストレーションを任せるを参照してください。
  • CodeDAG:手元のコンピューターのバックグラウンドで動作し、ワークフローの実行を進めます。ワークフローをキューに並べ、各タスクにワークスペースとブランチを割り当て、タスクエージェントのセッションを起動し、タスクがいつ完了したかを判定します。そのうえで、ルールに従って結果を自動承認するか、止まってレビューを待ちます。結果は順にマージしていきます。
  • タスクエージェント:タスクの中でプロンプトを実行する、Claude Code または Codex のセッションです。どのタスクも新しいセッションであり、知っているのは自分のプロンプトと、自分がいるワークスペースの内容だけです。理由はタスクとセッションを参照してください。
  • Git:デフォルトの分離ブランチモードでは、各タスクの変更はそれぞれのタスクブランチに残り、ワークフロー全体の結果は 1 本の統合ブランチにマージされます。メインブランチは変更されず、いつマージするかは自分で決めます。

デフォルトの分離ブランチモードでは、ワークフローを投入してからの一連の流れは次のとおりです。

sequenceDiagram  participant O as オーケストレーター  participant C as CodeDAG  participant A as タスクエージェント  participant G as Git リポジトリ  O->>C: ワークフローを投入  Note over C: キューで待ち、<br/>順番が来たら実行を開始  loop 依存関係が満たされた各タスク    C->>G: ワークスペースとタスクブランチを割り当て、<br/>上流の結果をマージ    C->>A: 新しいセッションを起動し、<br/>プロンプトを送信    A->>G: タスクブランチで作業    C->>C: タスクの完了を判定    opt このタスクに手動レビューを<br/>設定している場合      C-->>O: 止まってレビューを待つ      O->>C: タスクをレビュー    end  end  C->>G: すべてのタスクのレビューが終わったら、<br/>統合ブランチにマージ  opt ワークフローに手動レビューを<br/>設定している場合    C-->>O: 止まってレビューを待つ    O->>C: ワークフロー全体をレビュー  end  Note over C: ワークフローがキューを離れ、<br/>次のワークフローが開始  O->>G: ユーザーが統合ブランチを確認し、<br/>メインブランチにマージ

図の各部分は、それぞれ専用のページで詳しく説明しています。タスクが新しいセッションでどのように実行されるかはタスクとセッション、タスクがどこで実行され、ブランチがどのように作られてマージされるかはワークスペースとブランチ、完了した結果がどのように認められるかはレビューゲートと自動承認を参照してください。

どのノードで人が確認するかは、自分で決めます。デフォルトでは、タスクもワークフローも自動承認されます。実行が止まって人のレビューを待つのは、自動承認をオフにした箇所だけです。それ以外では、結果が統合ブランチにマージされるまで、ワークフローは自動で実行を続けます。途中で止まるのは、CodeDAG だけでは対処できない状況になったときだけで、どこで止まったかはステータスからわかります(ステータスとサブステータスを参照)。ただし、これには前提が 1 つあります。タスクエージェントが、操作のたびにユーザーの同意を求めなくてよいことです。そうでなければ、タスクエージェントは自分のセッションの中で止まり、許可を待ちます。権限モードの選び方は、無人実行か有人実行かを決めるを参照してください。

投入、キュー、フェーズ

投入とキュー

1 つのリポジトリでは、ワークフローをいくつも続けて書くことがよくあります。どのワークフローも、同じコードと同じワークスペースを使います。分離せずに同時に実行すれば、ファイルやブランチが互いに干渉します。かといって、ワークフローごとにもう一段の分離を設けると、ワークスペースが何倍も必要になり、ワークフロー間で結果をもう一度マージする手間も生じます。一度に 1 つだけ実行するとしても、キューに並べておけなければ、誰かが張り付いて、前のワークフローが終わるたびに次を手動で起動することになります。

CodeDAG は、一度に実行するワークフローを 1 つに絞りつつ、先に投入しておけるようにしています。前のワークフローがまだ実行中でも、次のワークフローを投入して待たせておけます。投入済みのワークフローを投入順に並べた列が、キューです。先頭のワークフローが実行され、レビューを経てキューを離れると、次のワークフローが自動的に始まります。席を離れる前にいくつかのワークフローを順に投入しておけば、続けて最後まで実行させられます。並列に実行されるのは、1 つのワークフロー内のタスク同士だけです。

つまり、投入したからといって、すぐに実行されるとは限りません。cdg dag submit はワークフローをキューに入れるコマンドで、実際に実行が始まるのは、それより前のワークフローがすべて終了してからです。

ここでいう「終了」には、はっきりした意味があります。すべてのタスクの実行が終わっても、それはエージェントが作業を終えたと判断したというだけです。結果が使えるかどうかは、レビューを経て初めて決まります。レビューは自分でしてもよく、ルールに従って自動的に通すこともできます。デフォルトは後者です。ゲートの設定方法は、レビューゲートと自動承認を参照してください。ワークフローは、レビューの結論が出て初めてキューを離れ、次のワークフローに順番を譲ります。したがって、キューの先頭のワークフローが、レビュー待ち、一時停止、保留のように対処を待つ状態で止まっていると、後ろのワークフローはずっと待ち続けます。

フェーズ

投入とレビューという 2 つの操作によって、ワークフローのライフサイクルは 3 つのフェーズに分かれます。

  • planning(計画中):書いてあるものの、まだ投入していない段階です。ファイルは自由に変更でき、実行はされません。
  • submitted(投入済み):キューに入っている段階で、キューで待っているか、実行中か、実行が終わってレビューを待っているかのいずれかです。実行には投入した時点のファイルの内容が使われ、そのあとでファイルを変更しても、投入済みの実行には影響しません。
  • reviewed(レビュー済み):レビューの最終的な結論が出て、キューを離れた段階です。これ以上実行されることはありません。

フェーズは投入とレビューによって進み、順序は決まっています。タスクにも独自のフェーズがあります。タスクはワークフローと一緒に投入されますが、レビューはタスクごとに行われます。そのため、ワークフローがまだ submitted であっても、その中でレビューが済んだタスクは reviewed になります。

cdg status が表示するプロジェクトのステータスボードは、このフェーズごとにグループ分けされています。Planning Workflows にはまだ投入していないワークフローが並び、Submitted Workflows がキューそのもので、順に番号が付きます。Reviewed Workflows は、レビューが済んだワークフローの履歴です。

ステータスとサブステータス

ステータス

投入したあとは、たいていその場を離れています。戻ってきたときには、各タスクがどういう状況にあるかをひと目で把握したいはずです。フェーズでは、この問いに答えられません。フェーズが示すのは「どの段階まで進んだか」だけで、待機も、実行も、一時停止も、完了も、すべて submitted の中で起こるからです。そこで、投入済みのタスクにはもう 1 つ、ステータスがあります。ステータスは submitted フェーズの中だけを表すもので、タスクが今、待っているのか、実行中なのか、止められているのか、すでに終わっているのかを示します。

  • pending(待機中):実行されておらず、開始または対処を待っています。
  • in-progress(実行中):タスクエージェントが作業しています。
  • stopped(停止中):一時停止または強制停止され、その場で止まって再開を待っています。
  • done(完了):実行は終わりましたが、結果はまだレビューを受ける必要があります。

ステータスには通常の順序があり、これがタスクのライフサイクルにあたります。最初は pending で、上流のタスクと空きワークスペースを待ちます。ワークスペースが割り当てられると、新しいセッションが実行を始めて in-progress になり、作業が終わると done になります。レビューを通ると、reviewed フェーズに入ります。ただし、フェーズと違って、ステータスは一方向にだけ進むわけではありません。一時停止、強制停止、復旧のほか、レビューでタスクに修正を続けさせた場合にも、ステータスは前に戻ったり、別のステータスへ移ったりします。

サブステータス

ステータスを見るだけでは、自分が何かする必要があるかどうかまではわかりません。同じ pending でも、上流を待っているだけで放っておいてよいタスクもあれば、保留になっていて、対処しないかぎり止まったままのタスクもあります。そこで、各ステータスはさらにサブステータスに分かれ、タスクがそのステータスにある理由を示します。pending は、blocked(上流待ち)と on-hold(保留)に分かれます。blocked のタスクは、上流のタスクが完了して承認されるのを待っているか、空きワークスペースを待っていて、条件が整えば自動的に開始されます(上流が done で止まってレビューを待っている場合は、このタスクも待ち続けます)。on-hold は、タスクが保留になっていることを表します。たとえば、開始前にワークスペースで未コミットの変更が見つかった場合や、上流の結果をマージするときに自動では解決できないコンフリクトが起きた場合です。このときは、自分で対処してからでないと復旧できません。同じように、in-progress は、通常どおり実行中の working と、一時停止を受けて現在のステップを終えようとしている draining(ドレイン中)に分かれます。stopped は、一時停止された paused と、強制停止された killed に分かれます。すべての組み合わせとその意味は、状態の意味を参照してください。

戻ってきて状況を確認するとき、blocked、working、draining には介入する必要がありません。on-hold と stopped は、自分で対処してから実行を再開させる必要があります。実際にそうなったときは、トラブルシューティングで症状から調べてください。done のタスクは、手動レビューを設定している場合、結論が出されるまで待ち続けます。詳しくは自動承認を参照してください。

cdg status、cdg dag status、cdg task status は、それぞれプロジェクト、ワークフロー、タスクの 3 つの階層で、フェーズ、ステータス、サブステータスを表示します。ステータスボードに [in-progress] [working] のように 2 つ並んで表示されるもののうち、前がステータス、後ろがサブステータスです。ワークフローにも独自のステータスとサブステータスがあり、そのワークフローに含まれるすべてのタスクの状況をまとめて表します。cdg status のキューの各行に表示されるのがこれです。タスクが on-hold になっている具体的な理由は、cdg task status にだけ表示されます。

プロジェクト

1 台のコンピューターで、複数のリポジトリに CodeDAG を使っていることはよくあります。リポジトリ同士はコードもブランチも無関係なので、互いを待つ理由がありません。あるリポジトリで投入したワークフローを、別のリポジトリのワークフローの後ろに並べるべきではありません。一方で、1 つのリポジトリには、タスクを並列に実行するために、チェックアウトが複数あることも珍しくありません。元のリポジトリのほかに、git worktree や git clone で追加したチェックアウトがあり、これらは元のリポジトリとひとまとめに扱うべきものです。

CodeDAG は、こうしたひとまとまりのディレクトリを 1 つの単位として扱います。元のリポジトリをプライマリリポジトリと呼び、.codedag/ ディレクトリはそのルートに作られます。追加で作り、プライマリリポジトリに登録したチェックアウトをレプリカと呼びます。プライマリリポジトリとそのレプリカを合わせたものが、1 つのプロジェクトです。

キューも、ほぼすべての cdg コマンドも、プロジェクトを単位とします。プロジェクトが違えば、ワークフローはそれぞれのキューに並び、互いに影響しません。プライマリリポジトリ、いずれかのレプリカ、.codedag/ ディレクトリのどこでコマンドを実行しても、操作の対象は同じプロジェクトと同じキューです。まだ初期化していないリポジトリで実行した場合は、先に cdg init を実行するよう案内されます。タスクの実行時には、プライマリリポジトリと各レプリカが、それぞれ 1 つのワークスペースになります。

リポジトリは、cdg init を実行するとプロジェクトになり、レプリカもこのときに登録されます。レプリカは、あらかじめ自分で Git を使って作っておく必要があり、CodeDAG が代わりに作ることはありません。また、1 つのプロジェクトのレプリカは、すべて worktree か、すべて clone かのどちらかにします。どちらを選ぶか、どう準備して登録するかは、並列実行とワークスペースを参照してください。

ワークフローファイルは .codedag/dags/ に置き、プロジェクト設定と実行ログも .codedag/ の中にあります。このディレクトリは、コードと一緒にプロジェクトリポジトリにコミットされることはありません。理由はサイドカーリポジトリを参照してください。

1 つのワークフローが対象にするのは、1 つのプロジェクトだけです。複数のリポジトリにまたがる仕事では、リポジトリごとにワークフローを書いて、それぞれ実行します。リポジトリ間の連携は、自分で段取りします。

サイドカーリポジトリ

プロジェクトのワークフローファイルと設定は、どちらもプライマリリポジトリのルートにある .codedag/ ディレクトリに置かれます。リポジトリの中にあるので、コードと一緒にプロジェクトリポジトリにコミットするのが自然に見えます。しかし、ワークフローの実行中、CodeDAG はリポジトリのブランチを切り替え、タスクの変更をコミットします。このディレクトリをプロジェクトリポジトリで管理していると、リポジトリが別のブランチに切り替わるたびに中のワークフローファイルも一緒に変わり、タスクのコミットにもこれらのファイルが混ざってしまいます。かといって、プロジェクトリポジトリにこのディレクトリを無視させるだけでは、ファイルがブランチの切り替えに影響されなくなる代わりに、バージョンの履歴が残らず、チームで共有することもできません。

そこで CodeDAG は、プロジェクトリポジトリに .codedag/ を無視させたうえで、このディレクトリを独立した Git リポジトリにしています。2 つのリポジトリは、それぞれ別のコミット履歴を持ちます。この独立したリポジトリが、プロジェクトのサイドカーリポジトリ(sidecar repository)です。cdg init の出力では sidecar repository と表記され、ドキュメントでは .codedag リポジトリとも呼びます。

プロジェクトリポジトリは、.git/info/exclude によってこのディレクトリを無視しています。そのため、.codedag/ をプロジェクトリポジトリにコミットする必要はなく、プロジェクトリポジトリの git status にも表示されません。サイドカーリポジトリは自分で管理するもので、CodeDAG がその中でコミット、プッシュ、プルをすることはありません。ワークフローの履歴を残したい場合は、.codedag/ に移動して、通常の git コマンドでコミットします。方法はワークフローと共有設定を別に保存するを参照してください。チームで共有したい場合は、さらにリモートリポジトリにプッシュします。詳しくはチームで共有するを参照してください。.codedag/local/ にあるローカル設定とログは、このコンピューターだけのもので、バージョン管理の対象にはなりません。

サイドカーリポジトリは、1 つのプロジェクトに 1 つだけです。レプリカには .codedag/ がなく、どのワークスペースで cdg を実行しても、使われるのはプライマリリポジトリにあるこの 1 つです。


最終更新