control-session-orchestrator について
control-session-orchestratorは、広範囲・高リスク・状態管理が必要なプロジェクト作業を、複数の永続セッションで調整するスキルです。構造化された作業者レポートと永続的な制御状態マニフェストで、担当や検証、判断を追跡します。
主な機能
- 01作業を範囲別タスクに分解
- 02永続セッションへの作業割り当て
- 03制御マニフェストで進捗を追跡
- 04構造化された作業者結果の解析
- 05検証と成果統合の調整
活用シーン
- 01コードベース全体の監査や移行の調整
- 02セッション間で実装とレビューを分担
- 03モジュール横断の並行調査を追跡
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ pskoett/ pskoett-ai-skills --skill control-session-orchestratorインストール後、Claude Code で/control-session-orchestratorを入力して読み込まれたか確認します。
同梱ファイルevals/evals.json
詳細
コントロールセッションオーケストレーター
1 つの会話では範囲が広すぎる、リスクが高い、または状態を保持する必要があるプロジェクト作業では、現在のセッションをコントロールプレーンとして使用します。コントロールセッションは、意図の把握、作業の分割、振り分け、状況管理、検証、統合を担います。ワーカーセッションは、範囲を限定した作業を担います。ワーカーのサブエージェントは、各ワーカーセッション内で実装、調査、監査を支援するローカルヘルパーです。
基本的な考え方
User
-> Control session (strategy, dispatch, tracking, integration)
-> Worker project session A (persistent branch/workstream)
-> Subagents for research, implementation, review, tests
-> Worker project session B (persistent branch/workstream)
-> Subagents for local fan-out
-> Verifier/reviewer session (optional independent gate)
これは動的ワークフローに似ていますが、実行時スクリプトではなく、人が読み取れるセッションネイティブなオーケストレーションです。完全に自動化されたファンアウトよりも、永続性、ブランチ、PR、人による誘導、セッション間の継続性が重要な場合に使用します。
コードランタイムでは、検証済みの結果、バリア、予算、重複排除、再開といった信頼性が自動的に得られます。プロンプト駆動のコントロールプレーンで同じ信頼性を得るには、状態を機械でチェックできるようにする必要があります。ランタイムを使わずにこれを実現するのが、必須のワーカー結果ブロックと永続的なコントロール状態マニフェストという 2 つの契約です(機械でチェックできる契約を参照)。このスキルのほかのすべての処理は、これら 2 つの成果物を基準にしています。これらがなければ、「このワーカーは完了していて、検証にも合格しているか?」はフィールドの読み取りではなく、推測になってしまいます。
対応するコントロールアプリ
このスキルは特定のアプリに依存しません。まず、現在のセッションで利用可能なオーケストレーションツールを確認し、そのうえで同じコントロールワークフローを利用可能な環境に合わせて適用します。
| 機能 | Codex アプリ | GitHub Copilot アプリ | フォールバック |
|---|---|---|---|
| ワーカーセッションの検索 | プロジェクトスレッドを一覧表示/検索 | アプリのセッションを一覧表示/検索 | 対象セッションのリンク/ID をユーザーに尋ねる |
| 永続的なワークストリームの作成 | 利用可能な場合、Codex スレッド/ワークツリーを作成または再利用 | 利用可能な場合、Copilot アプリのセッション/ワークスペースを作成または再利用 | ローカルサブエージェントのみを使用 |
| 既存のワークストリームへの指示 | スレッドにフォローアッププロンプトを送信 | セッションにフォローアッププロンプトを送信 | ワーカーにプロンプトを貼り付けるようユーザーに依頼 |
| ローカルでのファンアウト | このセッションからサブエージェントを起動するか、ワーカー自身に起動を依頼 | Copilot が利用可能なエージェント/セッションツールを使用 | ローカルで作業を続ける |
| 追跡 | スレッドのタイトル、ピン、ブランチ、PR、キャンバスノード、簡潔な状況テーブル | セッション名、ブランチ、PR、イシュー、キャンバスノード、簡潔な状況テーブル | Markdown の状況テーブル |
GitHub Copilot や Codex のツール名を決めつけないでください。現在の環境で公開されているツールを使用し、ワーカーを振り分ける前に、どのコントロールサーフェスが有効かを明示してください。
使用する場面
次のような場合に、このスキルを使用します。
- コードベース全体の監査、移行、または同等性チェック
- モジュール、サービス、機能、PR にまたがる並行調査
- 実装者セッションと検証者セッションを分けると効果的な作業
- 設計、実装、テスト、レビューを分割するべき大規模な機能
- 「エージェントを調整して」「セッションを立ち上げて」「ワークフローを実行して」「ワーカーに任せて」「ほかのセッションを監視して」「コントロール役をして」といったプロジェクト管理の依頼
- ワーカーセッション自身がローカルでの調査、コーディング、レビューにサブエージェントを使う可能性がある状況
単純な 1 ファイルの修正、簡単な回答、またはローカルサブエージェント 1 つで十分なタスクには使用しないでください。オーケストレーションにはオーバーヘッドがあります。調整によってリスクが下がるか、処理能力が上がる場合にのみ使用してください。
機械でチェックできる契約
これらは、ランタイムの型付き結果と永続的な実行状態に相当する、セッションネイティブな仕組みです。人が読み取れる形式ですが、参考情報ではなく必須です。コントロールセッションは、文章を読み返す代わりにこれらを解析します。
ワーカー結果ブロック
すべてのワーカーは、レポートの末尾に control-result をタグとして付けたフェンス付きの ```json ブロックを必ず記載してください。コントロールセッションは、状態の更新、重複排除、振り分けの判断にこのブロックを使用します(周囲の文章は読みません)。
{
"worker_id": "auth-api",
"wave_id": "w1",
"unit_key": "service/auth",
"scope": "src/auth/** — refresh-token rotation",
"status": "complete",
"files_changed": ["src/auth/rotate.ts"],
"verification": { "command": "pnpm test auth", "result": "pass", "evidence": "42 passed" },
"subagents_used": "2 — one research, one test author",
"risks": ["rotation interacts with logout; covered by test"],
"next_step": "ready for review session",
"report_ref": "thread/PR/path to the full report"
}
解析できるよう、ブロックは厳密な JSON(コメントや末尾のカンマなし)でなければなりません。status は complete | blocked | needs-decision | failed のいずれか、verification.result は pass | fail | not-run のいずれかです。
制御状態マニフェスト
ミッションの唯一の信頼できる情報源となる、永続的な成果物です。ピン留めされた制御スレッド、トラッキング課題の本文、キャンバスノード、またはコミット済みの control/state.json が該当します。毎ターン再読み込みして更新し、会話は状態ではなく意思決定のために使います。ユニットごとに1行を設けます(ユニットをキーとすることで、同じユニットが二度ディスパッチされないようにします。これは重複排除台帳です)。
{
"mission": "MCP tool parity audit",
"non_goals": ["no behavior changes"],
"success_criteria": ["every tool present in server, HTTP, SDK, docs or flagged"],
"budget": { "max_concurrent_workers": 5, "max_total_workers": 25, "spawned": 0, "in_flight": 0 },
"convergence": { "rule": "single-pass", "k_empty": 2, "empty_streak": 0, "target": null, "current": 0 },
"worker_contract": { "schema_name": "control-result/v1", "required_output_schema": null },
"batch_guard": {
"service_key": null,
"pilot_unit_key": null,
"pilot_status": "not-required",
"pause_after_same_signature": 2,
"paused": false,
"failure_signatures": {}
},
"workers": [
{
"unit_key": "surface/http",
"worker_id": "http-audit",
"session_ref": "thread-or-session id/link",
"scope": "HTTP API surface",
"branch_or_pr": "—",
"status": "pending",
"wave_id": "w1",
"last_update": "ISO-8601",
"evidence_ref": "report_ref from the result block",
"verification": "not-run",
"blocker": null
}
],
"decisions": [],
"open_followups": []
}
ルール:
- ワーカーのステータス(ワーカーが結果ブロックで自己申告するもの):
complete | blocked | needs-decision | failed。 - マニフェストのユニットステータス(制御セッションが管理する上位集合):
pending | dispatched | needs-decision | blocked | stalled | complete | failed | dropped。ワーカーが報告する値はこれらのサブセットなので、ワーカーブロックからユニットのステータスを設定しても(ステップ 5)、常に有効です。 - 終端状態、つまりユニットがクローズされた状態は
complete | failed | droppedです。それ以外はすべて非終端状態であり、ミッションをクローズする前に解決するか、理由を明記して明示的にdroppedにする必要があります(ステップ 8)。 budget.in_flightは、現在dispatchedの行数です。ディスパッチ時にspawnedとin_flightを増やし、ユニットがdispatchedから離れたときにin_flightを減らします。再ハイドレート時には、行から再計算します。convergence.ruleはsingle-pass | loop-until-dry | loop-until-budget | accumulate-to-targetのいずれかです。k_empty/empty_streakはloop-until-dryの場合にのみ使用し、target/currentはaccumulate-to-targetの場合にのみ使用します(target= 件数または網羅率の目標、current= これまでの進捗)。worker_contract.required_output_schemaには、存在する場合、呼び出し元が指定した正確な構造化出力スキーマを保存します。既定のコントラクトはcontrol-result/v1です。外部スキーマを言い換えたり、黙って置き換えたりしてはいけません。batch_guardには、同種の外部サービスを使うバッチのパイロット実行と、正規化された失敗シグネチャを記録します。service_keyは共有依存先を識別するものであり、個々の項目を識別するものではありません。dropped/failedのユニットには、必ずopen_followupsに理由を記載する必要があります。
新しい制御セッションは、このマニフェストから状態を再ハイドレートします(ステップ 0)。
制御ワークフロー
0. 再ハイドレート(進行中のミッションを再開する)
セッション開始時に、このミッションの既存の制御状態マニフェストを探します。存在する場合:
- 読み込み、唯一の信頼できる情報源として扱います。
session_refでワーカーに再接続し、新たなディスパッチを行う前に、各ワーカーの実際のステータスを再確認します(スレッド/PR を読みます)。dispatchedのままの行からbudget.in_flightを再計算します。- ステータスが
dispatchedまたはcompleteのユニットを再ディスパッチしてはいけません。代わりにフォローアップに回します。
マニフェストが存在しない場合は新しいミッションです。ステップ 1 で作成します。
1. ミッションの枠組みを定める
何かを起動する前に、以下を記録し(マニフェストに書き込み)ます。
- 目的と対象外事項
- 対象範囲のリポジトリ、ブランチ、PR、課題
- 各ワークストリームのファイルまたはサブシステムの境界
- 成功基準と検証ゲート
- マージ/統合に関する想定
- 「変更禁止」の制約
- 呼び出し元または実行環境が要求する場合は、正確なワーカー出力スキーマ
- 複数項目のバッチで使用する共有外部サービス
また、明示的な上限を事前に設定します(マニフェストの budget と convergence)。
max_concurrent_workers(既定値は約 4~6)— 同時に進行中にできる数はこれを超えてはいけませんmax_total_workers— ミッション全体を通じた上限(例:25)- 任意のトークン/コスト/時間の上限
- 収束ルール:範囲が明確なミッションには
single-pass、終わりのない監査/移行/パリティ確認にはloop-until-dry、loop-until-budget、またはaccumulate-to-target
境界が曖昧で、編集の競合を招く可能性がある場合は、ディスパッチ前に確認してください。
2. 制御サーフェスを特定する
ディスパッチする前に、利用可能なアプリツールを特定してください。
- Codex アプリ:一覧表示、作成/読み取り、メッセージ送信、名前変更、ピン留め/アーカイブなどのスレッド/セッションツールと、利用可能な場合はローカルサブエージェントツール。
- GitHub Copilot アプリ:アプリコネクターが公開するセッションまたはワークスペースツールと、利用可能な GitHub のイシュー/PR/ブランチ操作。
- 汎用エージェントアプリ:セッション、タスク、サブエージェント、ブランチ、イシュー、PR、自動化ツールの任意の組み合わせ。
永続セッションツールが利用できない場合は、ローカルのマルチエージェント計画に切り替え、その制約を説明してください。バックエンドを捏造してはいけません。
3. トポロジーを選択する
必要最小限のトポロジーを選んでください。
- ワーカー 1 つ:独立して実装できる作業やバグ修正で、専用のプロジェクトセッションで行うべきもの。
- 並列ワーカー:互いに独立したモジュール、パッケージ、エンドポイント、テスト、ドキュメント。
- 調査後に実装:探索的なセッションが調査結果を報告してから、コーディングを開始するもの。
- 実装者 + 検証者:1 つのセッションでコードを変更し、別のセッションで独立してレビューまたは検証するもの。
- 制御のみ:ワーカーはまだ起動せず、状態の確認、セッションの一覧表示、ディスパッチの計画だけを行うもの。
ワーカーが重複する履歴を編集する可能性がある場合、異なるブランチが必要な場合、または長期にわたるコンテキストが必要な場合は、別々のセッションを優先してください。タスクが探索的で、永続的なブランチ状態を必要としない場合は、1 つのセッション内のローカルサブエージェントを優先してください。
4. 完全なプロンプトでワーカーをディスパッチする
予算を守ってください。in_flight >= max_concurrent_workers の場合、絶対にディスパッチしてはいけません。その単位をキューに入れ(status: pending)、記録してください。max_total_workers またはトークン/コストの上限に達したら、ディスパッチを停止し、判断が必要であることを提示してください。ディスパッチはアトミックなマニフェスト更新です。単位の行を status: dispatched(session_ref、worker_id、wave_id、last_update を設定)にし、spawned と in_flight を同時にインクリメントします。ディスパッチの開始に失敗した場合は、行を pending のままにし、どちらのカウンターも進めてはいけません。単位が dispatched から離れたとき(終端状態に達したとき、または needs-decision/blocked/stalled に戻ったとき)に in_flight をデクリメントし、キューに入った単位を開始できるようにしてください。これにより、in_flight は Step 0 で再計算される dispatched 行の数と一致します。
各ワーカープロンプトは、それだけで完結している必要があります。次の情報を含めてください。
- ミッションと正確な対象範囲(および
unit_key) - ファイル、サブシステム、イシュー/PR リンク、ブランチに関する要件
- ワーカーが変更してよいものと、変更してはいけないもの
- 検証コマンドまたは受け入れ基準
- コミットや PR を作成してよいか、報告のみか
- 必須の出力形式
ワーカープロンプトのテンプレート:
You are worker <name> for <project>.
Mission: <specific outcome>
unit_key / wave_id: <key> / <wave>
Scope: <files/subsystems/issue/PR>
Do not touch: <boundaries>
Approach: <expected plan or constraints>
Verification: <commands/checks/evidence>
Required output schema: <exact JSON schema, or "control-result/v1">
Submission format: <default control-result block, or exact external-schema instruction>
You MAY use your own subagents for local research, implementation, and review, but you remain
accountable for this scope and the final report. Do NOT create or steer further persistent project
sessions — if the work needs another full workstream, say so in next_step.
Follow the submission format exactly and validate the payload against the required output schema
before submission. The control session reads only that payload.
control-result/v1 の場合は、すべてのフィールド(subagents_used を含む)を入力したフェンス付きの json control-result ブロックを提出形式として指定してください。呼び出し元が別のスキーマを要求する場合は、すべての必須ルートキーと型を含め、そのスキーマをそのまま保存して含めてください。また、ワーカーには control-result ラッパーを付けず、そのスキーマのみを正確に返すよう指示してください。実行サーフェスが構造化出力の検証に対応している場合は、同じスキーマで設定してください。対応していないサーフェスに対して引数を捏造してはいけません。ディスパッチ前に、外部スキーマから制御マニフェストへの情報損失のないアダプターを定義してテストしてください。アダプターがなければ、いずれかの契約を近似するのではなく、needs-decision を返してください。
Codex アプリの操作を使用する場合は、セッションの関連図が分かりやすくなるよう、重要なワーカー/制御スレッドの名前を変更し、ピン留めすることを優先してください。GitHub Copilot アプリの操作を使用する場合は、公開されていれば対応するセッションまたはワークスペースのラベルを使用してください。
同一の共有サービスを使用するバッチのパイロット実行
外部サービスを介して、同質な大規模バッチを一括でディスパッチする前に:
batch_guard.service_keyを設定し、代表となるpilot_unit_keyを選択します。- パイロットだけをディスパッチし、残りのユニットは
pendingのままにします。 - パイロットがスキーマに準拠した結果を返し、受け入れチェックに合格した後にのみ、バッチを実行します。
項目 ID が異なっていても、障害が独立しているとは限りません。同じ正規化済み障害シグネチャが異なる 2 つのユニットで発生した場合は、batch_guard.paused: true に設定し、そのサービスを共有するキュー内の起動を停止して、ブロッカーを報告します。診断または入力が実質的に変更された場合、あるいはリスクを受け入れる明示的な決定がなされた場合にのみ、再開してください。
5. 状態を一元管理する
制御状態マニフェストを唯一の信頼できる情報源とし、会話ではなく、毎ターン更新してください。受け入れた各ワーカーの結果から(必要な場合は、テスト済みアダプターを適用した後で)、ユニットの status、evidence_ref、verification を設定し、status が blocked または needs-decision の場合は blocker も設定します(それ以外の場合は null)。control-result/v1 では、これらは report_ref、verification.result、ブロッカーの理由に対応します。残りのフィールドは制御セッションで記録します。制御セッション自身の時計を使って last_update を記録し、判明している場合はワーカーのセッション/PR メタデータから branch_or_pr を設定します。制御セッションのコンテキストは、トランスクリプト全体ではなく、要約と決定に焦点を当ててください。完全なレポートは evidence_ref に保存します。
少なくとも各ユニットについて、unit_key、worker_id、session_ref、スコープ、ステータス、ブランチ/PR、最終更新日時、ブロッカー、検証状態を、上記の行スキーマに合わせて記録します。アプリで利用できる場合、Canvas ノードまたは SQL/todo テーブルをマニフェストのバックエンドとして使えます。
6. フォローアップを振り分ける(result-gate)
ワーカーから報告があったら、まず result-gate を実行します。
worker_contractで必要とされるペイロードを解析します。デフォルトのコントラクトではフェンス付きのcontrol-resultブロック、それ以外では指定された外部ペイロードです。必須フィールドが欠落しているか、不正な形式である場合は、受け入れず、修正済みのペイロードだけを求める標準化された再プロンプトを 1 回だけ送ります。再試行は最大 2 回までとし、その後はユーザーにエスカレーションします。- 外部スキーマの場合は、テスト済みアダプターを適用する前に、必須のルートキー、型、列挙値をすべて検証します。デフォルトの
control-resultが有効でも、呼び出し元が指定したスキーマに準拠していなければ無効です。 - 検証とアダプターの適用後、ステータスとエビデンスが矛盾する完了結果は拒否します。通常、
status: completeにはverification.result: passが必要です。 - ソースに基づく読み取り専用の調査ユニットは、マニフェストのスコープと成功基準に実行時検証が対象外と明記されており、
files_changedが空で、エビデンスが調査したソースを引用し、未テストの実行時に関する主張をせずにそれらの基準を満たす場合に限り、verification.result: not-runを使用できます。マニフェストにはnot-runを正確に記録してください。ツールが利用できない場合、チェックが省略された場合、または実装/設定が変更された場合は、この例外には該当せず、未検証の作業として拒否する必要があります。 - ブロックが検証に合格し、かつ成功基準を満たした場合にのみ、完了した作業を受け入れます。
その後、次のように振り分けます。
- 検証の欠落、スコープの逸脱、ブロッカーについて、対象を絞ったフォローアップを送ります。
- ワーカーの結果が不完全または疑わしい場合を除き、調査を重複させないでください(まずユニット台帳を確認します)。
- 2 人以上のワーカー間で矛盾がある場合は、さらなる編集が行われる前に統合を一時停止し、担当範囲を解決します。
- 外部サービスの障害が繰り返し発生する場合は、変動する項目 ID、リクエスト ID、タイムスタンプを除去して正規化します。シグネチャと影響を受けたユニットキーを
batch_guard.failure_signaturesに記録し、設定されたしきい値に達したら、そのサービスを共有するキュー内のユニットを一時停止します。一時的な再試行では上限付きのバックオフを使用できますが、同じ障害がすでに発生しているサービスに対して、再試行を同時に多数発行してはなりません。
7. 波を収束するまで反復する
複数の波があるミッションでは、波のフォローアップを割り当てた後、統合する前に宣言済みの convergence.rule を適用します。
- single-pass — 1 つの波のみです。統合に進みます。
- loop-until-dry —
k_empty回連続して新しい(重複排除済みの)ユニットが 0 件となるまで、ユニットを開き続けます。マニフェストのempty_streakを維持してください。 - loop-until-budget — 予算上限に達したら停止します。
- accumulate-to-target — 目標の件数/カバレッジに達したら停止します。
「新しい」および「空」は、メモリではなく、マニフェスト内の unit_key の集合を基準に判断します。黙って反復を止めてはいけません。反復を終了した理由を open_followups/decisions に記録してください。
8. 検証して統合する
ミッションの完了を宣言する前に、次を行ってください。
- 合意した検証ゲートを実行するか、実行を委任します。
- 差分を確認するか、独立したレビュアーセッションに重要度の高い指摘を求めます。
- ワーカーの出力が適切なブランチ/セッションに統合されていることを確認します。
波の合流/完全性ゲート: マニフェスト内のすべてのワーカー行が終了状態(complete、failed、dropped)になっている場合に限り、ミッションは完了です。終了状態でない行(pending、dispatched、needs-decision、blocked、stalled)は、まず解決する必要があります。解決できないユニット(たとえば、チェックポイントまでに応答がなく、stalled とマークされたワーカー)は、理由を明記して dropped に変更する必要があります。その場合に限り、ミッションを "complete with N dropped: <ids +
reasons>" と宣言できます。終了状態でない行を残したまま終了してはいけません。また、黙ってドロップしてはいけません。最終的な要約には、割り当てたすべてのユニットを列挙してください。
ポーリングのタイミング(プッシュ通知なし): セッションネイティブの制御プレーンには、セッションを再開させる「ワーカー完了」イベントがありません。波を割り当てた後、次のチェックポイントを起動する条件(フォローアップのターン、ステータステーブルのポーリング、またはユーザーからの通知)を定め、波を未合流のまま放置してはいけません。
PR に関連する作業では、最終的な PR の準備とレビューの振り分けを制御セッションが担当するようにしてください。
安全ルール
- 些細なタスクのためにワーカーを起動しないでください。
- 明示的に調整していない限り、複数のワーカーに同じファイルを編集させないでください。
- 名前が挙がったアプリコネクターが存在すると決めつけず、検出を試み、見つからない場合は正直に別の方法を使ってください。
- ブランチ、コミット、プッシュ、PR を黙って作成しないでください。ユーザーの同意とリポジトリのルールに従ってください。
- セッションをまたいで秘密情報や機密データを共有するようワーカーに依頼しないでください。
- ワーカーサブエージェントは末端のヘルパーです。永続的なセッションをさらに作成したり、指揮したりしてはいけません。階層は厳密に 2 段階(制御 -> ワーカー -> サブエージェント)です。別の完全な作業ストリームが必要なワーカーは、その必要性を制御セッションに報告してください。
- 同時実行数と総ファンアウト数の上限を守り、黙って超過してはいけません。ドロップ、スキップ、失敗したユニットは、理由とともに記録する必要があります(黙って打ち切らないでください)。
- 外部サービスを使う同種の大規模なバッチ処理は、小規模な試行で確認してから行い、共通する失敗のパターンが繰り返される場合は中断してください。
- 既存のチェックアウトを使用する場合は、他のユーザーが所有する変更がすでに存在する可能性があるため、特に注意してください。
- 計画に重大な変更が生じた場合は、続行する前にユーザーとワーカーに知らせてください。
推奨する報告形式
マニフェストから作成した行を使い、簡潔な制御プレーンの更新を行います。
**Status:** <on track | blocked | needs decision | complete>
**Budget:** in-flight <X/Y> · spawned <A/B> · wave <N> (empty-streak <E>)
| Workstream | Session | Scope | State | Evidence |
|---|---|---|---|---|
| <name> | <id/name> | <scope> | <state> | <test/report/PR> |
**Decision needed:** <only if blocked>
ユーザー向けの更新は簡潔にしてください。制御セッションでは、調整状況を分かりやすく伝えつつ、各ワーカーのやり取りをすべてユーザーに見せないようにしてください。