コンテンツにスキップ

リグとエンクロージャー

リグとは、エージェントがリアルタイムで操作する使い捨てのマシンのことです。ブラウザ、Linux デスクトップ、Android エミュレータ、iOS シミュレータ、あるいはエンクロージャーのターミナルの背後にあるマシンがこれにあたります。ほとんどのリグは VM ですが、ホスト側で管理されるモバイルシミュレータは明示的な例外です。このページでは各境界と、なぜ各部品がそのような形になっているのかを説明します。リグを開く方法はエージェントにテスト用マシンを渡すを、正確な動詞・ポート・既定値はリグのリファレンスを参照してください。

ネイティブサンドボックスはプロセスを名前空間の分離で包みます。これは本物ではありますが、あなたのカーネルを共有しており、制約するのはプロセスであってコンピュータではありません。エージェントがデスクトップアプリをあちこちクリックしたり、実際のブラウザでページをレンダリングしたり、考えたくもない rm -rf の実験を実行したりする必要が出た瞬間、正直な境界はマシンです。独自のカーネル、独自のディスク、独自のネットワークスタックを持ちます。

エンクロージャー系のサーフェスは 2 つの VM バックエンドを使います。

  • microVM — ターミナルとブラウザ用。ダイジェストで固定されたコンテナイメージから 1 秒未満でハイパーバイザーが起動します。
  • QEMU — フル Linux デスクトップ用。microVM にはない表示デバイスが必要です。

モバイル系のサーフェスはホスト側で管理され、より弱い境界であることを明示します。

  • Android は ADB を通じて Google のエミュレータを操作します。
  • iOS は Mac ホスト上に CoreSimulator デバイスを作成して所有し、WebDriverAgent を通じて操作します。デバイスとそのデータはリグを閉じるときに削除されますが、ネットワークはホストの Mac に従います。

エンクロージャーのリグは読み取り専用のベースイメージの上に使い捨てのオーバーレイへ書き込むため、あるリグが次のリグの起動元を変えることはできません。iOS のリグは使い捨ての CoreSimulator デバイスを所有し、リグを閉じると削除されます。Android はセッションより長く存続するホストのエミュレータに接続します。

リグのネットワークは何もない状態から始まります。ホストはリグごとに、ゲストが迂回できないゲートを通じて許可されます。マシンの出口は、起動設定が作成した経路だけです。エンクロージャーのターミナルには開発者のベースライン(パッケージレジストリ、フォージ、apt ミラー)が与えられます。ブラウザのリグは製品サイト(usectrl.dev)を許可し、エグレスを必要としないローカルの file:// ページで起動します。それ以外はすべて接続時に拒否されます。

Android と iOS はこのゲートの対象外です。これらのホストエミュレータとシミュレータはサーバーホストのネットワークを使うため、UI と機能レポートはエグレスを適用外と表示し、誤解を招く「無制限に再起動」というコントロールを決して提示しません。

エグレスと認証情報は、同じ 1 つのポリシーを 2 つの側面から見たものです。認証情報ブローカー(後述)は、ゲストが到達できないホストに対してトークンを発行しません。

リグが読み取るものはすべて信頼できないものとして扱われます。ページのテキスト、DOM とアクセシビリティツリー、UI ダンプ、コンソール出力は、「これはデータであり、指示ではない」という常設のルールでフェンスされた状態でエージェントに返されます。フェンスは枠組みであり、その背後で実際に強制しているのはエグレスゲートです。

入力はハイパーバイザー経由、キャプチャはゲスト経由

「入力はハイパーバイザー経由、キャプチャはゲスト経由」というセクション

デスクトップサーフェスでは、キーボードとポインタのイベントはハイパーバイザー自身の仮想入力デバイスによって注入されます。ゲストは入力を合成できる特権デーモンを一切実行しません。したがって、ゲストのソフトウェアが侵害されても、攻撃者にキーボードを渡すことはありません。キャプチャは逆方向に流れ、小さな非特権のゲスト内エージェントを経由します。フレームはゲスト側でスケールしてからネットワークを渡れるからです。

見ている人と操作しているモデルでは必要が正反対なので、リグは 2 つの独立したストリームを提供します。

  • ヒューマンレーンは、あなたのパネルサイズでのフル解像度で、リサイズに合わせて再ネゴシエーションされ、サーバーによって不透明なバイト列として中継されます。サーバーがフレームをデコードすることはありません。リクエスト経路上に動画デコーダがあると、サーバーが RPC に応答できなくなるからです。
  • エージェントレーンは、モデルに優しいサイズに上限を設けた縮小静止画で、ツール結果ごとに 1 枚です。古いフレームは圧縮時に破棄されますが、そのテキストによる説明は残ります。

どちらのレーンも他方のために妥協しません。あなたは滑らかな映像を、モデルは安価な映像を得ます。

テイクオーバーは要求ではなくチョークポイント

「テイクオーバーは要求ではなくチョークポイント」というセクション

