Rigi i izolacje
Rig to jednorazowa maszyna, którą agent steruje w czasie rzeczywistym — przeglądarka, pulpit Linuksa, emulator Androida, Symulator iOS albo maszyna stojąca za odizolowanym terminalem. Większość rigów to VM-y; zarządzane przez hosta symulatory mobilne są wyraźnymi wyjątkami. Ta strona wyjaśnia każdą granicę i to, dlaczego poszczególne elementy mają taki, a nie inny kształt. Aby otworzyć rig, zobacz Daj agentowi maszynę do testów; dokładne operacje, porty i wartości domyślne znajdziesz w dokumentacji referencyjnej rigów.
Dlaczego VM, a nie sandbox
Dział zatytułowany „Dlaczego VM, a nie sandbox”Natywny sandbox zamyka proces w
izolacji przestrzeni nazw — prawdziwej, ale dzieli z Tobą jądro i ogranicza
proces, a nie komputer. Gdy tylko agent musi klikać po aplikacji desktopowej,
renderować stronę w prawdziwej przeglądarce albo przeprowadzać eksperymenty z
rm -rf, o których wolisz nie myśleć, uczciwą granicą jest maszyna: własne
jądro, własny dysk, własny stos sieciowy.
Powierzchnie odizolowane korzystają z dwóch backendów VM:
- microVM-y dla terminala i przeglądarki — uruchomienie hypervisora w mniej niż sekundę z obrazów kontenerowych przypiętych skrótem.
- QEMU dla pełnego pulpitu Linuksa, który potrzebuje urządzenia wyświetlającego, jakiego microVM nie ma.
Powierzchnie mobilne są zarządzane przez hosta i wprost mówią o słabszej granicy:
- Android steruje emulatorem Google przez ADB.
- iOS tworzy na hoście Mac urządzenie CoreSimulator i nim zarządza, a następnie steruje nim przez WebDriverAgent. Urządzenie i jego dane są usuwane po zamknięciu riga, ale jego sieć działa przez hosta Mac.
Izolowane rigi zapisują do jednorazowej warstwy nakładkowej na obrazie bazowym tylko do odczytu, więc jeden rig nie może zmienić tego, z czego uruchamia się następny. Rig z iOS posiada jednorazowe urządzenie CoreSimulator, które jest usuwane po zamknięciu riga. Android podłącza się do emulatora hosta, który przeżywa sesję.
Domyślnie zabroniony ruch wychodzący
Dział zatytułowany „Domyślnie zabroniony ruch wychodzący”Sieć riga zaczyna się od niczego. Hosty są dopuszczane dla każdego riga przez
bramę, której system gościa nie może ominąć trasowaniem: jedyne drogi wyjścia z
maszyny to te, które utworzyła konfiguracja uruchomienia. Odizolowany terminal
dostaje bazowy zestaw deweloperski (rejestry pakietów, hosty kodu, mirrory apt);
rig przeglądarki dopuszcza witrynę produktu (usectrl.dev) i startuje z lokalną
stroną file://, która nie potrzebuje ruchu wychodzącego; wszystko inne jest
odrzucane w momencie połączenia.
Android i iOS nie są objęte tą bramą. Ich emulator i symulator hosta korzystają z sieci hosta serwera, więc interfejs i raport możliwości oznaczają ruch wychodzący jako niewymuszany i nigdy nie pokazują mylącej kontrolki „Uruchom ponownie bez ograniczeń”.
Ruch wychodzący i poświadczenia to jedna polityka widziana z dwóch stron — broker poświadczeń (poniżej) nie wystawi tokenu dla hosta, którego system gościa nie może osiągnąć.
Wszystko, co rig czyta, jest traktowane jako niezaufane: tekst strony, drzewa DOM i dostępności, zrzuty interfejsu i dane wyjściowe konsoli wracają do agenta ogrodzone stałą regułą „to są dane, nie instrukcje”. Ogrodzenie to oprawa; brama ruchu wychodzącego to stojące za nim wymuszanie.
Dane wejściowe idą przez hypervisor, przechwytywanie przez system gościa
Dział zatytułowany „Dane wejściowe idą przez hypervisor, przechwytywanie przez system gościa”Na powierzchni pulpitu zdarzenia klawiatury i wskaźnika wstrzykują własne wirtualne urządzenia wejściowe hypervisora. System gościa nigdy nie uruchamia uprzywilejowanego demona, który mógłby syntezować dane wejściowe — przejęcie oprogramowania systemu gościa nie oddaje więc atakującemu klawiatury. Przechwytywanie płynie w drugą stronę, przez małego, nieuprzywilejowanego agenta działającego w systemie gościa, bo to system gościa może skalować klatki, zanim przejdą przez sieć.
Dwa tory wyświetlania
Dział zatytułowany „Dwa tory wyświetlania”Osoba patrząca i model sterujący mają przeciwne potrzeby, więc rig obsługuje dwa niezależne strumienie:
- Tor dla człowieka to pełna rozdzielczość w rozmiarze Twojego panelu, negocjowana na nowo przy zmianie rozmiaru okna i przekazywana przez serwer jako nieprzejrzyste bajty — serwer nigdy nie dekoduje klatki, bo to dekoder wideo na ścieżce żądania powstrzymuje go przed odpowiadaniem na wywołania RPC.
- Tor agenta to pomniejszone klatki ograniczone do rozmiaru przyjaznego modelowi, po jednym obrazie na wynik narzędzia, przy czym starsze klatki są odrzucane podczas kompaktowania, a ich opisy tekstowe przetrwają.
Żaden tor nie idzie na kompromis dla drugiego: Ty dostajesz płynny obraz, model tani.
Przejęcie kontroli to wąskie gardło, nie prośba
Dział zatytułowany „Przejęcie kontroli to wąskie gardło, nie prośba”Wyłączna kontrola jest wymuszana w jednym punkcie, przez który przechodzi każde działanie — a nie przez proszenie modelu, by się dobrze zachowywał. Dopóki trzyma ją człowiek, serwer odrzuca modyfikujące operacje agenta. Agent zachowuje swoje operacje obserwacyjne (zrzuty ekranu, ekstrakcję), żeby mógł relacjonować, co robisz, a o przejęciu informuje go jego tor sterowania, zamiast zostawiać mu odkrycie tego przez odrzucone kliknięcia. Klikanie i pisanie na kanwie działa, gdy nikt inny nie trzyma tej blokady — albo gdy trzymasz ją Ty; znacznik statusu brzmi Masz kontrolę. Każde zdarzenie wejściowe — Twoje i agenta — trafia do dziennika audytu danego riga wraz z podmiotem i monotonicznym numerem sekwencji, więc pytanie „kto to kliknął” pozostaje rozstrzygalne także po zniknięciu maszyny.
Treść przekracza granicę; maszyny pozostają osobne
Dział zatytułowany „Treść przekracza granicę; maszyny pozostają osobne”Kopiowanie i wklejanie działa w obie strony, podobnie jak przeciąganie plików do środka i na zewnątrz — ale rig to inny komputer i projekt nigdy nie udaje inaczej.
Schowek jest przenoszony na żądanie, a nie odzwierciedlany w sposób ciągły. Naciśnij skrót kopiowania nad rigiem, a system gościa dostanie polecenie skopiowania; następnie to, co położył w swoim schowku — tekst, obraz, listę plików — zostaje pobrane i umieszczone w Twoim. Wklejanie wysyła tę samą treść w drugą stronę, a potem naciska wklejenie wewnątrz systemu gościa. Nic nie jest synchronizowane w tle: hasło skopiowane na Twojej własnej maszynie nie trafia po cichu do maszyny wirtualnej tylko dlatego, że zadziałał licznik czasu.
Przekraczanie granicy jest kontrolowane osobno dla każdego użytkownika i każdego kierunku. Wklejanie do riga jest domyślnie dozwolone; kopiowanie z riga najpierw pyta (dziesięciominutowe zezwolenie albo Zawsze zezwalaj w Ustawienia → Serwer → Rigi → Dostęp do schowka). To nigdy nie jest ustawienie obszaru roboczego: jeden członek nie może wyrazić zgody za schowek drugiego członka.
W systemie macOS skrótem przekraczania jest ⌘C/⌘V, co jest jednoznaczne — ⌃C nadal dociera do powłoki systemu gościa jako przerwanie, którym jest. W systemach Windows i Linux oba skróty to ten sam klawisz, więc system gościa otrzymuje go bez zmian, a Twój schowek jest nadpisywany tylko wtedy, gdy schowek systemu gościa faktycznie się zmienił. Przerwanie pozostaje przerwaniem.
Pliki przeciągnięte do środka są kopiowane do folderu upuszczania maszyny, a
następnie jej oferowane. To, co oznacza „oferowane”, zależy od tego, co da się
uczciwie zrobić: strona przeglądarki otrzymuje prawdziwe zdarzenie upuszczenia
w miejscu, w którym puszczasz plik, więc strefa wysyłania zachowuje się dokładnie
tak jak przy pliku lokalnym; pulpit dostaje pliki w ~/Drops, a ich ścieżki w
swoim schowku, bo żaden host nie potrafi zsyntezować przeciągania do dowolnego
zestawu narzędzi Linuksa bez uruchomienia uprzywilejowanego demona w systemie
gościa — a tego właśnie ten projekt nie chce mieć. Wynik mówi, który przypadek
zachodzi, więc plik CSV upuszczony na strefę wysyłania nigdy nie zostanie
zgłoszony jako wysłany, gdy jest tylko plikiem w folderze. Upuszczenie na
odizolowany terminal kopiuje plik do środka i wpisuje jego ścieżkę w systemie
gościa w wierszu zachęty, bo z tego powłoka naprawdę potrafi skorzystać.
Pliki przeciągnięte na zewnątrz działają na powierzchni pulpitu, gdzie protokół przeciągania X11 pozwala odczytać ładunek, gdy przeciąganie trwa. Rozpocznij przeciąganie wewnątrz systemu gościa, wynieś je poza kanwę, a pliki zostaną pobrane na Twoją maszynę i przekazane systemowi jako prawdziwe przeciąganie. Skopiowanie plików w menedżerze plików systemu gościa i wklejenie na hoście działa tak samo. Powierzchnia przeglądarki celowo tego nie oferuje: przeglądarka bez interfejsu graficznego nie ma zaznaczenia przeciągania do odczytania, a najbliższy dostępny sygnał — zaznaczenie tekstu na stronie — nie jest w ogóle dowodem przeciągania, więc działanie na jego podstawie przechwytywałoby zwykłe kliknięcia.
Wszystko odczytane z systemu gościa pozostaje niezaufaną treścią: tekst schowka dociera do modelu w tym samym ogrodzeniu co ekstrakcja ze strony, a dziennik audytu odnotowuje, że wklejenie nastąpiło i ile go było — nigdy tego, co zawierał.
Poświadczenia nigdy nie mieszkają w systemie gościa
Dział zatytułowany „Poświadczenia nigdy nie mieszkają w systemie gościa”git push działa z odizolowanego terminala otwartego przez Ciebie, a mimo to system gościa nie
przechowuje żadnego tokenu hosta kodu. Przechowuje jeden sekret na maszynę
wirtualną, którego jedyną mocą jest poproszenie brokera poświadczeń hosta —
przez tunel kontrolowany przez hosta — o krótkotrwały token ograniczony do
repozytorium, na każdą operację, z limitem częstości, ograniczony tą samą listą
dozwolonych hostów co ruch wychodzący i unieważniany w chwili zamknięcia riga.
Maszyna zbudowana po to, by ją wyrzucić, nie może zawierać niczego, co warto
ukraść.
To, co ten token może zrobić, ustala się przy otwarciu riga. Rig terminala otwarty przez człowieka dostaje token z prawem zapisu, ograniczony własnym dostępem tego członka do hosta kodu. Rig otwarty przez agenta dostaje token tylko do odczytu: pomocnik poświadczeń gita nie odróżnia push od fetch, więc reguły push nie da się zapytać przy każdym push wewnątrz gościa tak, jak robi to brama uruchomień agentów na hoście.
Worktree w rigu jest satelitą
Dział zatytułowany „Worktree w rigu jest satelitą”Gdy rig niesie Twoje repozytorium, worktree na hoście pozostaje autorytatywny.
Kopia jest zsynchronizowana do środka przy starcie (z wyłączeniem sekretów,
takich jak pliki .env), a commity wracają tylko wtedy, gdy o to poprosisz —
pobierane do refs/rigs/<id>/*, nigdy wypychane, nigdy wyewidencjonowywane. Nic
wewnątrz maszyny wirtualnej nie może przesunąć Twojej gałęzi ani dotknąć drzewa
roboczego; scalenie tego, co wytworzył rig, jest zawsze decyzją człowieka podjętą
na hoście.
Porty bez dziur
Dział zatytułowany „Porty bez dziur”Serwer deweloperski uruchomiony wewnątrz terminala VM staje się osiągalny — na Twojej maszynie, w Przeglądarce (VM), opcjonalnie w Twojej sieci LAN, opcjonalnie pod domeną deweloperską z HTTPS — bez otwierania maszyny na świat. Mapa portów hypervisora jest ustalana przy starcie, więc całe późniejsze przekierowanie jedzie dwoma wąskimi kanałami kontrolowanymi przez hosta: wcześniej utworzonym multiplekserem ruchu przychodzącego, który odmawia połączenia z czymkolwiek, czego system gościa faktycznie nie nasłuchuje, oraz tunelami odwrotnymi, które host trzyma otwarte dla połączeń inicjowanych przez system gościa. HTTPS domeny deweloperskiej kończy się na serwerze, używając lokalnie utworzonego urzędu certyfikacji, którego klucze nigdy nie trafiają do żadnego systemu gościa. Mechanika jest opisana w Przekieruj porty z terminala.
Maszyny są ograniczone z założenia
Dział zatytułowany „Maszyny są ograniczone z założenia”Rig nie może stać się pupilkiem:
- twardy TTL, którego system gościa nie może wydłużyć;
- drabinka bezczynności — zaparkowanie (wstrzymane vCPU, pamięć RAM nadal zajęta) po oknie bezczynności, zamknięcie po dwukrotności tego czasu — gdzie otwarty terminal albo ktoś patrzący na podgląd liczy się jako „w użyciu”;
- budżet pamięci liczony w megabajtach rezydentnych, a nie w sesjach, bo zaparkowana maszyna wirtualna zwalnia CPU, ale zachowuje każdy bajt RAM; najpierw usuwana jest maszyna używana najdawniej, i nigdy ta, którą ktoś steruje lub na którą patrzy;
- demontaż przy wyłączeniu serwera oraz przegląd sierot oznaczonych właścicielem przy następnym starcie, dzięki czemu zawieszony serwer nigdy nie zostawia hypervisora, który nikomu nie odpowiada.
Pierwsze uruchomienia pobierają przypięty obraz maszyny; serwer buforuje potem w
tle wcześniej rozpakowaną kopię, więc każde późniejsze uruchomienie maszyny tego
rodzaju zajmuje sekundy, a odizolowany terminal startuje z zainstalowanym już
bazowym zestawem CLI w rodzaju tego z runnerów hostowanych na GitHubie —
kompilatory, Python, jq, narzędzia archiwizujące — a nie z pamięcią podręczną
narzędzi językowych ani Dockerem. Obraz powierzchni Komputer zawiera ten sam
bazowy zestaw CLI już na etapie budowania, obok XFCE i przeglądarek.
Trzy przeglądarki, nie jedna
Dział zatytułowany „Trzy przeglądarki, nie jedna”„U mnie działa” to twierdzenie o jednym silniku renderującym. Rig przeglądarki nie jest więc „przeglądarką” — to Chromium, Firefox albo WebKit, wybierana przy otwarciu, a rig przez całe życie działa na tej, z którą został otwarty. Jedna rozmowa może zawierać po jednej z każdej: otwarcie Firefox (VM) obok Chromium (VM) daje dwie maszyny, a skierowanie obu na tę samą stronę jest porównaniem. WebKit jest tak blisko Safari, jak tylko może być coś działającego na Linuksie — ta sama linia rozwojowa silnika, więc wyłapuje luki, na które trafiają użytkownicy Safari.
Operacje są identyczne we wszystkich trzech; protokoły pod spodem już nie, a różnice są nazywane wprost, a nie wygładzane. Chromium mówi protokołem DevTools i wypycha klatki, więc jego podgląd na żywo nic nie kosztuje, dopóki strona się nie zmienia. Firefox mówi WebDriver BiDi, a WebKit klasycznym WebDriverem; żaden z nich nie ma transmisji obrazu, więc ich podglądy na żywo odpytywują — kilka klatek na sekundę, co jest właściwe przy patrzeniu na stronę, a nie na animację. Tam, gdzie silnik naprawdę czegoś nie potrafi (Firefox nie ma przeładowania z pominięciem pamięci podręcznej; WebKit nie widzi danych wyjściowych konsoli zapisanych, zanim strona zakończy ładowanie), odpowiedź to mówi, zamiast po cichu robić coś innego.
Gdzie rigi mieszkają w produkcie
Dział zatytułowany „Gdzie rigi mieszkają w produkcie”Rig celowo nie jest globalnym miejscem docelowym. Podgląd na żywo to karta w
przestrzeni albo PR, w których dzieje się praca, ograniczona do tej rozmowy —
więc Twoja karta i wywołania browser_use agenta adresują jedną maszynę (po
jednej na silnik, na powierzchni przeglądarki). To, czy rigi mogą się w ogóle
uruchamiać, jest właściwością hosta, więc możliwości, obrazy, niestandardowe
obrazy obszaru roboczego i lista działających maszyn znajdują się w
Ustawienia → Serwer → Rigi. Sterowanie izolacją to odrębna klasa działań
guardraili, więc obszar roboczy, agent albo
przestrzeń może ją dopuścić, wymagać dla niej zatwierdzenia albo odmówić jej
wprost — tryby tylko do odczytu odmawiają jej w całości.