Get started
クラウドワーカー計画
ステータス
提案、改訂3。未実装。方向性は2026-07に合意済み。改訂2では敵対的レビューの指摘事項(専用ワーカープロトコル、配置/環境ステートマシン、git対応の受信同期、一方向のv1ハンドオフ、制御された外向き通信に関するセキュリティ表現)を反映した。改訂3では同期の所有権モデル(ワーカーがコミットを作成し、Gatewayが取り込んで公開する)を確定し、gitを使用しない単純同期モードを追加し、ワーカーでのexecをボックス内で完全に実行するよう修正し、インターネットポリシーをプロビジョニング時へ移し、エージェントによるディスパッチをマイルストーン3に戻した。
問題
OpenClawのエージェントセッションは、1台のマシン上にあるGatewayプロセス内でループ、ツール、推論を実行する。計算能力はそのマシンによって制限され、長時間のタスクがマシンを占有し、並列作業がリソースを奪い合う。ホスト型製品(Cursor cloud agents、Claude Code on the web、Codex cloud)は、タスクごとに一時的なクラウドサンドボックスを用意することでこの問題を解決しているが、ベンダーのインフラとベンダーへの信頼が必要になる。
予備のマシンをすでに所有している(または安価に借りられる)運用者には、「このセッションをあちらで実行し、ほかのセッションと同じようにサイドバーへ表示し、終了後はマシンを破棄する」と指定する手段がない。
目標
- 完全なエージェントセッション(ループ+ツール)を一時的なリモートマシン(「クラウドワーカー」)で実行しつつ、そのセッションをローカルセッションとまったく同じようにControl UIへ表示し、ストリーミングする。
- ワーカーには常設の認証情報(プロバイダー認証やフォージトークン)を置かず、直接の外向きネットワーク通信も許可しない。ボックスに必要なのは、到達可能なsshdだけとする。
- プロビジョニング、同期、実行、収集、破棄を完全に自動化し、プロバイダーを差し替え可能にする(最初のプロバイダー:Crabbox形式のリースCLI)。
- 実行中の作業をターン境界でGatewayからワーカーへディスパッチし、トランスクリプト、セッションID、または(リクエストのバイト列が同等のままである場合)プロバイダーのキャッシュ親和性を失うことなく、安全に結果を取得する。
- 人間(UI)とエージェント(ツール)の両方が、作業をクラウドワーカーへディスパッチできる。
- 数日間にわたるセッションをサポートする。有効期間はポリシーであり、ハードコードされた上限ではない。
対象外(v1)
- ワーカー上で外部のコーディングハーネス(Claude Code、Codex CLI)を使用しない。ワーカーセッションはOpenClawの組み込みランナーのみを実行する。ハーネスは独自の認証情報を使って独自に推論するため、そのサポートはv2でのオプトインとする。
- best-of-Nや並列試行のファンアウトは行わない。
- VPN/テールネットへの依存は設けない。転送にはSSHのみを使用する。
- 新しいサンドボックスランタイムは導入しない。ワーカーマシンを隔離境界とし、ボックス内のOSサンドボックスは後から重ねられる。
- v1では対称的なライブマイグレーションを行わない。ディスパッチはローカル → ワーカーのみとする。ワーカー → ローカルには、停止済みセッションと完了済みのワークスペース調整が必要になる。ライブ双方向ハンドオフは、後から同じバリア機構の上に構築する。
- Gateway上にJSON形式の副次状態を置かない。環境、配置、カーソル、権限付与の状態はSQLiteに保存する。
先行事例(取り入れる点、反転させる点)
- Cursor cloud agents:エージェントループは同社のクラウドで実行され、VMはツール実行先となる。追記専用の会話ストアがすべてのクライアントへストリーミングされ、インストール後のスナップショットからウォームスタートし、セルフホスト型ワーカーは外向き接続専用のワーカープロセスである。「会話の信頼できる唯一の情報源をオーケストレーターに保持する」という考え方とストリーミングモデルを取り入れる一方、ループの配置は反転させる(後述の決定を参照)。
- Codex cloud:ネットワーク接続可能なセットアップフェーズと、シークレットを除去したオフラインのエージェントフェーズからなる二段階ランタイム。高速な後続処理のためにコンテナ状態をキャッシュする。外向き通信の方針としてこのフェーズ分割を、v2のウォームイメージ向けにキャッシュの考え方を取り入れる。
- Claude Code on the web:セッションごとのVM、認証情報を隔離するgitプロキシ(実際のトークンはサンドボックスへ入らず、pushはセッションブランチに制限される)、セットアップ後のファイルシステムスナップショット、push済みブランチ+再生された履歴によるテレポートハンドオフ。認証情報の隔離とハンドオフの枠組みを取り入れるが、送信同期はGatewayからのrsyncで行うため、未コミットの変更がある作業ツリーにも対応でき、フォージトークンはボックスの近くに一切存在しない。
- Copilot coding agent:パッケージレジストリの許可リストを使用したデフォルト拒否の外向き通信。定常状態における既定値はさらに強く(直接の外向き通信を一切許可しない)、推論とウェブ検索はSSHトンネル経由で到達する。ただし、これが「外向き通信ゼロ」ではなく「制御された外向き通信」である理由については、セキュリティの節を参照。
アーキテクチャ上の決定:ループはワーカー上、推論はGateway経由
3つの配置を検討した。
- ループをGateway上に残し、ワーカーがツールを実行する(Cursorモデル)。障害領域として最も安全であり(トランスクリプト、推論、承認、再起動時の復旧がすべてローカルに残る)、レビュー担当者が最初のマイルストーンとして推奨した方式でもある。しかし、製品アーキテクチャとしては採用しなかった。OpenClawのexec以外のツールはプロセス内のファイルシステム操作であるため、ファイルの読み取り/編集/grepのたびにネットワーク往復が発生するか、ツール境界を粗粒度のワークスペースRPCへ大規模にリファクタリングする必要がある。ランタイムの動作は通信頻度が高く、レイテンシに制約される。すでに構築されている箇所(Nodeへのexecオフロード)ではこの考え方を再利用するが、ツールのリモート化レイヤーは構築しない。
- ループと推論の両方をワーカー上で実行する。障害領域は最も単純だが、モデルの認証情報(OAuthプロファイルを含む)を使い捨てマシンへ送る必要があり、Gatewayはポリシー、ルーティング、監査の制御を失い、マイグレーションによってプロバイダー呼び出し元のIDが切り替わり、プロバイダーのキャッシュが無効になる。
- ループ+ツールをワーカー上で実行し、モデル呼び出しをGateway経由でプロキシする。これを採用する。ツール呼び出しごとではなく、モデルのターンごとに1往復となる。ツールはコードの近くで実行される。Gatewayは認証プロファイル、プロバイダールーティング、ポリシーの唯一の所有者であり続ける。ワーカーはシークレットを保持しない。
選択肢3では、各モデルターン中に同期的にGatewayへ依存するコストが発生する。そのため、耐久性の規則は後付けではなく、この決定の一部となる。
- ターンの途中でGatewayが失われると、実行中のプロバイダー呼び出しは失敗する。そのターンは失敗として記録され、再接続後に新しいターンとして再試行される。実行中のプロバイダーストリームを透過的に再生することはない(二重課金/二重ツール呼び出しのリスクがあるため)。
- ワーカー↔Gateway間のすべての操作には永続的なID(「ワーカープロトコル」を参照)を付与し、再接続時には処理を未完了のまま残すのではなく、再開するか、キャッシュ済みの最終結果を取得する。
- Gatewayは容量管理対象のコンポーネントとする。同時実行ワーカー数の制限、フロー制御、負荷遮断はv1の範囲に含める(「容量」を参照)。
Gatewayはトランスクリプトを保存すると同時に、すべてのプロバイダートラフィックの発信元でもあるため、セッションは場所に依存しない。Gatewayとワーカーの間でループを移動しても、プロバイダー側にもUIのデータ経路にも何も変化はない。これにより、ディスパッチと引き戻しを低コストで実現できる。
コンポーネント
1. 環境ステートマシン+プロバイダー契約
Gatewayプロトコルのenvironments.*は、現在はステータスのみの投影である。永続的な中核として、RPCの形式より先に設計された、SQLite所有の環境レコードとステートマシンを使用する。
requested → provisioning → bootstrapping → ready → (attached|idle) → draining → destroying → destroyed | failed | orphaned
- プロビジョニングはクラッシュセーフである。プロバイダー呼び出しの前に、決定論的な操作IDとともに意図を示す行を永続化するため、Gatewayの再起動後も二重にプロビジョニングしたり有料マシンを孤立させたりすることなく、実行中のリースを引き継げる。
- 再起動時の調整と孤立リソースのスイーパー(プロバイダーの
inspectとローカルレコードの比較)は、堅牢化ではなくv1の要件である。
プロバイダー契約(Pluginで実装し、コアにはプロバイダー名やポリシーを含めない):
type WorkerProvider = { id: string; provision(profile: WorkerProfile, opId: string): Promise<WorkerLease>; // → ssh host/port/user/key material inspect(lease: { leaseId: string; profile: WorkerProfile }): Promise<LeaseStatus>; // adopt/health/orphan sweep renew?(leaseId: string): Promise<void>; // long-lived sessions vs provider TTLs destroy(lease: { leaseId: string; profile: WorkerProfile }): Promise<void>; // idempotent, returns only on proof of teardown};RPC:environments.create、environments.destroy、拡張されたenvironments.list/status(プロバイダー、リースID、状態、経過時間、アイドル時間、接続中のセッション)。最初のプロバイダーは、Crabbox形式のリースCLIラッパー(製品向け経路)と、開発専用と明記した静的SSHホストプロバイダーとする。共有ホスト上のワーカーはホスト内の無関係なデータを読み取れるため、静的ホストは機能開発用であり、既定のセキュリティ方針ではない。
2. ワーカーのブートストラップ:ボックスへのOpenClawのインストール
専用のワーカー成果物は用意せず、npmの可用性にも依存しない。
- すべてのモードでの標準インストール:Gatewayが生成した、コンテンツハッシュ付きのワーカーバンドル(Gateway自身のビルド出力をtarballとしてパッケージ化したもの)をSSH経由で転送し、ボックスへインストールする。これにより、開発ビルドと未リリースのコミットも構造上そのまま対象となる。
- Gatewayがリリース済みバージョンを実行している場合、
npm i -g openclaw@<exact gateway version>を最適化として使用できる。latestは決して使用しない。 - ブートストラップは冪等である。バンドルハッシュが一致するウォームリースでは、インストールを省略する。未構成のマシンでは、ネットワーク接続可能なツールチェーンフェーズ(Nodeランタイム)が必要になる場合がある。これはセットアップフェーズの一部であり、その後は閉じられる。
- ハンドシェイクでは、ワーカーのビルドハッシュ、プロトコル機能セット、ランタイム互換性を検証する。既存のGatewayバージョン/プロトコル検査では不十分である(SSHトンネル経由のNodeは厳密なバージョン拒否の対象外となる)ため、ワーカーの受け入れ処理で独自に完全一致のビルド検査を行う。
ワーカーモード(openclaw worker)はフォークではなく、エントリーポイントである。接続処理と組み込みエージェントランナーを含み、セッション永続化とモデル呼び出しはGateway RPCによって提供される。Gatewayの機能面を起動してはならない。チャンネルは起動せず、セッションのツールセット以外のPluginは自動起動せず、使い捨ての状態ディレクトリを使用し、ローカルの認証プロファイルは持たない。
3. 転送:すべてSSH経由
接続性はGatewayが所有し、ワーカーに必要なのはsshdだけである。
- GatewayはワーカーへのSSH接続を開き(認証情報はプロバイダーのリースから取得し、ホストキーはプロビジョニング出力から固定する。
StrictHostKeyChecking=noは使用しない)、ワーカーのローカルソケットをGatewayのWSエンドポイントへ転送するリバーストンネルを確立する。 - 制御/モデルのトラフィックとワークスペース転送には、同じ固定済みの信頼情報を使った別々のSSH接続を使用し、rsyncがトークンストリームを先頭ブロッキングしないようにする。
- トンネルのライフサイクル(キープアライブ、バックオフ付き再接続)は、Gateway上の環境ランタイムが所有する。トンネルの一時的な切断はセッションレベルでは不可視である。以下の永続的なプロトコル状態により、ワーカーは再接続して再開できる。
4. ワーカープロトコル(専用。Nodeプロトコルではない)
現在のNode境界に対する敵対的レビューにより、単純な再利用は不適切と判断された。保留中のNode呼び出しは接続とともに失われるプロセスローカルなPromiseであり、Nodeの冪等性キーは解析されるものの重複排除には使われていない。さらに決定的な点として、接続済みNodeは通常のNodeイベント(エージェント実行リクエストを含む)を送信できるため、「Node種別+機能上限」は受信セキュリティ境界にならない。したがって、ワーカーには、閉じたバージョン管理済みRPC/イベント許可リストを持つ認証済みのworkerロールを用意する。ワーカー接続から従来のNodeイベントハンドラーへ到達することはできない。
IDと認証情報:プロビジョニング時に、環境ID、ワーカーキー、バンドルハッシュ、許可された単一セッション、許可されたRPCセット、有効期限に紐づく短期ワーカー認証情報を発行する。SSHで検証されたペアリングも引き続き適用される(こちらがボックスをプロビジョニングし、キーを保持している)が、認可は宣言されたNode機能面ではなく、発行された認証情報に基づく。
永続的な操作セマンティクス(既存のACPランタイムとそのイベント台帳から形式を借用する。安定したハンドル、セッションごとの直列化、永続的な(session, seq)再生):
- すべての操作は
(sessionId, lifecycleRevision, runId, ownerEpoch, streamKind, seq)のスコープを持つ。 - 所有権エポックによって古いワーカーを排除する。代替ワーカーはエポックを進め、古いエポックから遅れて届いた結果は決定論的に拒否される。
- SQLiteに永続化されたACKカーソルとキャッシュ済みの最終結果を使用する、少なくとも1回の配信とする。重複排除は決定論的に行う。厳密に1回の保証は行わない。
- キャンセル、クローズ、再開、最終結果のための明示的なフレームを用意し、ストリームにはクレジット/ウィンドウ方式のフロー制御を使用する。
- プロトコル機能のネゴシエーションは、一般的なNodeプロトコルのバージョンから独立させる。
5. セッションバックエンドRPC
2 つの異なる契約 — 現在のコードベースでは、永続的なトランスクリプト変更(セッションマネージャーが所有し、親/リーフ状態を持つ JSONL ツリー)と、プロセスローカルなライブイベント(ストリーミング差分、ツールのライフサイクル、承認)を分離しており、ワーカープロトコルでもこの分離を維持する必要がある。
- 永続的なトランスクリプトのコミット: ワーカーは
runEpochとベースリーフの比較交換を伴う、意味的な追記バッチを送信する。Gateway のセッションマネージャーがエントリ ID と親 ID を生成する。ワーカーが、信頼済みトランスクリプト行、エントリ ID、親 ID、または別セッションの ID を指定することは決してできない。 - 再生可能なライブイベント: ワーカーのシーケンス番号、Gateway の ACK、上限付き保持、遅延イベントのフェンシングを備えた型付きイベントユニオン。既存のエージェントイベントのファンアウトに供給することで、チャットビュー、ツール行、未読/ステータスロジックがローカルセッションと同一に動作する。
推論プロキシ: 既存のランタイムプロキシストリームクライアント(src/agents/runtime/proxy.ts)のイベント語彙を再利用するが、信頼境界を移動する。ワーカーが送信するのは、セッション/実行の識別情報、承認済みモデル参照、コンテキスト、制約付き生成オプションのみとする。Gateway は、自身のカタログからプロバイダー、エンドポイント、認証、ヘッダー、ルーティング、コストポリシーを解決する。ワーカーから提供されたモデルオブジェクト(例: 攻撃者が制御する baseUrl)は拒否する。リクエストサイズ制限、キャンセル、監査、終了結果の再生を適用する。Gateway 常駐ツール(websearch)は Gateway 上で実行し、同じチャネル経由で結果を返す。
6. ワークスペース同期
同期の基点は、排他的な配置所有権を持つ Gateway ローカルのワークスペースとする。git ワークスペースでは、専用の管理対象ワークツリー(既存の管理対象ワークツリーのメタデータ — ブランチ、ベース、スナップショットの所有権 — を基盤とする)を使用し、git 以外のワークスペースでは、Gateway が所有する対象ディレクトリを使用する。ユーザーの使用中のチェックアウトは決して使用しない。セッションがリモートに配置されている間の排他的所有権により、受信同期は構造上競合しない。
所有権の分離 — コミットと公開:
- ワーカー側のエージェントは、自身のコピー内で通常どおりコミットを作成する(
git commitはローカルかつ認証情報不要の操作であり、作成者の識別情報は Gateway 設定から反映される)。これらのコミットは、Gateway が採用するまで不活性なオブジェクトである。 - 信頼を必要とするすべての処理は Gateway が行う。受信コミットが記録済みベースを基に構築されていることの検証、ローカルワークツリーの fast-forward、push、PR 作成、任意の署名/再署名を、すべて Gateway ローカルの認証情報で実行する。ワーカーは git や forge の認証情報を保持せず、リモートにも一切アクセスしない。
ワークスペースが git リポジトリかどうかに応じて、次の 2 つの同期モードを選択する。
- Git モード。送信: ワークツリーを rsync し(未コミットファイルと対象となる未追跡ファイルを含む。crabbox 形式の include/exclude を使用し、
.worktreeincludeを尊重する)、トンネルの SSH 識別情報を介して転送する。その状態を不変のベースマニフェスト(コンテンツハッシュ + ベースコミット)として記録する。受信: 新しいコミットを、記録済みベースに対する git bundle または一時 ref として返す。未追跡の成果物は、サイズ/種類/シンボリックリンク封じ込めチェックを含む明示的なマニフェスト経由で返す。採用時にベースの祖先関係を検証し、分岐があれば停止する。どちら側も暗黙には上書きしない。削除、名前変更、サブモジュール、シンボリックリンクによる脱出は、rsync のヒューリスティックではなくマニフェスト規則で処理する。 - プレーンモード(git なし — 例: ボックス上でプロジェクトをゼロから構築する場合)。送信は同じ rsync + ベースマニフェストを使用する。受信では、マニフェスト差分を反映したミラーを Gateway 所有の対象ディレクトリへ戻し、削除も伝播する。Git モードと同じ理由で安全である。排他的所有権により、競合する同時ローカル編集が存在しないためである。ベースマニフェストは予期しないローカルドリフトを引き続き検出し、上書きせずに停止する。
チェックポイント処理により、数日間にわたるセッションをリース喪失から保護する。受信チェックポイントを定期的に作成し(git モードではセッションブランチへのコミット、プレーンモードではマニフェストスナップショット)、頻度はプロファイルポリシーとする(デフォルトはターン単位)。
7. 配置ステートマシン、セッション、UI
ランタイム配置は、ばらばらな 2 つの行フィールドではなく、セッションをキーとする SQLite 所有のステートマシンである。
local → requested → provisioning → syncing → starting → active(worker) → draining → reconciling → local | reclaimed | failed
環境 ID、遷移世代、アクティブ所有者エポック、ワークスペースのベースマニフェスト、ワーカーバンドルのハッシュ、最新の ACK カーソルを永続化する。どちらかのループがターンを開始する前に、ターン受付が配置をアトミックに獲得するため、古いスナップショットに基づいて受け付けられたローカルメッセージがワーカーのターンと競合することはない。常に 1 つのループだけがセッションを所有する。
UI:
- ワーカーセッションは、配置メタデータが付加された通常のセッション行である。通常のストアに存在し、
sessions.listで一覧化され、既存のサブスクリプション経由でストリーミングされる。サイドバーとチャットに新しいデータパスは不要であり、必要なのはワーカーバッジと配置/環境ステータス(provisioning / syncing / running / idle / reconciling / reclaimed)の表示だけである。 - 作成 UX: セッション対象バー(セッションサイドバーの再設計)に、Gateway と Node に加えてクラウドワーカーの宛先を追加する。設定済みのプロバイダープロファイルが必要であり、設定されるまではこの機能を表示しない。
- エージェントディスパッチ: セッションツールにより、人間と同じ方法でエージェントが作業をクラウドワーカーへ引き渡せるようにする(ワーカーを基盤とするサブセッション、サブエージェント形式)。人間によるディスパッチと同じマイルストーンで提供し、同じオプトインのプロバイダー設定で制御する。再帰は構造的に制限する(v1 では、ワーカーセッション自身が別のワーカーをディスパッチすることはできない)。支出制御は環境単位の会計/監査で行い、クォータ機構は使用しない。
ディスパッチと引き継ぎ
v1 は意図的に非対称とする。
- ローカル → ワーカー(ディスパッチ): 下記の移行バリアを通過し、ワーカーをプロビジョニングまたは再利用して同期し、配置を切り替える。次のターンはリモートで実行される。
- ワーカー → ローカル(引き戻し): セッションを停止し(同じバリアに従ってワーカーをドレインする)、受信調整を完了して、配置をローカルに切り替える。ライブマイグレーションではない。
- 対称ライブ引き継ぎ(作業中のセッションを停止せず双方向に移動する)は、同じバリアと調整機構を再利用し、障害注入テストでバリアが実証された後に提供する。
移行バリア(「ターン境界」だけでは不十分である。承認、バックグラウンドプロセス、解放済みロックに対するトランスクリプトのマージは、その境界をまたぐ可能性がある):
- 新しいターンの受付を停止する(配置の獲得)。
- アクティブな実行をキャンセルまたはドレインする。
- 保留中の exec 承認と実行許可を取り消す。
- トランスクリプトの副次書き込みとライブイベントの ACK をドレインする。
- ワーカーの子プロセスを終了する。
- 所有者エポックを進めて、以前の所有者をフェンシングする。
- ワークスペースを調整する(受信、競合考慮)。
- 新しい所有者を有効化する。
キャッシュアフィニティ: どちらの配置でもプロバイダーリクエストは Gateway から発信されるため、シリアライズされたプロバイダーリクエストが同等であれば、キャッシュアフィニティは維持される。つまり、ツールの順序、システム指示、プロバイダーラッパー、キャッシュメタデータ(Gateway 側に保持される)が同一であることが条件となる。これは仮定ではなく、テスト可能な性質である。サポート対象の各プロバイダー転送方式について、ローカル/ワーカー配置間のバイト同等性テストを、ワーカーループを導入するマイルストーンに含める。
セキュリティモデル
正確には、ワーカーには直接のネットワーク外向き通信がなく、常設のプロバイダー/forge 認証情報もない。ただし、「外向き通信が一切ない」わけではない。推論と Gateway 実行ツールは、制御された外向き通信チャネルである(プロンプトインジェクションを受けたワーカーは、ワークスペースのバイト列をモデルコンテキストや websearch クエリに含めることが依然として可能である)。したがって、次を適用する。
- 制御された外向き通信の会計: 推論プロキシと Gateway ツールについて、環境単位の監査とオペレーターから確認可能な会計を提供する。レート/バイト制限は、支出クォータ機構ではなく、プロトコルのフロー制御(容量)として設ける。
- ワーカーから Gateway への入力は、閉じたワーカープロトコルの許可リストに限定する。トランスクリプト書き込みは構造的に制約する(Gateway が生成する ID、単一のバインド済みセッション)。
- ワーカーの exec は、ボックス内で完全な権限を持つ。ボックスは破棄可能かつ認証情報を持たないため、コマンド単位の承認は何も保護せず摩擦を増やすだけである。保護対象の境界は、受信調整と監査である。Exec は Gateway の Node 承認パスを決して通過しない。
- インターネットポリシーは、プロビジョニング時にプロバイダーが決定する。環境プロファイルがボックス作成時に決定し(ファイアウォール/セキュリティグループ/外向き通信なしのネットワーク)、必要に応じてネットワーク接続可能なセットアップフェーズを設け、エージェントフェーズ開始前にプロバイダーが閉じる。コアはランタイムのネットワーク切り替えを実装しない。
- プロビジョニング時のボックス衛生: クラウドメタデータエンドポイントをブロックするか、存在しないことを検証し、インスタンスプロファイル、継承された SSH エージェント、Docker ソケットを持たせず、クリーンな環境変数/ホームを使用する。プロビジョニング出力から SSH ホスト鍵を固定する。
- Gateway 側のあらゆる処理(push、PR、プロバイダー呼び出し)に対する承認とポリシーは、引き続き Gateway 上で実行する。
侵害されたワーカーセッションの影響範囲は、同期されたワークスペースのコピーと、監査対象のプロキシチャネルが許可する範囲に限定される。認証情報も直接ネットワークもなく、許可リストを超える Gateway の表面にもアクセスできない。
容量
Gateway は N 個のワーカーについて、すべてのプロンプトとトークンストリームを中継する。そのため v1 では、本番環境で問題が発覚してから対応するのではなく、容量モデルを明示する。Gateway 単位の同時ワーカー数制限、ストリーム単位のクレジットウィンドウ(現在のイベントストリームキューは上限がなく、Node のソケットバッファ上限は低速なコンシューマーを強制切断するため、いずれも無変更では不適切)、バースト対応の上限付きディスクスプーリング、UI に可視のバックプレッシャー状態を伴う負荷制限を設ける。ワークスペース転送は独立した SSH チャネル上に維持する。
ライフサイクル
- アイドル時の自動停止と TTL は、固定定数ではなくプロバイダープロファイルのポリシーとする。デフォルトは明示的な keep-alive を備えた余裕のある値とする。数日間にわたる作業を第一級の用途として扱う(リース方式のバックエンド向けにプロバイダーの
renewを用意する)。ターン実行中または直近にアクティビティがあったセッションは、決して回収しない。 - ワーカーの停止または回収時: 配置を
reclaimedに移行し、セッション行は保持する。次のメッセージで新しいワーカーをプロビジョニングし、最後のチェックポイントから再同期する。会話は決して失われない(Gateway 側のストア)。最後のチェックポイント以降のワークスペース変更は失われ、その旨を UI に表示する。 - 初日からウォームリースを再利用する(対応プロバイダーのみ)。ブートストラップ後のイメージスナップショットは、v2 の高速起動パスとする。
設定表面
最小限かつオプトインとする。プロバイダープロファイルブロック(プロバイダー ID、認証情報/CLI 参照、同期規則、有効期間ポリシー、予算、任意のセットアップフェーズ)と、セッション単位の配置選択のみを追加する。新しい環境変数は追加しない。未設定のインストール環境には何も表示しない。
マイルストーン
実装は、小さく独立してマージ可能な PR として導入する。以下の各マイルストーンは、1 つの変更ではなく一連の PR である。
- 基盤: 環境ステートマシン + プロバイダー契約 + crabbox 形式のプロバイダー(開発用ハーネスとして static-SSH)、ワーカーバンドルのブートストラップ + 受付ハンドシェイク、SSH トンネル + ホスト鍵固定、管理対象ワークツリーのスナップショット + 送信同期(git + プレーンモード)。孤立リソースの掃除 + 再起動時の再採用。
- ワーカープロトコル + ワーカーループ: 認証済みワーカーロール、永続操作/エポック/ACK カーソル、トランスクリプトコミット + ライブイベント契約、Gateway 解決済みモデルを使用する推論プロキシ、フロー制御。プロバイダーは 1 つ、新規セッションの人間によるディスパッチのみ、引き継ぎなし。障害注入テスト(トンネル分断、Gateway 再起動、ワーカー停止)を完了条件とする。
- ディスパッチ + 引き戻し + エージェントディスパッチ: 移行バリア、UI 対象バーに接続された配置ステートマシン、受信調整 + チェックポイント、環境単位の監査、容量制限、エージェントディスパッチツール(ワーカーセッションは再帰不可)。プロンプトキャッシュのバイト同等性テスト。
- 対称ライブ引き継ぎ。マイルストーン 3 の障害注入による実証後に実施する。
今後: 環境単位で認証情報の注入をオプトインできる、ワーカー上の ACP ハーネス。スナップショット/ウォームイメージによる高速起動。ファンアウト(N 個のリース、同一プロンプト)。ボックス内の OS サンドボックス化。成果物スキーマを使用した、より高度な成果物取得。
未解決事項
- ワーカーでの Plugin/Skills の可用性: リポジトリに含まれる Skills はワークスペースと無料で同期されます。Gateway で設定されたエージェントの Skills/Plugin については、同期するか除外するかを明示的に決定する必要があります(いずれの場合もツール/Plugin マニフェストは受け入れハンドシェイクの一部です)。
- チェックポイント間隔のデフォルト: 非常に発言量の多いセッションでは、ターンベースにするか時間ベースにするか。
- 環境プロファイルとマルチエージェントルーティングの連携方法(エージェントごとのデフォルトプロファイルか、セッションごとの選択のみか)。