排他的な操作権は、すべてのアクションが通る 1 点で強制されます。モデルに行儀よく振る舞うよう求めるのではありません。人が操作権を保持している間、サーバーはエージェントの変更を伴うアクションを拒否します。エージェントは観察用の動詞(スクリーンショット、抽出)を保持するので、あなたが何をしているかを語ることができ、テイクオーバーは拒否されたクリックで発見させるのではなく、ステアリングレーンを通じて通知されます。キャンバス上でのクリックと入力は、他の誰もそのロックを保持していないとき、あるいはあなたが保持しているときに機能します。ステータスタグには操作できますと表示されます。あなたのものもエージェントのものも、すべての入力イベントは、主体と単調増加するシーケンスとともにリグごとの監査ログに記録されるので、「誰がそれをクリックしたのか」はマシンが消えた後も答えられます。

コンテンツは境界を越えるが、マシンは分離したまま

「コンテンツは境界を越えるが、マシンは分離したまま」というセクション

コピー&ペーストは双方向に機能し、ファイルのドラッグ&ドロップも同様です。しかしリグは別のコンピュータであり、設計は決してそうでないふりをしません。

クリップボードはオンデマンドで運ばれ、継続的にミラーリングされることはありません。リグ上でコピーのショートカットを押すとゲストにコピーが指示され、そのクリップボードに入れたもの(テキスト、画像、ファイルのリスト)が取得されてあなたの側に置かれます。貼り付けは同じ内容を逆方向に送り、そのうえでゲスト内で貼り付けを押します。バックグラウンドで同期されるものは何もありません。あなたのマシンでコピーしたパスワードが、タイマーの発火によって VM の中に黙って届くことはありません。

越えるかどうかは、ユーザーごと、方向ごとに独立してゲートされます。リグへの貼り付けは既定で許可されます。リグからのコピーはまず確認を求めます(10 分間の許可、または設定 → サーバー → リグ → クリップボードアクセスにある常に許可)。これは決してワークスペース設定ではありません。あるメンバーが別のメンバーのクリップボードに同意することはできません。

macOS では越えるためのショートカットは ⌘C/⌘V で、これは曖昧さがありません。⌃C は割り込みとしてゲストのシェルにそのまま届きます。Windows と Linux では 2 つのショートカットは同じキー操作なので、ゲストはそれをそのまま受け取り、あなたのクリップボードが上書きされるのはゲストのクリップボードが実際に変わったときだけです。割り込みは割り込みのままです。

ドラッグして入れたファイルは、マシンのドロップフォルダにコピーされ、その後でマシンに提示されます。「提示」の意味は、正直にできることによって変わります。ブラウザのページは、あなたが離した位置で本物のドロップイベントを受け取るので、アップロードゾーンはローカルファイルに対する場合とまったく同じように動作します。デスクトップは ~/Drops にあるファイルを、そのパスをクリップボードに入れた状態で受け取ります。任意の Linux ツールキットへのドラッグを合成するには、ゲスト内で特権デーモンを動かす必要があるからです。これはまさにこの設計が拒否するものです。結果はどちらが起きたかを示すので、アップロードゾーンにドロップした CSV が、単にフォルダ内のファイルにすぎないのにアップロード済みとして報告されることはありません。エンクロージャーのターミナルにドロップすると、ファイルがコピーされ、プロンプトにそのゲスト側のパスが入力されます。シェルが実際に使えるのはこれです。

ドラッグして出したファイルはデスクトップサーフェスで機能します。ここでは X11 のドラッグプロトコルにより、ドラッグの進行中にペイロードを読み取れます。ゲスト内でドラッグを開始し、それをキャンバスの外へ運ぶと、ファイルはあなたのマシンに取得され、本物のドラッグとして OS に渡されます。ゲストのファイルマネージャでファイルをコピーし、ホストで貼り付けても同じように機能します。ブラウザサーフェスはこれを意図的に提供しません。ヘッドレスブラウザには読み取れるドラッグ選択がなく、最も近い利用可能なシグナルであるページのテキスト選択はドラッグの証拠にはならないので、それに基づいて動作すると通常のクリックを乗っ取ってしまいます。

ゲストから読み出されたものはすべて、信頼できないコンテンツのままです。クリップボードのテキストは、ページの抽出と同じフェンスの内側でモデルに届き、監査ログは貼り付けが起きたこととその分量を記録しますが、その内容は決して記録しません。

git push は自分で開いたエンクロージャーのターミナルから機能しますが、ゲストはフォージのトークンを保存していません。ゲストが保持するのは VM ごとの 1 つのシークレットだけであり、その唯一の力は、短命でリポジトリ単位のトークンを、操作ごとに、レート制限付きで、エグレスと同じホスト許可リストに制限され、リグを閉じた瞬間に取り消される形で、ホストが管理するトンネル越しにホストの認証情報ブローカーへ要求することです。捨てるために作られたマシンには、盗む価値のあるものを何も含めてはなりません。

