Rigs
Alleen feiten. Lees Rigs en omhullingen voor het model erachter; volg de gids om een machine te openen.
Oppervlakken en backends
Sectie getiteld “Oppervlakken en backends”| Oppervlak | Stuurt aan | Backend | Waarde | Ingesloten egress |
|---|---|---|---|---|
| Terminal (exec) | Een shell via het exec-kanaal van de VM | microVM | smolvm |
Ja |
| Browser | Headless Chromium (CDP), Firefox (WebDriver BiDi) of WebKit (W3C WebDriver) | microVM | smolvm |
Ja |
| Computer | X11-desktop: invoer via de hypervisor, beeldopname via de gastagent | QEMU | qemu-hvf (macOS), qemu-kvm (Linux), qemu-tcg (niet-versnelde terugvaloptie, nooit automatisch gekozen) |
Ja |
| Android | Android via ADB | Google’s emulator | android-emulator |
Nee — de emulator beheert zijn eigen netwerk |
| iOS | iOS Simulator via WebDriverAgent | CoreSimulator | ios-simulator |
Nee — het netwerk volgt de host-Mac |
De terminal en het computer_use-oppervlak delen de oppervlakwaarde
computer; de terminal is te herkennen aan zijn exec-imagemarker en wordt
nooit hergebruikt als aanstuurbare desktop (of andersom). Eén gesprek
hergebruikt één terminalmachine.
Browser-engines
Sectie getiteld “Browser-engines”| Engine | Waarde | Protocol | Live weergave | Stills |
|---|---|---|---|---|
| Chromium | chromium (standaard) |
Chrome DevTools Protocol | Screencast — de browser stuurt frames zodra de pagina opnieuw tekent | JPEG |
| Firefox | firefox |
WebDriver BiDi | Opgevraagde stills (BiDi heeft geen screencast), begrensd op 6 fps | JPEG |
| WebKit | webkit |
W3C WebDriver (klassiek) | Opgevraagde stills, getranscodeerd door de ffmpeg van de host | PNG |
Een rig draait zijn hele leven één engine. Eén gesprek kan per engine één rig aanhouden, en dat maakt een vergelijking naast elkaar mogelijk: “Firefox (VM)” naast “Chromium (VM)” openen betekent twee machines, en als je de ene sluit blijft de andere draaien.
Geef engine mee aan rig.open of aan de tool browser_use. Een onbekende
naam wordt geweigerd in plaats van als standaardwaarde te gelden — om een
browser vragen en er stil een andere krijgen beantwoordt een
compatibiliteitsvraag met het verkeerde antwoord.
Enginespecifieke beperkingen, benoemd in plaats van omzeild:
- Firefox heeft geen herlaadactie die de cache omzeilt (het wijst de
ignoreCachevan BiDi resoluut af), dus een harde herlaadactie is een gewone herlaadactie. - WebKit heeft evenmin een herlaadactie die de cache omzeilt, geen
consolefeed (uitvoer wordt opgevangen door
console.*te onderscheppen na elke navigatie, dus alles wat tijdens het laden wordt gelogd gaat verloren — elke console-extractie vermeldt dat), en heeftffmpegop de host nodig voor zijn live weergave. - Geen van beide stelt via zijn protocol een platformbrede
toegankelijkheidsboom beschikbaar, dus
extract (a11y)geeft een van de DOM afgeleide benadering terug, die als zodanig wordt gelabeld. - Geen van beide kan een echte bestandsdrop ontvangen; een bestandsinvoerveld kan nog steeds naar paden binnen de machine wijzen.
Machine-images
Sectie getiteld “Machine-images”| Oppervlak | Image | Opgehaald |
|---|---|---|
| Terminal | ubuntu:24.04, op digest vastgezet |
Automatisch bij de eerste keer opstarten, via het eigen afgeschermde netwerk van de machine |
| Browser (Chromium, Firefox, WebKit) | debian:trixie-slim, op digest vastgezet, plus de eigen packages van de engine |
Automatisch bij de eerste keer opstarten, daarna gecachet als een voorverwarmde pack |
| Computer | Een qcow2-desktopimage met Chromium, Firefox, WebKit en dezelfde GitHub-hosted-runner-CLI-basis die de terminal voorverwarmt | Importeren onder Instellingen → Server → Rigs (downloads die op checksum zijn vastgezet waar die gepubliceerd zijn) |
| Android | Google’s systeemimages | Via de Android SDK |
| iOS | Een Xcode Simulator-runtime plus een op checksum vastgezette WebDriverAgent | Runtime via Xcode; automatiseringsbrug via Instellingen → Server → Rigs |
Na de eerste keer opstarten van elke soort microVM cachet de server een vooraf
uitgepakte kopie onder de datadirectory en start hij elke latere machine
daaruit op — inclusief voorverwarmde images waarop de packages al zijn
geïnstalleerd. De terminal voorverwarmt een CLI-toolset in de stijl van een
GitHub-hosted runner (git, gcc, python3, jq, rsync,
archiveringstools en de rest van de apt-basis; geen Docker of taal-toolcaches).
De Computer-qcow2 bakt bij het bouwen van de image dezelfde CLI-namen er al
in, naast XFCE en de drie browsers. Elke browser voorverwarmt zijn engine. Alle
drie de engines delen een Debian-basis, maar nooit een pack: de cache is
gekoppeld aan de image, de engine en een audiorevisie
(audio-v1-<engine>), omdat een machine die voor de ene engine is
voorverwarmd — of voordat PulseAudio en ffmpeg deel uitmaakten van de workload
— niets van de andere in huis heeft. De terminal-pack is om dezelfde reden
gekoppeld aan een toolsetrevisie (tools-v1): een pack die is voorverwarmd
voordat de compiler deel uitmaakte van de image, mag niet een machine bedienen
die er een hoort te hebben.
Er is geen ingebakken automatiseringsimage die de moeite waard is — de
chromedp/headless-shell van Chromium compileert zowel ALSA als PulseAudio
eruit, dus hij kan nooit geluid produceren; de enige onderhouden
Firefox-versie is 33× zo groot als de Debian-basis en bevat nog steeds geen
socat; een onderhouden WebKit-versie bestaat helemaal niet. Elke engine
installeert dus bij de eerste start (chromium, firefox-esr of
webkit2gtk-driver) en bereikt daarbij de Debian-archieven
(deb.debian.org, security.debian.org, cloudfront.debian.net). Chromium
is het distributiebinary, gestart als chromium --headless=new.
Aangepaste images per werkruimte
Sectie getiteld “Aangepaste images per werkruimte”| Instellingssleutel | Overschrijft |
|---|---|
rigs.smolvm.execImage |
De Terminal (VM)-image |
rigs.smolvm.browserImage |
De Chromium Browser (VM)-image |
Ingesteld via de door beheerders afgeschermde instellingenopslag van de werkruimte (Instellingen → Server → Rigs → Aangepaste images (deze werkruimte)). De waarde moet een registry-referentie zijn — lokale paden, archieven en op flags lijkende strings worden geweigerd, zowel in het veld als opnieuw bij het opstarten. Een ongeldige opgeslagen waarde wordt met een duidelijke melding genegeerd en in plaats daarvan start de standaardimage op. De eigen registry van de image (plus bekende blob-CDN-metgezellen voor Docker Hub, GHCR, Quay, GitLab en GCR) wordt voor het ophalen via het egress-hek toegelaten.
Imagecontract voor de terminal — bash aanwezig; git, curl, socat
vooraf geïnstalleerd of een Debian/Ubuntu-apt-basis (de omhulling installeert
bij de eerste start die drie plus een CLI-toolset in de stijl van een
GitHub-hosted runner: compilers, Python 3, jq, archiveringstools, rsync.
Taal-toolcaches en Docker worden niet geïnstalleerd).
Imagecontract voor de browser — een Debian/Ubuntu-apt-basis (of de al
geïnstalleerde packages) met bash en socat, plus een chromium-binary die
de server zelf start als chromium --headless=new, met DevTools op
gast-loopback 9223, doorgestuurd naar gastpoort 9222. PulseAudio en ffmpeg
worden bij de eerste start geïnstalleerd voor het audiokanaal. Bouw niet
FROM chromedp/headless-shell: de upstream headless.gn compileert zowel ALSA
als PulseAudio eruit, dus die binary kan geen geluid produceren. De
overschrijving geldt alleen voor Chromium-rigs — het workloadcommando dat
hij opstart is dat van Chromium, en het aan Firefox of WebKit geven zou een
binary starten die er niet is. Een Firefox- of WebKit-rig negeert die met een
duidelijke melding en start zijn vastgezette image op.
Automatiseringspoorten — elke browsermachine stuurt precies één
host-loopbackpoort door naar gastpoort 9222. Daarachter: de DevTools van
Chromium en de remote agent van Firefox zitten op gast-loopback 9223 met een
socat-relay ervoor (beide binden zich onvoorwaardelijk aan loopback); het
stuurprogramma van WebKit neemt een --host aan en bindt zich zelf aan de
gast-NIC. Firefox valideert daarnaast de Host-header tegen zijn eigen poort,
dus de client stuurt de authority aan de gastzijde in plaats van degene die
hij heeft gebeld.
Actiewerkwoorden
Sectie getiteld “Actiewerkwoorden”Elke actie wordt volledig geparseerd: een misvormde payload levert een bericht op dat het veld noemt, nooit een exception. Observatiewerkwoorden (gemarkeerd met ○) blijven toegestaan zolang een mens de besturing heeft; wijzigende werkwoorden worden geweigerd.
computer_use
Sectie getiteld “computer_use”screenshot○, cursor_position○, mouse_move, left_click,
right_click, middle_click, double_click, triple_click,
left_mouse_down, left_mouse_up, left_click_drag, scroll, key,
hold_key (0–60 s), type, wait○ (0–60 s), set_display,
clipboard_read○, clipboard_write.
Coördinaten zijn gastpixels in de huidige modus van de gast; elke
schermafbeelding vermeldt de weergavegrootte. Toetscombinaties gebruiken
X11-notatie (ctrl+s, alt+Tab, Return).
clipboard_read neemt een selection: clipboard (wat ctrl+C vult, de
standaard), primary (X11 selecteren-en-kopiëren) of xdnd (een
sleepbeweging die gaande is). Een leeg resultaat is voor alle drie een normaal
antwoord. clipboard_write neemt alleen text — afbeeldingen en bestanden
reizen over het bestandskanaal, omdat de argumenten van een actie in het
auditlogboek worden vastgelegd en image-bytes daar niets te zoeken hebben.
Klembordinhoud komt terug omheind als niet-vertrouwde gegevens.
browser_use
Sectie getiteld “browser_use”navigate (alleen http/https), reload (hard optioneel), stop_loading,
click (selector of coördinaat), fill, type, key (DOM-toetsnamen),
scroll, mouse_move, drag, left_mouse_down, left_mouse_up,
extract○ (a11y | dom | console), screenshot○ (full_page
optioneel), set_viewport (minimaal 320×240), history, wait_for○
(selector, 0,1–30 s), clipboard_read○, clipboard_write.
Geëxtraheerde paginainhoud komt omheind terug als niet-vertrouwde gegevens.
De browser heeft precies één klembord, dus clipboard_read neemt geen
selection. Beide klembordwerkwoorden vereisen een secure context: een
pagina die over gewoon http:// wordt geserveerd heeft helemaal geen
klembord-API, en het werkwoord zegt dat in plaats van een leeg klembord te
melden — gebruik daar type, dat op de cursorpositie invoegt zonder via een
klembord te gaan.
mobile_use
Sectie getiteld “mobile_use”tap, swipe (50–5000 ms), type, key (aliassen back, home,
recents, enter, delete, backspace, tab, escape, search,
menu, volume_up, volume_down, power, of een willekeurige
KEYCODE_*), screenshot○, ui_dump○, install_apk (beperkt tot de
worktree van de rig en de datadirectory van de server), start_app,
stop_app, clear_app_data, uninstall_app, open_url en shell.
shell neemt een argv-lijst en draait binnen Android, nooit via een
hostshell; het dekt ontwikkelaarsdiagnoses zoals logcat, dumpsys en
pm grant af.
mobile_use heeft geen klembordwerkwoorden. Sinds Android 10 mag alleen de
app met focus het klembord lezen.
ios_use
Sectie getiteld “ios_use”tap, swipe (50–5000 ms), type, key (enter, backspace, tab,
escape, pijltoetsen of één afdrukbaar teken; optionele modifiers
command, control, option en shift), home, lock, unlock,
screenshot○, ui_dump○, install_app (een simulator-.app-map, beperkt
tot de worktree van de rig of de datadirectory van de server), start_app,
stop_app, uninstall_app, open_url en spawn. spawn neemt argv en
voert die binnen de simulator uit via simctl; het roept nooit een
hostshell aan.
Coördinaten zijn iOS-schermpunten, geen schermafbeeldingspixels. De live stream behoudt de vaste grootte van de simulator en zet die met balken in het beeld in plaats van het apparaat te verschalen. Tekstoverdracht via het klembord van host naar simulator en van simulator naar host gebruikt hetzelfde toestemmingsbeleid per gebruiker en per richting als andere rigs; bestanden en afbeeldingen worden niet geaccepteerd door het pasteboard-kanaal van iOS.
Elke rig maakt een eigen CoreSimulator-apparaat en WebDriverAgent-sessie aan. Bij het sluiten wordt WebDriverAgent gestopt, wordt dat apparaat afgesloten en verwijderd, en verdwijnt de vermelding uit het register. iOS-rigs draaien alleen op een macOS-server met Xcode, een geïnstalleerde iOS-runtime en de vastgezette automatiseringsbrug. Ze bieden geen garantie voor audio, microfoon, bestandsdrop, hostshell of ingesloten netwerk.
Beheertools
Sectie getiteld “Beheertools”| Tool | Beschrijving |
|---|---|
rig_list |
Toon de rigs van een werkruimte met oppervlak, status, weergave en besturing |
rig_close |
Vernietig een rig en gooi de schijf weg |
Levenscyclus
Sectie getiteld “Levenscyclus”| Fase | Betekenis |
|---|---|
provisioning |
Opstarten; het statusdetail bevat de huidige stap woordelijk |
ready |
Bereikbaar en accepteert acties |
parked |
Geparkeerd wegens inactiviteit: vCPU’s gestopt, RAM blijft resident; de volgende actie wekt hem |
closing |
Aan het afsluiten |
closed |
Verdwenen; de rij blijft bestaan voor het auditspoor |
failed |
Gestorven of nooit opgekomen; te onderscheiden zodat de UI een nieuwe poging kan aanbieden |
| Afsluitreden | Wordt geactiveerd wanneer |
|---|---|
requested |
Een persoon of agent erom vroeg |
idleTimeout |
Inactief voorbij 2× het inactiviteitsvenster, of verwijderd wegens geheugen |
ttlExpired |
De harde levensduur is verstreken |
conversationEnded |
Het eigenaarsgesprek is beëindigd |
workspaceGone |
De werkruimte is verwijderd of het lidmaatschap is verloren |
serverShutdown |
De server stopt |
backendFailure |
De hypervisor eronder is gestorven |
Standaardwaarden en plafonds
Sectie getiteld “Standaardwaarden en plafonds”| Waarde | Terminal | Browser | Computer | Mobiel |
|---|---|---|---|---|
| Geheugen | 512 MB | 2048 MB (Chromium); 2560 MB (Firefox, WebKit) | 4096 MB | 4096 MB |
| vCPU’s | 2 | 2 | 4 | 4 |
| Harde TTL | 8 uur | 2 uur | 2 uur | 2 uur |
| Inactiviteitsvenster | 45 min | 15 min | 15 min | 15 min |
| Opstartweergave | — | 1280×800 | 1280×800 | 1080×1920 |
- Stills voor het agentkanaal zijn begrensd op 1280×800; het menselijke kanaal onderhandelt tot 2560×1600.
- Het budget voor resident geheugen van de host voor alle rigs is standaard 12 GB, geteld in residente megabytes (een geparkeerde VM houdt zijn RAM vast). Verwijdering gebeurt op basis van langst-niet-gebruikt en treft nooit een machine die iemand aanstuurt, bekijkt of waarin iemand een terminal open heeft.
- Een open terminal- of meekijkkanaal houdt de rig vast tegen parkeren en inactief opruimen; de harde TTL geldt nog steeds.
Poorten en dev-domeinen
Sectie getiteld “Poorten en dev-domeinen”| Poort | Waar | Gereserveerd voor |
|---|---|---|
7911 |
Terminalgast | De poortmultiplexer waar elke doorsturing overheen loopt |
9222, 9223 |
Browsergast | De automatiseringsrelay en -endpoint (WebKit bindt 9222 rechtstreeks en gebruikt geen relay) |
80, 443 |
Browser-gast-loopback | De HTTP/HTTPS-kanalen van de dev-domeinen |
- Detectie pollt de luisterende TCP-poorten van de terminalgast elke ~4 s, aan de serverkant.
- Per rig worden hoogstens 16 poorten automatisch doorgestuurd; meer poorten worden in het log vermeld, niet doorgestuurd.
- De doorsturing aan de hostkant bindt aan loopback en geeft de voorkeur aan het eigen poortnummer van de gast; Delen op lokaal netwerk voegt een door het besturingssysteem toegewezen LAN-poort toe.
- Dev-domeinen moeten overeenkomen met
name.testofname.localhost(kleine letters, label van maximaal 63 tekens). Eén domein mapt naar één poort. - HTTPS op een dev-domein gebruikt een lokale CA op de server (EC P-256, onder
<dataDir>/rigs/tls/, sleutels 0600 en nooit in een gast) met één wildcard-leaf voor*.test/*.localhost. Zonderopensslop de host is er geen HTTPS-kanaal; gewoon HTTP blijft wel routeren.
Egress-standaardwaarden
Sectie getiteld “Egress-standaardwaarden”| Oppervlak | Standaard-allowlist |
|---|---|
| Terminal | De ontwikkelaarsbasis van de sandbox (forges, pakketregisters, modelproviders) + de Ubuntu-apt-mirrors + de eigen forge-host van de worktree |
| Browser | usectrl.dev (de productsite) — plus de Debian-archieven bij de eerste keer opstarten van elke engine, terwijl die zijn packages installeert. De startpagina is een lokaal file://-document en heeft geen egress nodig |
| Computer | Leeg — alles weigeren — tot een aanroeper hosts toekent |
| Mobiel | Niet afgedwongen (netwerk beheerd door de emulator) |
Elke microVM krijgt daarnaast de registry-hosts van zijn image, alleen voor het ophalen. De set toegestane hosts van de inloggegevensbroker is afgeleid van dezelfde allowlist: er wordt geen token uitgegeven voor een host die de gast niet kan bereiken.
Klembord en bestandsoverdracht
Sectie getiteld “Klembord en bestandsoverdracht”Kopiëren en plakken in beide richtingen, en bestanden naar binnen en naar buiten slepen. Beschikbaar voor een persoon die een rig aanstuurt; een agent krijgt het klembord via de werkwoorden hierboven en helemaal geen bestandsoverdracht (hij heeft al een shell binnen de omhulling).
Het oversteken van het klembord is per gebruiker en per richting. Plakken van host naar rig is standaard toegestaan; kopiëren van rig naar host vraagt om toestemming (een machtiging van tien minuten, of altijd toestaan onder Instellingen → Server → Rigs → Klembordtoegang). De twee keuzes zijn onafhankelijk en zijn nooit een werkruimte-instelling.
| Kanaal | Route | Vervoert |
|---|---|---|
| Klembord | GET/POST /rig/clipboard/<rigId> |
Tekst, één PNG/JPEG (≤16 MB), en de gastpaden van bestanden op het klembord |
| Bestanden | POST /rig/files/<rigId> |
Maximaal 64 bestanden, ≤256 MB per stuk en ≤512 MB per drop, met een optioneel droppunt in gastpixels |
| Bestanden | GET /rig/files/<rigId>?p=<base64url path> |
De bytes van één bestand, terug naar buiten |
- HTTP, geen RPC. De RPC-socket sluit een verbinding bij een inkomend frame groter dan 256 KB — een DoS-beveiliging die goed is voor JSON-commando’s en fataal voor een geplakte schermafbeelding. Bytes reizen over hetzelfde soort route als rigframes en vergaderaudio al gebruiken.
- Auth is het ondertekende doel
rig-files:<workspaceId>/<rigId>plus lidmaatschap van de werkruimte — een eigen doel, zodat een URL die is uitgegeven om mee te kijken naar een machine niet ook bestanden erin kan schrijven. - Overname geldt. Het klembord schrijven en bestanden droppen zijn wijzigend en worden geweigerd zolang iemand anders de besturing heeft; het klembord lezen en een bestand naar buiten lezen zijn observerend en dus niet.
- Waar drops terechtkomen:
~/Drops(desktop),~/drops(terminal — naast de worktree, nooit erin, zodat een drop nooit als niet-gevolgde wijziging opduikt),/tmp/cc-drops(browser). De server kiest de map; een aanroeper kan die niet benoemen. Bestaande bestanden worden nooit overschreven — een botsende naam komt binnen als2-name.ext. - Wat de gast te horen krijgt: een browserpagina krijgt een echte
drop-gebeurtenis op het opgegeven punt (
Input.dispatchDragEvent); een desktop krijgt de bestanden plus hun URI’s op zijn klembord, omdat geen enkele host een XDND-sleepbeweging kan synthetiseren naar een willekeurige toolkit zonder een bevoorrechte daemon in de gast. Het antwoord vermeldt welke van de twee heeft plaatsgevonden. - Naar buiten slepen werkt alleen op de desktop en leest de
XdndSelectionvan de gast terwijl er wordt gesleept. Een payload die identiek is aan wat de gast al vasthield toen de druk begon, wordt behandeld als een verouderde selectie van een afgeronde sleepbeweging, niet als een nieuwe — X heeft geen stap “de sleepbeweging is voorbij”. - Vereisten voor de image: de desktopimage moet protocol 2 of hoger zijn (gebouwd nadat klembordondersteuning erin kwam). Een oudere image antwoordt met 404 en de app zegt dat je hem opnieuw moet bouwen in plaats van een kapotte machine te melden.
- Het auditlogboek legt de vorm vast, nooit de inhoud: rijen voor
clipboard_read,clipboard_write,drop_filesenread_filebevatten aantallen, groottes en paden. Een klembord is de plek waar inloggegevens steeds een paar seconden leven, en niets daarvan wordt opgeschreven.
Beveiligingen, gebeurtenissen en opslag
Sectie getiteld “Beveiligingen, gebeurtenissen en opslag”- Rig-tools declareren de actieklasse
enclosureControl(plusnetworkEgressenprocessSpawnbij de use-tools;mobile_useenios_usedeclareren ookpackageInstall).rig_closedeclareertenclosureControl;rig_listdeclareert niets. Standaard toegestaan; alleen-lezen-modi weigeren het in hun geheel; de autonomieschakelaar per ruimte kan het terugzetten naar eerst vragen. - Domeingebeurtenissen:
RigClosedEvent(met zijn afsluitreden),RigControlChanged(overname / teruggave),RigReaped(inactief, TTL of geheugenverwijdering, met de aansturende agent). Een rig openen is geen gebeurtenis. Zie domeingebeurtenissen. - Opslag:
rig_sessionsenrig_action_login elke werkruimtedatabase. Het actielogboek legt elke invoergebeurtenis vast met de bijbehorende identiteit en een monotone volgorde per rig; getypte tekst wordt teruggebracht tot een lengte en een hash voordat die wordt opgeschreven. - Datadirectory:
rigs/images/(geïmporteerde qcow2-images),rigs/smolvm/(runtime-status per rig),rigs/smolvm-packs/(vooraf uitgepakte machine-packs),rigs/tls/(de CA voor dev-domeinen),rigs/run/(QEMU-overlays en seeds). - Routes: de live weergave is een tabblad in een ruimte of op een PR-pagina;
/settings/server/rigsis het scherm Rigs-instellingen.