方案設計と実装ワークフロー
核心理念
先に議論を徹底し、それからコードを書く。 このワークフローは「考える」と「実行する」を強制的に分離します:
- 議論フェーズ:対話のみ、コードは書かない。すべての結論はコミュニケーションドキュメントに集約
- 設計フェーズ:合意事項を設計ドキュメントに整理。これが唯一の事実ソース
- 実装フェーズ:設計ドキュメントに基づいて実装ドキュメントを生成し、ステップごとに実行
議論が結論に達していない、ユーザーが明確に「実装を開始してよい」と言っていない限り、絶対にコードに手を付けません。疑問がある限り議論を続け、両者が納得するまで徹底します。
ドキュメントディレクトリ構造
固定でプロジェクトルートの docs/design/ に配置。タスクごとに独立したサブフォルダを作成します:
プロジェクトルート/
└── docs/design/
├── README.md ← グローバルタスク一覧(複数タスクのエントリポイント、最初に読む)
├── 01-ユーザー認証モジュール/
│ ├── 00-タスクステータス.md ← クロスコンテキスト記憶アンカー
│ ├── 01-コミュニケーションログ.md
│ ├── 02-設計.md ← 受け入れ基準を含む
│ ├── 03-実装.md
│ └── 04-テスト.md ← テストケース集(実装計画フェーズで生成)
└── 02-ペイメントリファクタリング/
└── ...
命名規則:
- タスクフォルダ:グローバルにインクリメントする2桁の番号 + タスク名(例:
01-ユーザー認証モジュール、02-ペイメントリファクタリング)。番号はタスク間で連続し、作成順にソートされることを保証。 - タスク内ドキュメント:固定フェーズ番号プレフィックス:
00-タスクステータス/01-コミュニケーションログ/02-設計/03-実装/04-テスト。固定プレフィックスにより、どのタスクでも同じ種類のドキュメントを一目で特定可能。
初めてタスクに入る際の番号決定方法:docs/design/ 下の既存フォルダの最大番号を確認し、+1 を新しいタスク番号とします。ディレクトリが存在しない場合は 01 から開始します。
新しい会話のたびの最初のステップ(マルチコンテキスト記憶機構)
このワークフローは複数の会話コンテキストにまたがって実行される可能性があります。毎回新しい会話でコードを広範囲に読み直したり、記憶を失ったりすることを避けるため、以下の順序でコンテキストを復元します:
docs/design/README.mdを読む —— グローバルタスク一覧を確認し、どのタスクが存在し、それぞれどのフェーズにあるかを把握。ユーザーがタスクを指定している場合は、そのタスクに直接ジャンプ。00-タスクステータス.mdを読む —— 現在のタスクの記憶アンカー。次に何をすべきかを確認。- 現在のフェーズに対応するドキュメントを読む(設計フェーズなら
02-設計.md、実装フェーズなら03-実装.md)。 - 確認が必要な場合のみコードを読む。コンテキスト復元の第一手段としては使用しない。
00-タスクステータス.md には以下を必ず維持する:タスクの一言概要、現在のフェーズ、主要な決定事項の要約、TODO と疑問点、ドキュメントインデックス、コンテキスト切り替えログ、変更履歴(修正とロールバックの両方を含む、後述の「実装期の変更」を参照)。
ワークフローの4つのフェーズと対応するドキュメント
フェーズ一:議論(出力 → コミュニケーションログドキュメント)
トリガー:ユーザーが新しい要件、機能、モジュールを提案した、または既存の計画について疑問を議論したい場合。
行動制約:
- このフェーズでは議論のみを行い、いかなる業務コードも書かない。
- 意味のあるやり取り(重要な決定点、却下された選択肢、合意に至った内容)はすべて
01-コミュニケーションログ.mdに追記する。 - 未解決の疑問の追跡:
01-コミュニケーションログ.mdの上部に「現在の未解決の疑問」リストを維持する。議論の終了ごとにこのリストを更新する——どの疑問がまだ残っているか、どの新しい疑問が生じたか、どの疑問が解決されたか。設計フェーズに進むための直接的な判断基準は、このリストが空になっているかどうか。これにより、議論の収束プロセスを可視化し、「だいたい議論が終わった」という感覚に頼らなくて済む。 - 議論は複数ラウンドにわたる可能性があり、複数の会話にまたがってもよい。
- ユーザーが「もういい」「これで決めよう」「設計を始めよう」と表現し、未解決の疑問リストが空になったら、フェーズ二に進む。
いつ議論を継続し、いつ進めるか:未解決の設計上の疑問、技術選定の相違、境界が明確でない限り、フェーズ一で議論を続ける。不明確な仮定を持ったまま設計に進むよりも、もう一度質問する方が良い。
フェーズ二:設計(出力 → 設計ドキュメント)
トリガー:議論が合意に達し、未解決の疑問リストが空になり、ユーザーが計画の確定に同意した場合。
行動制約:
- コミュニケーションログの結論を、構造化された
02-設計.mdに整理する。設計ドキュメントは唯一の事実ソースである。 - 設計ドキュメントは可能な限り完全でなければならない:納品時には確定済みで実行可能な計画であり、「未定」「実装フェーズで対応」といった残留があってはならない。完全性は2つのことで保証する——徹底的なコミュニケーションで疑問を解消すること、そして既存のコードを読んで、依存する既存の実装の事実(インターフェースの形状、テーブル構造、呼び出し方法など)をすべて確認すること。「設計フェーズでは議論のみでコードを書かない」という制約は業務コードに対するもの。設計のために既存コードを読んだり、現状を確認したりすることは設計調査であり、制約に違反しない。設計フェーズでは、たとえ時間がかかっても徹底的に練り上げる。欠陥を持ったまま実装に進むことは絶対に避ける——どんな欠陥も実装フェーズで手戻りや乖離を引き起こす。
- 受け入れ基準は設計の一部である:設計ドキュメントには「何を、なぜ」に加えて、「どの程度まで満たせば要件を満たしたと言えるか」——すなわち抽象的な受け入れ基準(ルールレベル、例:「高リスクワードは必ずブロックし、記事は保存しない」)を記述する。受け入れ基準は要件の境界を定義し、設計の完全性を担保する最後の要素。受け入れ基準のない設計ドキュメントは、「完了した」という客観的な定義がなくなる。具体的なテストケース(インスタンスレベル)は設計ドキュメントには書かず、
04-テスト.mdに実装計画フェーズで受け入れ基準を具体化して記述する。 - 設計変更履歴:設計ドキュメント内に「設計変更履歴」セクションを維持し、重要な変更があるたびに1行記録する(日時、変更内容、変更理由)。これは
01-コミュニケーションログ.mdと補完関係にある——コミュニケーションログは生の記録、設計ドキュメントは結論、変更履歴は結論の進化の歴史。これにより「計画変更は設計ドキュメントを修正し、実装ドキュメントは修正しない」という鉄則を、履歴を失うことなく実行可能にする。 - 設計ドキュメントが完了したら、
00-タスクステータス.mdを更新し「設計完了、実装待ち」とマークし、docs/design/README.mdのタスクフェーズも併せて更新する。
フェーズ三:実装計画(出力 → 実装ドキュメント)
トリガー:設計ドキュメントが確定した場合。
行動制約:
- 設計ドキュメントに基づいて
03-実装.mdを生成し、計画を実行可能でチェック可能なステップリストに分解する。 - 同時に設計ドキュメントの「受け入れ基準」を具体的なテストケースに落とし込み、
04-テスト.mdを生成する:テストケースは受け入れ基準の具体化である(例:受け入れ基準「高リスクワードは必ずブロック」→ ケース「高リスクワードを含むテキストを入力、期待結果は 40901、記事は保存されない」)。ケースは4層に分かれる:機能(T-F)、異常(T-EX)、回帰(T-R)、インターフェース(T-API)。番号形式はT-{タイプ}-{2桁番号}、テンプレートはassets/test.mdを参照。 - 実装ドキュメントは「どのように行うか」、テストドキュメントは「何をテストし、期待される結果は何か」、設計ドキュメントは「何を、なぜ行うか」。3つの役割は異なる。設計の詳細を実装ドキュメントにそのままコピーしたり、実装ドキュメントに計画の変更を混在させたりしてはならない。
- 実装ドキュメントは純粋なステップ分解であり、各ステップは「設計ドキュメントの特定の部分を実装する」だけであり、「設計を補完する」役割は一切負わない。ステップを分解中に、あるステップで「インターフェースの形状を確認」「設計を書き戻す」「フィールドを決定する」が必要だと気づいた場合、それは設計フェーズが完了していないことを意味する——その場合はフェーズ二に戻って設計を補完すべきであり、実装ドキュメントに「設計補完」ステップを詰め込んではならない。一言で言えば、実装ドキュメントには「コードを読んで計画を確定する」性質の動作は一切現れてはならず、「確定した計画に従って実装する」動作だけが許される。
- 実装ドキュメント内のテスト動作はテストケース番号のみを参照し、ケースの内容を繰り返し記述しない。各ステップ完了後に検証すべき事項は、「ケース T-XX-XX に従って検証」と記述し、ケース自体は
04-テスト.mdに集中させる。 - 実装ステップは大ステップと小ステップの2層構造とし、それぞれに独立した完了マークを付ける。
- 実装ドキュメントが完了したら、
00-タスクステータス.mdを更新し「実装待ち」とマークする。
フェーズ四:実装(実装ドキュメントのステップを実行)
トリガー:ユーザーが「実装を開始」「着手」「ドキュメント通りに進めて」と指示した場合。
行動制約:
03-実装.mdのステップに厳密に従って進め、各ステップが完了するごとにドキュメント内のマークを更新し、結果を簡潔に記録する。- 各ステップが完了するごとに、
04-テスト.mdでそのステップが参照しているテストケースに従って検証する。テストケースが失敗した場合、そのステップは完了と見なさない。問題を特定する(実装のバグか、設計/テストケース自体に問題があるか。後者は修正/ロールバック機構を適用)。全ステップが完了したら、回帰テストケース(T-R)セットを実行する。 - 設計ドキュメントと矛盾する状況に直面した場合は、停止する:まず
02-設計.md(変更履歴を含む)を更新し、次に03-実装.mdと04-テスト.md(ケースは計画に合わせて変更)を同期修正し、その後続行する。計画から逸脱したまま進めてはならない。 - 実装中に発見された設計の抜け穴、新たな制約、APIの変更は、すべて
02-設計.mdの「設計変更履歴」セクションに書き戻し、設計ドキュメントを最新の状態に保つ。 - 各フェーズの切り替え、および重要なマイルストーンごとに、
00-タスクステータス.mdとdocs/design/README.mdを必ず更新する。
実装期の変更:修正メカニズム vs ロールバックメカニズム
ワークフローは名目上、議論→設計→実装計画→実装だが、実装中に計画と要件/現実の間に乖離が生じることは、予想される通常の状態であり、異常ではない——どれほど完全な設計でも、実装の細部を100%予見することはできない。
乖離には性質の異なる2種類があり、厳密に区別し、それぞれのプロセスで処理する必要がある:
| 修正 | ロールバック | |
|---|---|---|
| 本質 | 計画はおおむね正しいが、ギャップ/欠落を補う必要がある | この部分の計画が根本的に間違っており、破棄してやり直す必要がある |
| 主体計画 | 変更しない | 破棄する |
| 完了済み成果物 | 無効にしない | 部分的に無効にする |
| 頻度 | 通常 | 稀 |
| 典型的なシナリオ | フィールド漏れ、ブランチ漏れ、辞書値漏れ、新しい要件ポイントの見落とし | 方向性の誤り、核心的な前提が成立しない、実際のビジネスに合わない |
まずどちらのタイプかを判定する(判定の責任は各メカニズムの説明を参照)。判定に迷う場合は、まず「修正」として処理し、ユーザーに確認する。明確に根本的な誤りである場合のみ「ロールバック」を実行する。
修正メカニズム(通常、軽量、インクリメンタル)
判定の3条件(すべて満たす場合のみ修正):
- 主体計画の方向性に問題がない
- 完了済みの成果物を無効にする必要がない
- 単なる補足/微調整(フィールド追加、ブランチ追加、辞書値追加、見落とした新しい要件ポイントの追加など)
処理フロー(厳密な順序、逆順禁止):
- 現在の実装を停止する
- まず設計ドキュメントを更新する:設計ドキュメントの該当セクションに内容を補足し、設計変更履歴の1行を追加する
- ユーザーの確認を待つこの修正について(自分で判断して実行してはならない)
- ユーザー確認後、実装ドキュメントを同期修正する
- その後、実装を続行する
重要な原則:まず設計を更新し、その後実装する——順序は絶対に逆にしてはならない。「先に実装を完了させ、後で設計ドキュメントに書き戻す」ことは、設計ドキュメントを事後の記録に退化させ、事実ソースではなくなる。たとえ1つのフィールドを追加するだけでも、このフローを踏むこと。
ロールバックメカニズム(稀、重量、破棄)
判定の3条件(すべて満たす場合のみロールバック):
- 主体計画の方向性に問題がある
- 完了済みの成果物を無効にする必要がある
- 再議論/再設計が必要
判定責任:ロールバックの最終決定権はユーザーにある。AIが根本的な問題の可能性を発見した場合、ロールバックの可能性を提案し、理由を説明することのみができ、最終的な判定はユーザーが行う。AIは自らロールバックを判定してはならない。
処理フロー:
- 現在の実装を停止する
- AIが ロールバックの可能性を提案し、理由を説明する(どの部分の方向性が間違っているか、なぜ成立しないか)
- ユーザーの最終判定を待つロールバックするかどうか
- ユーザーがロールバックを確認したら、
00-タスクステータス.mdに1行記録する:XフェーズからYフェーズへのロールバック、理由、無効になった成果物 - 議論/設計フェーズに戻り、再調整する
- 新しい計画は元のフローに従って蓄積する:新しい疑問は
01-コミュニケーションログ.mdの未解決疑問リストへ;計画変更は02-設計.mdへ記録し、変更履歴を追加する 03-実装.mdを同期修正する
2つのメカニズムに共通する鉄則
- 計画変更は常に設計ドキュメントを修正し、実装ドキュメントを直接修正してはならない
- まず設計を更新し、その後実装する。順序は絶対に逆にしてはならない(後で実行してから補足しない)
- いかなる変更もタスクステータスドキュメントに痕跡を残すこと(修正は設計変更履歴、ロールバックは別途ロールバック記録)
- ユーザー確認はすべての変更に必須のゲートである(修正は計画補足の確認が必要;ロールバックは判定自体の確認が必要)
マインドセット:乖離は恐れるに足らない。恐れるべきは、乖離があるまま無理に進めるか、計画から密かに逸脱することだ。「修正」を軽量で低摩擦にし(通常はスムーズに行われるべき)、「ロールバック」を慎重にし(破棄してやり直すにはユーザーの決定が必要)、両方とも規範的に痕跡を残せば、手戻りのコストは最小限になる。
実装ドキュメントのステップマーク規範
実装ステップは大ステップと小ステップの2層構造とし、それぞれに独立した完了マークを付ける。大ステップはタイトルでブロック分けし、進行状況カウントを表示。小ステップは4状態のチェックボックスを使用する。
4状態マーク:
- [ ] 未開始
- [~] 進行中
- [x] 完了
- [!] ブロック(理由を付記)
編成例:
### 1. データベース層 ✅ 1/3
- [x] 1.1 usersテーブルを作成(マイグレーションスクリプト含む)
- [~] 1.2 インデックスを作成
- [ ] 1.3 シードデータを作成
### 2. インターフェース層 ⬜ 0/2
- [ ] 2.1 POST /api/users を実装
- [ ] 2.2 認証ミドルウェアを接続
大ステップ状態記号:
⬜未開始(0/N 完了)🌗進行中(一部完了)✅すべて完了(N/N)
進行状況カウント形式は 完了数/総数 とし、大ステップタイトルの末尾に配置する。これにより全体の進行状況と、どの小ステップで詰まっているかを同時に把握できる。
バックエンドプロジェクトの特別処理
現在のプロジェクトが純粋なバックエンドプロジェクトの場合(フロントエンドコードなし、またはフロントエンドとバックエンドが分離してバックエンドが独立したリポジトリ):
- 設計ドキュメントと実装ドキュメントはバックエンドの内容のみを記述し、フロントエンドの実装には触れない。
- いかなる新規インターフェースまたは既存インターフェースの変更(URL、メソッド、入力パラメータ、出力パラメータ、エラーコード、認証要件など)は、
02-設計.md内に専用の 「インターフェース変更リスト」 セクションを設けて集中的に表現する。 - インターフェースリストの形式は、フロントエンドの開発者がそのまま結合テストに使用できるようにする。推奨フィールド:インターフェースパス、リクエストメソッド、リクエストボディ例、成功レスポンス例、エラーコードテーブル、認証要件、備考。
- このインターフェースリストはフロントエンドへの成果物であり、自己完結し、独立して読めるように記述する。
- インターフェースリストは設計フェーズで確定した結論を提供しなければならず、判断を実装フェーズに先送りしてはならない。「このインターフェースは新規か変更か」「パスは既存のものを踏襲するか変更するか」「入力パラメータはどの既存構造に合わせるか」など、既存コードに依存する事実は、設計フェーズで既存コードを読んで確認し、結論をインターフェースリストに書き込まなければならない。「設計フェーズでは議論のみでコードを書かない」という制約は業務コードに対するもの。インターフェースの形状を確認するために既存コードを読むことは設計調査であり、実装には該当せず、制約に違反しない。設計ドキュメント内に「詳細は既存コード次第」「実装フェーズで確認」といった曖昧な表現は禁止であり、また【実装期確認】のようなタグで不確実性を正当化することも許可されない。インターフェースリストがフロントエンドに引き渡される時点で完全に確定していなければならない。そうでなければフロントエンドは結合テストができない。
受け入れ基準とテスト(3層の責任分離)
テストは実装フェーズで後付けするものではなく、設計から実装まで一貫した体系である。3層の責任は厳密に分離する:
| 層 | 媒体 | 内容 | 性質 | 成果物フェーズ |
|---|---|---|---|---|
| ルール | 02-設計.md | 抽象的な受け入れ基準 | 「どの程度まで満たせば要件を満たしたと言えるか」 | 設計 |
| インスタンス | 04-テスト.md | 具体的なテストケース | 「どの入力に対して、どの出力を期待するか」 | 実装計画 |
| アクション | 03-実装.md | ステップ + ケース参照 | 「どのアクションを実行し、どのケースで検証するか」 | 実装計画 |
なぜこのように分けるのか:受け入れ基準は要件の境界(設計に属する)、ケースはその境界の具体化、実装は実行アクション。3層が分離されていることで、ルールが変われば設計ドキュメントを、ケースが変わればテストドキュメントを、アクションが変われば実装ドキュメントを参照すればよい——それぞれに事実ソースがあり、互いに汚染されない。
テストケースの階層と番号:
| プレフィックス | タイプ | 用途 |
|---|---|---|
T-F- | 機能ケース | 正常フロー |
T-EX- | 異常ケース | 異常系、境界値、エラーブランチ |
T-R- | 回帰ケース | 修正/ロールバック後に必ずテストすべきクリティカルパス(F/EXから選択、A修正によるBの壊れを防止) |
T-API- | インターフェースケース | 設計ドキュメントの「インターフェース変更リスト」の各インターフェースに対応 |
すべてのタスクで 04-テスト.md の生成を必須とする:本スキルは中~大規模タスクを対象としており、小規模な要件ではユーザーがスキルをトリガーしないため、複雑さの判断は行わない——タスクがいったん実装計画フェーズに入ったら、テストドキュメントは必須の成果物である。
修正/ロールバックとテストの関係:修正またはロールバックメカニズムを実行した後、計画が変わった → ケースも更新する(まず設計の受け入れ基準を変更し、次にテストケースを変更する)、そして回帰テストケースセット(T-R)を少なくとも1回は再実行し、局所的な修正がグローバルな回帰を引き起こさないようにする。
拡張モードA:タスク分割(大規模マルチモジュールタスク)
いつ有効にするか:大規模タスクが本質的に複数の半独立モジュールを含む場合(例:「審査システム = 不適切ワードフィルタリング + 画像審査 + 手動審査ワークベンチ」)、単一のコンテキストでは収まらない。ユーザーが議論フェーズで明示的に「これは大規模タスクなので、マルチモジュールに分割する」と指示した場合に有効にする。タスクの規模を自動判断せず、ユーザーの明示的なトリガーが必要。
核心メカニズム:親タスクは全体設計 + モジュール分割 + モジュール間インターフェース契約 + 編成を担当し、子タスクは親タスクの境界内でそれぞれ完全な4フェーズフローを実行する。
A.1 親子タスクのドキュメント構造(ネスト型)
プロジェクトルート/docs/design/
├── README.md ← グローバルタスク一覧
├── 01-審査システム/ ← 親タスク
│ ├── 00-タスクステータス.md ← parent-task-status.md テンプレートを使用、子タスク一覧を含む
│ ├── 01-コミュニケーションログ.md ← 親タスクレベルの全体議論
│ ├── 02-設計.md ← 全体アーキテクチャ + モジュール分割 + モジュール間インターフェース契約
│ ├── 03-実装.md ← 親レベルの編成のみ(統合テスト、結合調整)、モジュール内部は記述しない
│ ├── 04-テスト.md ← クロスモジュール統合テストのみ
│ └── 子タスク/
│ ├── 01-1-不適切ワードフィルタリング/ ← 子タスク(完全な4フェーズドキュメント、通常テンプレート使用)
│ ├── 01-2-画像審査/
│ └── 01-3-手動審査ワークベンチ/
└── 02-その他のタスク/
子タスクは通常テンプレートを使用(task-status / communication / design / implementation / test)、完全に不変。親タスクは assets/parent-task-status.md テンプレートを使用、「子タスク一覧」セクションが追加される;親タスクの設計ドキュメントは通常の設計テンプレートに加えて、以下の2つのセクションを必須で含まなければならない:
- モジュール分割:どの子タスクに分割するか、それぞれの責務境界を列挙
- モジュール間インターフェース契約:子タスク間のインターフェース取り決め(インターフェースシグネチャ、データ形式、呼び出し方法など)。これは子タスクが独立して並行作業できるための鍵であり、設計フェーズで確定しなければならない
A.2 親タスクのフェーズ進行(厳密なシリアル)
- 親タスクはまず「議論 + 設計」を実行し、モジュール分割 + モジュール間インターフェース契約を必ず成果物として生成する
- 親タスクの設計がユーザーに確認された後、子タスクを開始できる
- 子タスクを開始する際は、依存関係に基づいて開始順序を決定する:親タスクの設計フェーズで子タスク間の依存関係を明確にする(例:「手動審査ワークベンチは不適切ワードフィルタリングのインターフェースに依存する」)、依存される側の子タスクが先に完了し、依存する側がその後開始する
- 各子タスクはそれぞれ完全な4フェーズフローを実行する(依存関係が満たされている限り並行可能)。複数の子タスクを並行して開始する方法は、使用するエージェントフレームワークに依存する(一般的にはバックグラウンド/非同期子タスク機能で実現)。具体的な実装は B.5 を参照
- すべての子タスクが完了したら、親タスクは「クロスモジュール統合テスト」で締めくくる
なぜ親タスクと子タスクを並行できないのか:親タスクの核心的な成果物はモジュール間インターフェース契約であり、これが子タスクが独立して作業できる前提である。親タスクの設計が確定していない状態で子タスクを開始すると、子タスク間で必ず衝突が発生する。
A.3 子タスクは親タスクが定義したインターフェース契約を勝手に変更できない
インターフェース契約は複数モジュールの合意であり、いずれかの子タスクが勝手に変更すると、他の子タスクが制御不能になる。子タスクが親タスクのインターフェース契約に問題を発見した場合:
- 自らインターフェース契約を変更してはならない
- 必ず親タスクに戻って修正メカニズムを実行する:親タスクの
02-設計.mdを更新する(変更履歴を含む)→ ユーザーの確認を待つ → そのインターフェースに依存するすべての子タスクに通知する → 影響を受ける子タスクは自身の設計/実装/テストを同期修正する
A.4 ネスト深度制限:1層のみ許可
親→子、それ以上のネストは不可(子タスクがさらに自身の子タスクを持つことはできない)。理由:ネスト層が多すぎるとタスク関係が非常に複雑になる。もし子タスクをさらに分割する必要がある場合、それは通常タスク分割の粒度が適切でないことを意味する——そのタスク自体を独立した親タスクとして再計画すべきであり、既存の多層構造に詰め込むべきではない。
A.5 親タスクテンプレートの使用
- 親タスクステータスドキュメント:
assets/parent-task-status.mdを使用(通常の task-status テンプレートは使用しない) - 親タスクのその他のドキュメント(コミュニケーションログ/設計/実装/テスト):通常テンプレートを使用するが、設計ドキュメントは A.1 で述べた2つのセクションを必須で含むこと
- 子タスクのすべてのドキュメント:通常テンプレートを使用し、完全に不変
拡張モードB:デュアルエージェント実装(実装フェーズ分割)
いつ有効にするか:単一タスク内で、実装+テストの2つのフェーズが積み重なり、コンテキストが長くなりすぎる場合。ユーザーが実装フェーズ開始時に明示的に「実装はデュアルエージェントモードで」と指示した場合に有効にする。自動判断せず、ユーザーの明示的なトリガーが必要。
核心メカニズム:実装フェーズを内部的に2つのシリアルなステップに分割する——実装エージェント(03-実装.md に従ってコードを書く)+ テストエージェント(04-テスト.md に従って検証する)。両者は物理的に独立した2つのエージェント(2つの独立したコンテキスト)であり、タスクステータスドキュメントを介して引き継ぎを行う。B の核心的な価値はコンテキストの分離にある:実装エージェントはテストのコンテキストを持たず、テストエージェントは実装の詳細を持たない。
B.1 実装とテストの責務境界
- 実装エージェント:03-実装.md のステップのみを実行する(コードを書く)。完了後、自らテストは実行せず、
00-タスクステータス.mdの「実装分割状態」セクションで「実装完了、バージョンX、テストに進める」と宣言する。 - テストエージェント:最新の 03-実装.md + 04-テスト.md に基づいて検証する。責務は厳密に「テストケースを実行し、失敗を判定し、報告する」ことに限定され、コードの修正は担当しない(実装のバグを発見しても、自ら修正しない)。
B.2 テストエージェントが失敗を発見した場合の処理
テストエージェントがテストケースの失敗を発見した場合、失敗の根本原因を初期的に判断する(テストエージェントは実際の動作を見ているため、初期的判断の情報優位性が最も高い):
- 実装バグと判定(コードが間違っている、設計は正しい)→ 実装エージェントに報告し、実装エージェントが修正する。修正後は必ずテストエージェントに戻って再テストを依頼し、そのケースが合格してから次のステップに進む(実装エージェントが一方的に「直した」と宣言してもクローズできない)。
- 設計バグと判定(コードは設計通りに書かれているが、設計自体に問題がある)→ 勝手に設計を変更してはならず、修正メカニズムをトリガーする:停止 → 設計を更新 → ユーザーの確認を待つ → 実装を修正 → テストを修正 → テストエージェントに戻って再テストする
判定が間違っていればユーザーが修正する。しかし「設計変更」の影響範囲は大きいため、ユーザーの決定が必要である。
B.3 実装分割状態セクション
00-タスクステータス.md にオプションのセクションを追加する(Bモード有効時のみ記入、通常モードでは記入しない):
## 実装分割状態(Bモード専用、通常モードでは空欄)
- 現在のステップ:実装 / テスト
- 実装バージョン:(実装エージェントが完了または修正のたびにインクリメント)
- 実装完了宣言:YYYY-MM-DD、実装エージェントがテストに進めることを宣言済み
- テスト進捗:
- 合格:T-F-01, T-F-02, ...
- 失敗・修復待ち:T-EX-03(実装バグ、実装エージェントに報告済み)、...
- 再テスト待ち:T-EX-03(実装エージェントが修正済み、テストエージェントの再テスト待ち)
実装エージェントとテストエージェントは両方ともこのセクションを読み書きし、これが両者の唯一の引き継ぎポイントである。
B.4 A との組み合わせ(A+B)
A と B は直交しており、組み合わせ可能:大規模タスクを A で子タスクに分割し、各子タスク内で B で実装+テストに分割する。組み合わせ時に追加のメカニズムは不要——なぜなら子タスクは通常タスクだからである(A.1 で子タスクは通常テンプレートを使用すると説明済み)。したがって、子タスク内部は自然に B をサポートする。有効化方法:親タスクの設計 + 子タスク起動後、各子タスクは実装フェーズ開始時に B を有効にするかどうかを判断する。
B.5 エージェントスケジューリングガイド
Bモードは2つの物理的に独立したエージェント(実装エージェントとテストエージェント)を必要とし、これらは「実装分割状態」セクションを介して間接的に引き継ぎを行い、直接互いに通信しない。具体的なリレー方法は、使用するエージェントフレームワークに依存する。
どのフレームワークを使用する場合でも、以下の共通スケジューリングパターンに従う:
- スケジューラ(メインエージェント、外部オーケストレーションスクリプト、またはユーザー自身)が「実装分割状態」セクションを読み、現在のステップを判断する
- スケジューラが実装エージェントを起動し、設計/実装ドキュメントのパスを渡し、03-実装.md に従って進め、完了後に状態セクションを更新するよう指示する
- 実装ステップが終了したら、スケジューラがテストエージェントを起動し、テストドキュメントのパスを渡し、04-テスト.md に従ってテストケースを実行し、結果(失敗判定を含む)を状態セクションに書き込むよう指示する
- スケジューラは状態セクションのテスト結果に基づいて次のステップを決定する:実装バグなら実装エージェントに戻って修正と再テスト;設計バグなら停止してユーザーに報告し修正メカニズムを適用;すべて合格なら終了
共通のキーポイント:
- 実装エージェントとテストエージェントはそれぞれ独立してコンテキストを構築し、互いに汚染しない——これがBモードの「コンテキスト分離」の核心
- 2つのエージェントは互いを直接認識せず、「実装分割状態」セクションという共有ドキュメントを介してのみ間接的に引き継ぎを行う
- スケジューラは「状態を読む → 判断する → ディスパッチする」のみを行い、実装やテスト自体には参加しない
具体的なクライアントの実装参考:エージェントフレームワークによって、サブエージェント / バックグラウンドタスク / マルチウィンドウ機能は異なる。本文書は特定の実装に固定しない。ZCode を使用する場合、詳細は assets/references/zcode-scheduling.md を参照(必要に応じてロード:Bモード有効化かつ具体的な操作ガイダンスが必要な場合にのみ読む)。その他のクライアントはこのファイルの考え方を参考に、自身の能力に応じてアダプトすること。
重要な境界:スキルは具体的なスケジューリング実装に固定しない
スキルが定義するのは引き継ぎプロトコル(実装分割状態セクションの形式とセマンティクス)とロール責務(実装/テストの各々の作業内容)であり、具体的なスケジューリング方法は固定しない。「ファイルを読み、サブタスクを起動し、ファイルを書き込む」ことができる任意のフレームワークでBモードを実装できる。
フェーズ切り替えの確認原則
フェーズ間の切り替えは自動ではなく、明示的なシグナルが必要である:
| 移行条件 | 充足条件 |
|---|---|
| 議論に入る | (スキルが手動でアクティブ化されたところから開始) |
| 議論 → 設計 | ユーザーが計画の確定に明確に同意し、未解決の疑問リストが空である |
| 設計 → 実装計画 | 設計ドキュメントが完了し、ユーザーの承認を得る |
| 実装計画 → 実装 | ユーザーが着手の開始を明確に要求する |
| 実装 → 設計(修正) | 実装中に計画のギャップを発見し、「修正メカニズム」に従って停止して設計を変更し、ユーザーの確認を待つ |
| 実装 → 議論/設計(ロールバック) | 実装中に根本的な誤りを発見し、AIがロールバックを提案し、ユーザーが最終判定する |
切り替えるべきか判断できない場合、デフォルトで現在のフェーズに留まり議論を継続し、積極的にユーザーに質問する。「計画はもう十分だ、書き始めていいだろう」という判断をユーザーに代わって行ってはならない。
テンプレートの使用
新しいドキュメントを作成する際は、assets/ ディレクトリから対応するテンプレートを読み込む:
assets/readme.md→docs/design/README.md(グローバルタスク一覧)assets/task-status.md→00-タスクステータス.md(通常タスク / 子タスク)assets/parent-task-status.md→00-タスクステータス.md(親タスク専用、Aモード有効時)assets/communication.md→01-コミュニケーションログ.mdassets/design.md→02-設計.md(受け入れ基準セクションを含む;親タスクはモジュール分割 + インターフェース契約セクションを追加で必須)assets/implementation.md→03-実装.mdassets/test.md→04-テスト.md(実装計画フェーズで生成)
テンプレートを読み込み、実際の内容を埋め、タスクフォルダに書き込む。ドキュメント構造をでっち上げてはならない。
スキルの反復と旧タスクドキュメント
スキルは継続的に反復され、テンプレートや規範は更新されるが、すでに使用中の旧タスクドキュメントは自動的に新しい規範に移行しない。これは意図的である——ユーザーのドキュメント構造に対する既存の記憶を保護し、マルチコンテキスト記憶機構の安定性を維持するためである。ドキュメント構造は、ユーザーがコンテキストを切り替えた後に素早く位置を特定するための記憶アンカーであり、アンカーはスキルアップグレードのたびに頻繁に変形してはならない。
処理原則:
- 能動的な移行は行わない:AIは旧タスクを勝手にスキャンしたり、規範を揃えようとしたりしない。たとえ旧ドキュメントの形式が新しい規範と異なっていても(例:旧ドキュメントに「ロールバック記録」セクションがあるが、新しい規範では「変更履歴」が要求されている場合など)。発見した差異は、せいぜい「実装期のメモ」や会話内で一言触れる程度に留め、勝手に手を加えない。
- ユーザーの明示的な指示があった場合のみ移行する:ユーザーが能動的に「タスクXのドキュメントを現在のスキル規範に揃えて」「タスクXを新しい形式に移行して」などと要求した場合にのみ対応する。AIは「この旧タスクを移行すべきか」をユーザーに代わって判断しない。
- インクリメンタルな補完を優先する:移行はデフォルトで新しい規範に合わない部分のみを補足/修正し、元のドキュメントの全体構造と内容を保持し、破棄して書き直さない。これにより、ユーザーがコンテキストを戻したときにドキュメント全体を読み直す必要がなくなる——構造が変わっていなければ、記憶アンカーはそのままである。
- ユーザーが明示的に書き直しを要求した場合、書き直しをサポートするが、必ず元ファイルをバックアップしてから新しいファイルを生成する:
- 元ファイルに直接上書きしない
- バックアップファイルには日付またはバージョン接尾辞を付ける(例:
00-タスクステータス.md.bak.20260617) - 新しいファイルは元のファイル名を引き継ぎ、書き直し後の内容を保持する
- 元ファイルはユーザーの履歴記憶アンカーであり、書き直し後も元のバージョンを保持し、比較やロールバックに備える
- 移行/書き直し前に範囲を説明する:作業前にユーザーにどこを変更するか(インクリメンタル)またはどのファイルを書き直すか(フル)を伝え、変更後は何を変えたかを簡単に説明し、予測可能性を保つ。
アンチパターン(避けるべきこと)
- ❌ 議論フェーズで業務コードを書き始める——本末転倒。
- ❌ 計画変更を設計ドキュメントを更新せずに実装ドキュメントに直接書き込む——単一の事実ソースを破壊する。
- ❌ 新しい会話が始まったときに状態ドキュメントや README を読まず、ユーザーに進捗を説明させる——コンテキストを浪費する。
- ❌ 実装中に乖離に遭遇しても密かに実装を変更し、設計に書き戻さない——設計ドキュメントが徐々に信頼性を失う。
- ❌ バックエンドプロジェクトでフロントエンドの実装詳細を記述したり、インターフェース変更をインターフェースリストに反映させなかったりする——フロントエンドが結合テストの根拠を得られない。
- ❌ 明示的なシグナルなしに自動的にフェーズを進める——ユーザーの決定権を奪う。
- ❌ 実装中に計画のギャップ(フィールド漏れ、ブランチ漏れ、辞書値漏れなど)を発見した際に、実装ドキュメントを直接修正し、設計ドキュメントに戻さず、ユーザーの確認を待たない——「修正メカニズム」を踏むべき:停止→まず設計を修正→確認を待つ→実装を修正→続行。
- ❌ 実装中に根本的な誤りを発見しても、無理に実装ドキュメントを修正し続ける、またはAIが自らロールバックを判定する——「ロールバックメカニズム」を踏むべき:AIは提案のみ、ユーザーが最終判定し、ロールバック記録を残してから議論/設計に戻って再調整する。
- ❌ 大ステップにチェックが入っているが、内部の小ステップがまだ未完了——大ステップと小ステップそれぞれ独立してマークする。
- ❌ 議論が発散して収束せず、未解決の疑問が新しい話題に埋もれる——未解決疑問リストで強制的に収束させる。
- ❌ インターフェースリストに「詳細は既存コード次第」「実装フェーズで確認」といった曖昧な表現や、【実装期確認】タグで不確実性を正当化する——既存コードに依存する事実は設計フェーズでコードを読んで確認し、設計ドキュメント納品時にはインターフェースリストが完全に確定していなければならない。そうでなければフロントエンドは結合テストができない。
- ❌ スキル反復後に旧タスクドキュメントを勝手に移行したり、新しい規範に合わせようとしたりする——ユーザーの記憶アンカーを破壊する。ユーザーの明示的な指示があった場合のみ移行し、デフォルトでインクリメンタル補完、フル書き直しはしない。ユーザーが書き直しを要求した場合は必ず元ファイルをバックアップしてから新しいファイルを生成する。
- ❌ 設計ドキュメントが計画のみを書き、受け入れ基準を書かない——受け入れ基準は要件の境界であり、それがなければ「完了した」という客観的な定義がなく、実装期の受け入れは感覚に頼ることになる。
- ❌ 実装ドキュメントに「ユニットテストでXXXをカバー」といった漠然としたアクションを書き、具体的なテストケース番号を参照しない——テストアクションは
04-テスト.mdの具体的なケースを指さなければならない(例:「T-EX-03 に従って検証」)。そうでなければ、何をテストし、期待される結果は何かが不明確である。 - ❌ 修正/ロールバックメカニズムを実行した後に回帰テストケース(T-R)を再実行しない——局所的な変更がグローバルな回帰を引き起こす可能性があり、必ずクリティカルパスを再テストしなければならない。
- ❌ Aモードで親タスクの設計が確定していない(モジュール分割またはインターフェース契約が未成果)状態で子タスクを開始する——子タスク間で必ず衝突する。親タスクの設計はまずユーザーの確認を得なければならない。
- ❌ Aモードで子タスクが親タスク定義のインターフェース契約を勝手に変更する——インターフェース契約は複数モジュールの合意であり、必ず親タスクに戻って修正メカニズムを実行し、そのインターフェースに依存するすべての子タスクに通知しなければならない。
- ❌ Aモードで子タスクがさらに子タスクをネストする(1層を超える)——通常、分割粒度が適切でないことを意味し、その子タスクは独立した親タスクとして再計画すべきである。
- ❌ Aモードで親タスクが子タスクの依存関係を考慮せずにすべての子タスクを並行実行させる——依存する側は、依存される側が完了していない場合にデッドロックする。依存関係は親タスクの設計フェーズで明確にしなければならない。
- ❌ Bモードでテストエージェントが自分で実装バグを修正する——責務は分離しなければならない:テストは問題を指摘するのみ、修正は実装エージェントが行う。修正後はテストエージェントが再テストし、実装エージェントが一方的にクローズしてはならない。
- ❌ Bモードで同じエージェントを「実装」と「テスト」の両方の役割でシリアル実行する——Bの核心的価値はコンテキスト分離であり、物理的に2つの独立したエージェントでなければならない。そうでなければコンテキストは全く分離されておらず、Bを有効にした意味がない。
- ❌ Bモードでテストエージェントが設計バグを発見した際に自ら設計を変更する——設計変更の影響範囲は大きく、必ず修正メカニズムをトリガーし、ユーザーの確認を得なければならない。テストエージェントは初期的に判断し報告するのみである。