Status: Specification(v1) 親: #710 サブエージェント委譲プロトコルをPlanGate運用に組み込む 対応子 Issue: #712 サブエージェント成果物契約を定義する 位置付け:
README.md§2.5 の「委譲の契約・規範層」のうち 報告契約を担当。派遣プロンプト側の必須要素はdispatch-template.mdを参照。
PlanGate で派遣するサブエージェントの最終報告形式を標準化し、オーケストレータ と実行ログ側が安定して判定できるようにする。表記ゆれ・偽 fail 判定・要判断事項の 見落としを構造的に防ぐ。
本契約は承認境界(C-3 / C-4 / 親子 PBI Gate)を変更しない。あくまで「サブエージェ ントがどう報告するか」「オーケストレータが受領時に何を確認するか」を定める。
サブエージェントは最終報告の最終行に、必ず以下のいずれか 1 つだけを出力する。
OUTCOME: success
OUTCOME: partial
OUTCOME: failure
| 値 | 意味 |
|---|---|
OUTCOME: success |
依頼されたタスクを完遂し、要判断事項(P0)が残っていない |
OUTCOME: partial |
タスクの一部のみ完遂(未完了部分が残る)。または P0 の要判断事項が残り success を名乗れない。判別軸は完遂/一部完遂であり、P1/P2 は success と併存可(P0 のみが success を阻む。§2 / §7.4 と一致) |
OUTCOME: failure |
タスクを完遂できなかった、または致命的な問題で継続不能になった |
OUTCOME(全て大文字)。Outcome: / outcome: は不可OUTCOME: success。OUTCOME:success(スペース
なし)や OUTCOME : success(コロン前スペース)は不可success / partial / failure。Success / SUCCESS /
日本語(成功 等)は不可OUTCOME 行の後に
他の行を続けないOUTCOME: 行を書かない(最終判断が
曖昧になる)判定用の正規表現例:
^OUTCOME: (success|partial|failure)$
この正規表現に一致しない最終行は契約違反として扱い、オーケストレータは
サブエージェントへ SendMessage で是正を要求する(§6 受け入れ確認チェックリスト
参照)。
review=true タスクでの OUTCOME の扱いレビュー・監査タスクで重大な問題を発見した場合でも、依頼されたレビュー作業自体
が完了していれば OUTCOME: success とする(何を発見したかと、依頼作業が完了
したかは別軸)。判定基準は「タスクの遂行状況」であり「対象コードの健全性」では
ない。詳細は §4 を参照。
ユーザーまたはオーケストレータの判断が必要な事項には、以下の優先度を付ける。
| 優先度 | 定義 | 扱い |
|---|---|---|
| P0 | ブロッカー。即判断が必要 | オーケストレータはユーザーへ即座にエスカレーションする。後続作業を進めない |
| P1 | 次工程に進む前に判断したい | 次フェーズ(レビュー確定・実装着手・マージ等)に進む前にユーザー確認を挟む |
| P2 | 後続改善・補足判断でよい | 記録に残すが、即時のブロッカーにはしない(handoff / known-issues 等に転記可) |
報告本文中に箇条書きで明示する。
## 要判断事項
- [P0] 既存 API のレスポンス形式を変更する必要がある。後方互換性が壊れる
- [P1] テストを追加したが、CI のタイムアウト設定が現行の 2 倍必要になる可能性がある
- [P2] 命名を `fooBar` から `foo_bar` に統一する余地がある(今回は既存命名踏襲)
OUTCOME は原則 partial または failure になる
(P0 を残したまま success を名乗らない)各主張・成果物には、検証状態を以下 4 区分で明示する。
| 検証状態 | 意味 | 記載必須事項 |
|---|---|---|
| 実行済み | 検証コマンド・テストを実際に実行し、出力を確認した | 実行したコマンド・結果概要 |
| 未実行 | 実行する予定だったが、時間・権限・環境制約等で実行しなかった | 未実行の理由 |
| 失敗 | 実行したが結果が NG だった | エラー内容・失敗した箇所 |
| 未検証 | 検証手段自体が未定義、または着手していない(レビュー系タスクで結論の裏付けがまだない場合など) | なぜ未検証か(検証手段がない/対象外/今回のスコープ外 等) |
この区別により、「本来やるべきだったが省略した」(未実行)と「今回のタスクの 性質上、検証という概念がまだ適用できない」(未検証)を混同しない。
## 検証結果
- ユニットテスト `npm test`: 実行済み(32 件 PASS / 0 件 FAIL)
- E2E テスト: 未実行(本タスクのスコープ外・ステージング環境が未提供のため)
- 型チェック `tsc --noEmit`: 失敗(`src/foo.ts:12` で型エラー 1 件)
- パフォーマンス影響: 未検証(負荷試験環境が存在しないため計測不能)
review=trueレビュー・批評・監査・リスク列挙・真因調査タスクでは、失敗モードの列挙自体が 正しい成果物になる(例: 「脆弱性を 3 件発見した」は健全なレビュー成果物であり、 タスクの失敗ではない)。
このようなタスクを派遣する際は、Agent の description(または派遣プロンプトの
タスク種別フィールド)に review=true を含める。
description: "セキュリティレビュー review=true — 認証まわりの脆弱性を洗い出す"
以下のタスク種別で review=true を付ける。
実装・修正・生成タスク(Implementer 系)には付けない。
OUTCOME 行そのものの意味・判定基準。review=true は
タスク遂行の成否(レビューを最後まで完了できたか)を判定する軸を上書きしない言い換えると、review=true は「本文中に失敗語が出現しても、それだけで
OUTCOME を failure と誤判定してはならない」という解釈規則のフラグであり、
タスク遂行自体が失敗した場合(例: レビュー対象にアクセスできず何も評価できな
かった)はやはり OUTCOME: failure を書く。
review=true を使わない(#712 注意点)。実装タスクが
未完了なのに review=true を付けて OUTCOME: success を偽装することは
契約違反であり、受け入れ確認(§6)で検出対象とするサブエージェントの最終報告は以下の構造要件を満たす。
OUTCOME: {success|partial|failure} を書く(§1)サブエージェントの報告を受け取ったオーケストレータは、ユーザーへ結果を返す前に
以下を確認する(README.md §3 と同一チェックリストをここで
判定基準込みで定義する)。
| # | 確認項目 | PASS 例 | FAIL 例(是正要求) |
|---|---|---|---|
| 1 | 要求された成果物があるか | ファイルパス・PR URL 等が明記されている | 「実装しました」とだけ書かれ、パスや diff が示されない |
| 2 | 制約違反がないか | 指定 scope(read-only / 対象 worktree 等)内に収まっている | 禁止された操作(例: git push --force、対象外ディレクトリの編集)が行われている |
| 3 | OUTCOME が最終行にあるか |
^OUTCOME: (success\|partial\|failure)$ に一致する行が最終行 |
OUTCOME 行がない、途中にある、表記ゆれがある(§1.2) |
| 4 | 要判断事項が P0/P1/P2 で分類されているか | 全ての要判断事項に [P0]/[P1]/[P2] が付いている |
優先度なしの箇条書きだけ、または「要検討」とだけ書かれている |
| 5 | テスト・検証結果が明示されているか | §3 の 4 区分(実行済み/未実行/失敗/未検証)で記載されている | 「テストは問題ありません」とだけ書かれ、実行有無が不明 |
いずれか 1 項目でも FAIL の場合、オーケストレータはユーザーへ結果を返す前に
同一サブエージェントへ SendMessage で是正を要求する(別セッションへの
再委譲ではなく、同一コンテキストでの追指示を優先する)。P0 の要判断事項が
含まれる場合は、是正要求と並行してユーザーへ即座にエスカレーションする
(§2 の P0 定義に従う)。
OUTCOME: success の例TASK-0142 のバリデーション追加を完了した。
成果物: src/validators/email.ts(新規) / src/validators/email.test.ts(新規)
PR: なし(同一ブランチ内コミット、コミット SHA: 3f2a9c1)
## 要判断事項
なし
## 検証結果
- ユニットテスト `npm test -- email.test.ts`: 実行済み(8 件 PASS / 0 件 FAIL)
- lint `npm run lint`: 実行済み(エラーなし)
OUTCOME: success
OUTCOME: partial の例TASK-0143 の API 修正のうち、実装は完了したがマイグレーション方針の判断待ち。
成果物: src/api/orders.ts(更新)
未完了: DB スキーマ変更が必要だが、破壊的変更のため未実施
## 要判断事項
- [P0] `orders` テーブルの `status` 列を enum 化する必要がある。既存データの
移行方針(デフォルト値 or 手動マッピング)をユーザーに判断してもらいたい
- [P2] `orders.ts` 内の重複ロジックを共通関数に切り出す余地がある(今回は
スコープ外として着手せず)
## 検証結果
- ユニットテスト `npm test -- orders.test.ts`: 実行済み(5 件 PASS / 2 件 FAIL、
DB スキーマ未変更のため失敗)
- マイグレーション: 未実行(P0 の判断待ちのため意図的に保留)
OUTCOME: partial
OUTCOME: failure の例TASK-0144 の外部 API 連携実装は、認証情報が提供されておらず着手できなかった。
成果物: なし
着手できなかった理由: `.env.example` に記載の `EXTERNAL_API_KEY` が未設定で、
サンドボックス環境からも取得手段がない
## 要判断事項
- [P0] `EXTERNAL_API_KEY` の払い出し方法をユーザーに確認する必要がある
## 検証結果
- 実装: 未実行(認証情報欠如により着手不能)
- 疎通確認: 失敗(401 Unauthorized)
OUTCOME: failure
review=true タスクでの OUTCOME: success の例(レビュー結果に重大指摘あり)description: "認証まわりのセキュリティレビュー review=true"
認証フローのセキュリティレビューを完了し、重大な脆弱性を 2 件発見した。
成果物: レビュー結果(本報告に記載)
## 発見事項(レビュー成果物)
- [重大] セッショントークンが localStorage に平文保存されており XSS で窃取可能
- [中] パスワードリセットトークンの有効期限が 24 時間と長すぎる
## 要判断事項
- [P0] セッショントークンの保存方式を httpOnly Cookie に変更するかの方針決定
- [P1] パスワードリセットトークンの有効期限短縮(推奨: 1 時間)の採否
## 検証結果
- 認証フロー全体のコードレビュー: 実行済み(対象ファイル 12 件を精読)
- 実際の攻撃再現: 未実施(レビュータスクのスコープ外)
OUTCOME: success
注: このタスクは「脆弱性を発見して報告する」ことが依頼内容であり、それを 完遂できたため
OUTCOME: success。発見された脆弱性の深刻さは P0/P1 の 要判断事項として分離して報告する(§4.3 参照)。
README.md — 配置 ADR・オーケストレータ責務・全体索引dispatch-template.md — 派遣プロンプト
必須 8 要素(本契約は要素 7「出力形式」に対応)behavior-norms.md — 行動規範(結論先行・進捗実証等、
本契約の記法要件の背景)examples.md — より詳細なシナリオ別サンプル(派遣プロンプト
込みのフルサンプル)