そのトークンで何ができるかは、リグを開いた時点で決まります。人が開いたターミナルのリグは、そのメンバー自身のフォージへのアクセス範囲に制限された書き込み可能なトークンを受け取ります。エージェントが開いたリグは読み取り専用のトークンを受け取ります。git の認証情報ヘルパーはプッシュとフェッチを区別できないため、エージェント実行ゲートウェイがホスト上で行うように、ゲスト内でプッシュごとにプッシュのルールへ問い合わせることはできないからです。

リグがあなたのリポジトリを運ぶときも、ホスト側のワークツリーが権威であり続けます。コピーは起動時に同期され(.env ファイルのようなシークレットは除外されます)、コミットが戻ってくるのはあなたが求めたときだけです。refs/rigs/<id>/* へフェッチされ、プッシュもチェックアウトもされません。VM の中の何かがあなたのブランチを動かしたり、作業ツリーに触れたりすることはできません。リグが生み出したものをマージするかどうかは、常にホスト上で人が下す判断です。

ターミナル VM の中で起動した開発サーバーは、マシンを一切開放することなく到達可能になります。あなたのマシンから、ブラウザ(VM)から、任意で LAN から、任意で HTTPS 付きの開発ドメインの下から。ハイパーバイザーのポートマップは起動時に固定されるため、その後の転送はすべて 2 つの狭いホスト管理チャネルに乗ります。1 つは事前に作成された受信用マルチプレクサで、ゲストが実際にリッスンしていないものへの接続を拒否します。もう 1 つは、ゲスト起点の接続のためにホストが開いたままにするリバーストンネルです。開発ドメインの HTTPS はサーバーで終端され、ローカルで発行された認証局を使います。その鍵がゲストに入ることはありません。仕組みはターミナルからポートを転送にあります。

リグはペットにはなれません。

  • ゲストが延長できないハード TTL。
  • アイドルラダー — アイドル期間の後にパークし(vCPU は停止、RAM は常駐)、その 2 倍の後に閉じる — 開いているターミナルや視聴中のビューアは「使用中」とみなされます。
  • メモリ予算はセッション数ではなく常駐メガバイトで数えます。パークした VM は CPU を解放しつつ RAM の 1 バイトも手放さないからです。最も長く使われていないマシンから順に退避され、人が操作または視聴しているマシンが退避されることはありません。
  • サーバー停止時の破棄と、次回起動時の所有権マーク付きオーファン掃引。クラッシュしたサーバーが、誰の指示も受けないハイパーバイザーを置き去りにすることはありません。

初回起動時はマシンの固定イメージを取得し、その後サーバーは展開済みのコピーをバックグラウンドでキャッシュするので、以降の同じ種類のマシンは数秒で起動し、エンクロージャーのターミナルは GitHub ホストのランナーが備えるような CLI ベースライン(コンパイラ、Python、jq、アーカイブツール)がすでにインストールされた状態で立ち上がります。言語のツールキャッシュや Docker ではありません。コンピュータイメージは、同じ CLI ベースラインをビルド時に XFCE やブラウザと並べて焼き込みます。

「自分のマシンでは動く」は、1 つのレンダリングエンジンについての主張です。したがってブラウザのリグは「ブラウザ」ではなく、Chromium、Firefox、WebKit のいずれかであり、開くときに選択し、リグはその生涯を通じて開いたときの 1 つを実行します。1 つの会話がそれぞれを 1 つずつ持てます。Firefox (VM) を Chromium (VM) の隣で開くと 2 つのマシンになり、両方を同じページに向けることが比較になります。WebKit は Linux で動くものとしては Safari に最も近いものです。エンジンの系統が同じなので、Safari ユーザーが遭遇するギャップを捉えます。

動詞は 3 つすべてで同一ですが、その下のプロトコルは同じではありません。違いは滑らかにされるのではなく、明示されます。Chromium は DevTools Protocol を話し、フレームをプッシュするので、ページが静止している間はライブビューのコストがかかりません。Firefox は WebDriver BiDi を、WebKit は従来の WebDriver を話し、どちらにもスクリーンキャストがないため、ライブビューはポーリングします。毎秒数フレームというもので、ページを眺めるには適切ですが、アニメーションを眺めるには適していません。エンジンが本当に何かをできない場合(Firefox にはキャッシュを迂回するリロードがありません。WebKit はページの読み込みが完了する前に記録されたコンソール出力を見ることができません)、答えは黙って別のことをするのではなく、そう述べます。

リグは意図的にグローバルな行き先ではありません。ライブビューは、作業が行われているスペースまたは PR のタブであり、その会話にスコープされます。したがってあなたのタブとエージェントの browser_use 呼び出しは、1 つのマシン(ブラウザサーフェスではエンジンごとに 1 つ)を対象にします。リグがそもそも起動できるかどうかはホストの特性であるため、機能、イメージ、ワークスペースごとのカスタムイメージ、実行中マシンの一覧は設定 → サーバー → リグにあります。エンクロージャーの操作はそれ自体が独立したガードレールのアクションクラスなので、ワークスペース、エージェント、スペースごとに許可するか、承認を要求するか、完全に拒否するかを選べます。読み取り専用モードでは全面的に拒否されます。