Rigs
Hanya fakta. Untuk model di baliknya, baca Rigs dan lingkungan terisolasi; untuk membuka mesin, ikuti panduannya.
Permukaan dan backend
Bagian berjudul “Permukaan dan backend”| Permukaan | Mengemudikan | Backend | Nilai | Egress terkurung |
|---|---|---|---|---|
| Terminal (exec) | Shell di atas kanal exec VM | microVM | smolvm |
Ya |
| Browser | Chromium headless (CDP), Firefox (WebDriver BiDi), atau WebKit (W3C WebDriver) | microVM | smolvm |
Ya |
| Computer | Desktop X11: masukan melalui hypervisor, tangkapan melalui agen sistem tamu | QEMU | qemu-hvf (macOS), qemu-kvm (Linux), qemu-tcg (fallback tanpa akselerasi, tidak pernah dipilih otomatis) |
Ya |
| Android | Android melalui ADB | Emulator Google | android-emulator |
Tidak — emulator mengelola jaringannya sendiri |
| iOS | Simulator iOS melalui WebDriverAgent | CoreSimulator | ios-simulator |
Tidak — jaringan mengikuti Mac host |
Terminal dan permukaan computer_use berbagi nilai permukaan computer;
terminal dibedakan oleh penanda image exec-nya dan tidak pernah dipakai ulang
sebagai desktop yang dapat dikemudikan (atau sebaliknya). Satu percakapan
menggunakan ulang satu mesin terminal.
Engine browser
Bagian berjudul “Engine browser”| Engine | Nilai | Protokol | Tampilan langsung | Gambar diam |
|---|---|---|---|---|
| Chromium | chromium (default) |
Chrome DevTools Protocol | Screencast — browser mendorong frame saat halaman digambar ulang | JPEG |
| Firefox | firefox |
WebDriver BiDi | Gambar diam yang di-poll (BiDi tidak punya screencast), dibatasi 6 fps | JPEG |
| WebKit | webkit |
W3C WebDriver (klasik) | Gambar diam yang di-poll, ditranskode oleh ffmpeg host | PNG |
Sebuah rig menjalankan satu engine sepanjang masa hidupnya. Satu percakapan dapat memuat satu rig per engine, dan itulah yang memungkinkan perbandingan berdampingan: membuka “Firefox (VM)” di samping “Chromium (VM)” berarti dua mesin, dan menutup salah satunya membiarkan yang lain tetap berjalan.
Teruskan engine ke rig.open atau ke alat browser_use. Nama yang tidak
dikenal ditolak alih-alih dijadikan default — meminta satu browser lalu
diam-diam mendapat browser lain berarti menjawab pertanyaan kompatibilitas
dengan jawaban yang salah.
Batas khusus tiap engine, dinyatakan apa adanya alih-alih diakali:
- Firefox tidak punya muat ulang yang melewati cache (ia menolak
ignoreCachemilik BiDi mentah-mentah), sehingga muat ulang keras sama dengan muat ulang biasa. - WebKit juga tidak punya muat ulang yang melewati cache maupun umpan
konsol (keluarannya ditangkap dengan mengaitkan
console.*setelah setiap navigasi, sehingga apa pun yang dicatat selama pemuatan terlewat — setiap ekstraksi konsol menyatakan hal itu), dan membutuhkanffmpegdi host untuk tampilan langsungnya. - Keduanya tidak mengekspos pohon aksesibilitas platform melalui
protokolnya, sehingga
extract (a11y)mengembalikan hampiran turunan DOM, yang diberi label demikian. - Keduanya tidak dapat menerima penyeretan berkas sungguhan; input berkas tetap dapat diarahkan ke path di dalam mesin.
Image mesin
Bagian berjudul “Image mesin”| Permukaan | Image | Cara memperoleh |
|---|---|---|
| Terminal | ubuntu:24.04, dipin dengan digest |
Otomatis saat boot pertama, melalui jaringan bergerbang milik mesin itu sendiri |
| Browser (Chromium, Firefox, WebKit) | debian:trixie-slim, dipin dengan digest, plus paket milik engine itu sendiri |
Otomatis saat boot pertama, lalu di-cache sebagai paket yang dihangatkan |
| Computer | Image desktop qcow2 dengan Chromium, Firefox, WebKit, dan baseline CLI ala runner yang dihosting GitHub yang sama dengan yang dihangatkan terminal | Impor di Pengaturan → Server → Rigs (unduhan yang dipin checksum jika dipublikasikan) |
| Android | Image sistem Google | Melalui Android SDK |
| iOS | Runtime Xcode Simulator plus WebDriverAgent yang dipin checksum | Runtime melalui Xcode; jembatan otomasi dari Pengaturan → Server → Rigs |
Setelah boot pertama setiap jenis microVM, server menyimpan salinan yang sudah
diekstrak di bawah direktori data dan mem-boot setiap mesin berikutnya dari
salinan itu — termasuk image yang sudah dihangatkan dengan paket yang telah
terpasang. Terminal menghangatkan toolset CLI ala runner yang dihosting GitHub
(git, gcc, python3, jq, rsync, alat arsip, dan sisa baseline apt;
bukan Docker atau toolcache bahasa). Qcow2 Komputer menanamkan nama CLI yang
sama pada waktu build image, di samping XFCE dan ketiga browser. Setiap browser
menghangatkan engine-nya. Ketiga engine berbagi basis Debian tetapi tidak
pernah berbagi paket: cache-nya dikunci pada image, engine dan revisi audio
(audio-v1-<engine>), karena mesin yang dihangatkan untuk satu engine — atau
sebelum PulseAudio dan ffmpeg menjadi bagian dari beban kerjanya — tidak memuat
engine lain di dalamnya. Paket terminal dikunci pada revisi toolset
(tools-v1) dengan alasan yang sama: paket yang dihangatkan sebelum compiler
menjadi bagian dari image tidak boleh melayani mesin yang seharusnya
memilikinya.
Tidak ada image otomasi siap pakai yang layak diambil — chromedp/headless-shell
milik Chromium mengompilasi ALSA dan PulseAudio keluar, sehingga ia tidak akan
pernah bisa mengeluarkan suara; satu-satunya image Firefox yang dipelihara
ukurannya 33× basis Debian dan tetap tidak menyertakan socat; image WebKit
yang dipelihara tidak ada sama sekali. Jadi setiap engine memasang dirinya saat
mulai pertama (chromium, firefox-esr, atau webkit2gtk-driver) dan
menjangkau arsip Debian (deb.debian.org, security.debian.org,
cloudfront.debian.net) saat melakukannya. Chromium adalah biner distribusi
yang diluncurkan sebagai chromium --headless=new.
Image kustom per ruang kerja
Bagian berjudul “Image kustom per ruang kerja”| Kunci pengaturan | Menimpa |
|---|---|
rigs.smolvm.execImage |
Image Terminal (VM) |
rigs.smolvm.browserImage |
Image Browser Chromium (VM) |
Ditulis melalui penyimpanan pengaturan ruang kerja yang bergerbang admin (Pengaturan → Server → Rigs → Image kustom (ruang kerja ini)). Nilainya harus berupa referensi registry — path lokal, arsip, dan string mirip flag ditolak, baik di kolomnya maupun sekali lagi saat boot. Nilai tersimpan yang tidak valid diabaikan dengan berisik dan default-nya yang di-boot. Registry milik image itu sendiri (plus pendamping blob-CDN yang dikenal untuk Docker Hub, GHCR, Quay, GitLab, dan GCR) diizinkan melewati gerbang egress untuk penarikannya.
Kontrak image Terminal — bash tersedia; git, curl, socat terpasang
sebelumnya atau basis apt Debian/Ubuntu (enclosure memasang ketiga paket itu
plus toolset CLI ala runner yang dihosting GitHub saat mulai pertama:
compiler, Python 3, jq, alat arsip, rsync. Toolcache bahasa dan Docker
tidak dipasang).
Kontrak image Browser — basis apt Debian/Ubuntu (atau paket yang sudah
terpasang) dengan bash dan socat, plus biner chromium yang diluncurkan
server sendiri sebagai chromium --headless=new dengan DevTools pada loopback
sistem tamu 9223, diteruskan ke port sistem tamu 9222. PulseAudio dan
ffmpeg dipasang saat mulai pertama untuk jalur audio. Jangan membuat image
FROM chromedp/headless-shell: headless.gn hulu mengompilasi ALSA dan
PulseAudio keluar, sehingga biner itu tidak dapat mengeluarkan suara. Penimpaan
berlaku untuk rig Chromium saja — perintah beban kerja yang di-boot adalah
milik Chromium, dan menyerahkannya ke Firefox atau WebKit akan meluncurkan
biner yang tidak ada di sana. Rig Firefox atau WebKit mengabaikannya dengan
berisik dan mem-boot image yang dipin.
Port otomasi — setiap mesin browser meneruskan tepat satu port loopback
host ke sistem tamu 9222. Di baliknya: DevTools milik Chromium dan agen jarak
jauh milik Firefox berada pada loopback sistem tamu 9223 dengan relai socat
di depannya (keduanya mengikat loopback tanpa syarat); driver WebKit menerima
--host dan mengikat NIC sistem tamu sendiri. Firefox juga memvalidasi header
Host terhadap port-nya sendiri, sehingga klien mengirim otoritas sisi sistem
tamu, bukan otoritas yang dihubunginya.
Verb tindakan
Bagian berjudul “Verb tindakan”Setiap tindakan diurai secara total: payload yang cacat mengembalikan pesan yang menyebut kolomnya, bukan pengecualian. Verb pengamatan (ditandai ○) tetap diizinkan selama manusia memegang kendali; verb yang memutasi ditolak.
computer_use
Bagian berjudul “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 detik), type, wait○ (0–60 detik), set_display,
clipboard_read○, clipboard_write.
Koordinat adalah piksel sistem tamu dalam mode sistem tamu saat itu; setiap
tangkapan layar menyatakan ukuran tampilan. Kombinasi tombol memakai ejaan X11
(ctrl+s, alt+Tab, Return).
clipboard_read menerima selection: clipboard (yang diisi oleh ctrl+C,
default), primary (pilih-untuk-salin X11), atau xdnd (penyeretan yang
sedang berlangsung). Hasil kosong adalah jawaban normal untuk ketiganya.
clipboard_write hanya menerima text — gambar dan berkas melintas di jalur
berkas, karena argumen sebuah tindakan disimpan permanen di log audit dan byte
gambar tidak layak berada di sana. Konten papan klip kembali dipagari sebagai
data yang tidak tepercaya.
browser_use
Bagian berjudul “browser_use”navigate (hanya http/https), reload (hard opsional), stop_loading,
click (selector atau koordinat), fill, type, key (nama tombol DOM),
scroll, mouse_move, drag, left_mouse_down, left_mouse_up,
extract○ (a11y | dom | console), screenshot○ (full_page
opsional), set_viewport (min 320×240), history, wait_for○ (selector,
0,1–30 detik), clipboard_read○, clipboard_write.
Konten halaman yang diekstrak kembali dipagari sebagai data yang tidak tepercaya.
Browser hanya punya satu papan klip, sehingga clipboard_read tidak menerima
selection. Kedua verb papan klip membutuhkan konteks aman: halaman yang
disajikan melalui http:// polos sama sekali tidak punya API papan klip, dan
verb-nya menyatakan hal itu alih-alih melaporkan papan klip yang kosong —
gunakan type di sana, yang menyisipkan di posisi kursor tanpa melewati
papan klip.
mobile_use
Bagian berjudul “mobile_use”tap, swipe (50–5000 ms), type, key (alias back, home,
recents, enter, delete, backspace, tab, escape, search,
menu, volume_up, volume_down, power, atau KEYCODE_* apa pun),
screenshot○, ui_dump○, install_apk
(terbatas pada worktree rig dan direktori data server), start_app,
stop_app, clear_app_data, uninstall_app, open_url, dan shell.
shell menerima daftar argv dan berjalan di dalam Android, tidak pernah
melalui shell host; ia mencakup diagnosis pengembang seperti logcat,
dumpsys, dan pm grant.
mobile_use tidak punya verb papan klip. Sejak Android 10, hanya aplikasi
yang sedang difokuskan yang boleh membaca papan klip.
ios_use
Bagian berjudul “ios_use”tap, swipe (50–5000 ms), type, key (enter, backspace, tab,
escape, tombol panah, atau satu karakter yang dapat dicetak; pengubah
command, control, option, dan shift bersifat opsional), home, lock,
unlock, screenshot○, ui_dump○, install_app (direktori .app simulator
yang terbatas pada worktree rig atau direktori data server), start_app,
stop_app, uninstall_app, open_url, dan spawn. spawn menerima argv dan
menjalankannya di dalam simulator melalui simctl; ia tidak pernah memanggil
shell host.
Koordinat adalah point layar iOS, bukan piksel tangkapan layar. Aliran langsung mempertahankan ukuran tetap simulator dan memberinya letterbox alih-alih mengubah ukuran perangkat. Transfer papan klip teks dari host ke simulator dan sebaliknya memakai kebijakan izin per pengguna, per arah yang sama dengan rig lain; berkas dan gambar tidak diterima oleh jalur papan klip iOS.
Setiap rig membuat perangkat CoreSimulator dan sesi WebDriverAgent yang dimilikinya. Menutupnya menghentikan WebDriverAgent, mematikan dan menghapus perangkat tersebut, serta menghapus entri registrinya. Rig iOS hanya berjalan di server macOS dengan Xcode, runtime iOS yang terpasang, dan jembatan otomasi yang dipin. Rig ini tidak menyediakan audio, mikrofon, penyeretan berkas, shell host, maupun jaminan jaringan yang terkurung.
Alat pengelolaan
Bagian berjudul “Alat pengelolaan”| Alat | Deskripsi |
|---|---|
rig_list |
Daftar rig milik sebuah ruang kerja beserta permukaan, status, tampilan, dan pengendalinya |
rig_close |
Hancurkan rig dan buang disknya |
Siklus hidup
Bagian berjudul “Siklus hidup”| Fase | Arti |
|---|---|
provisioning |
Sedang boot; detail status memuat langkah saat itu apa adanya |
ready |
Dapat dijangkau dan menerima tindakan |
parked |
Diparkir karena idle: vCPU dihentikan, RAM tetap residen; tindakan berikutnya membangunkannya |
closing |
Sedang dimatikan |
closed |
Sudah hilang; barisnya tetap ada untuk jejak audit |
failed |
Mati atau tidak pernah menyala; dapat dibedakan agar UI dapat menawarkan coba lagi |
| Alasan penutupan | Dipicu saat |
|---|---|
requested |
Seseorang atau agen memintanya |
idleTimeout |
Idle melewati 2× jendela idle, atau digusur karena memori |
ttlExpired |
Masa hidup kerasnya habis |
conversationEnded |
Percakapan pemiliknya berakhir |
workspaceGone |
Ruang kerja dihapus atau keanggotaan hilang |
serverShutdown |
Server sedang berhenti |
backendFailure |
Hypervisor di bawahnya mati |
Default dan batas atas
Bagian berjudul “Default dan batas atas”| Nilai | Terminal | Browser | Computer | Mobile |
|---|---|---|---|---|
| Memori | 512 MB | 2048 MB (Chromium); 2560 MB (Firefox, WebKit) | 4096 MB | 4096 MB |
| vCPU | 2 | 2 | 4 | 4 |
| TTL keras | 8 jam | 2 jam | 2 jam | 2 jam |
| Jendela idle | 45 menit | 15 menit | 15 menit | 15 menit |
| Tampilan saat boot | — | 1280×800 | 1280×800 | 1080×1920 |
- Gambar diam di jalur agen dibatasi pada 1280×800; jalur manusia menegosiasikan hingga 2560×1600.
- Anggaran memori residen host untuk semua rig default-nya 12 GB, dihitung dalam megabyte residen (VM yang diparkir tetap memegang RAM-nya). Penggusuran memakai kebijakan paling lama tidak digunakan dan tidak pernah mengambil mesin yang sedang dikemudikan seseorang, sedang ditonton, atau yang di dalamnya ada terminal terbuka.
- Terminal atau jalur tontonan yang terbuka menahan rig agar tidak diparkir dan tidak disapu karena idle; TTL keras tetap berlaku.
Port dan domain dev
Bagian berjudul “Port dan domain dev”| Port | Di mana | Direservasikan untuk |
|---|---|---|
7911 |
Sistem tamu terminal | Multiplekser port yang ditumpangi setiap penerusan |
9222, 9223 |
Sistem tamu browser | Relai dan endpoint otomasi (WebKit mengikat 9222 secara langsung dan tidak memakai relai) |
80, 443 |
Loopback sistem tamu browser | Jalur HTTP/HTTPS domain dev |
- Penemuan melakukan polling port TCP yang didengarkan sistem tamu terminal setiap ~4 detik, di sisi server.
- Paling banyak 16 port diteruskan otomatis per rig; selebihnya dicatat di log, tidak diteruskan.
- Penerusan di sisi host mengikat loopback, dan mengutamakan nomor port milik sistem tamu; Bagikan di jaringan lokal menambahkan port LAN yang ditetapkan OS.
- Domain dev harus cocok dengan
name.testatauname.localhost(huruf kecil, label maksimal 63 karakter). Satu domain memetakan ke satu port. - HTTPS domain dev memakai CA lokal server (EC P-256, di bawah
<dataDir>/rigs/tls/, kunci 0600 dan tidak pernah masuk ke sistem tamu mana pun) dengan satu leaf wildcard untuk*.test/*.localhost. Tanpaopenssldi host berarti tidak ada jalur HTTPS; HTTP polos tetap dirutekan.
Default egress
Bagian berjudul “Default egress”| Permukaan | Daftar izin default |
|---|---|
| Terminal | Baseline pengembang sandbox (forge, registry paket, penyedia model) + mirror apt Ubuntu + host forge milik worktree itu sendiri |
| Browser | usectrl.dev (situs produk) — plus arsip Debian pada boot pertama setiap engine, selama ia memasang paketnya. Halaman berandanya adalah dokumen file:// lokal dan tidak membutuhkan egress |
| Computer | Kosong — tolak semuanya — sampai pemanggil memberikan host |
| Mobile | Tidak ditegakkan (jaringan dikelola emulator) |
Setiap microVM juga mendapat host registry milik image-nya, hanya untuk penarikan. Himpunan host yang diizinkan milik broker kredensial diturunkan dari daftar izin yang sama: tidak ada token yang dicetak untuk host yang tidak dapat dijangkau sistem tamu.
Papan klip dan transfer berkas
Bagian berjudul “Papan klip dan transfer berkas”Salin/tempel di kedua arah, serta menyeret berkas masuk dan keluar. Tersedia bagi orang yang mengemudikan rig; agen mendapat papan klip melalui verb di atas dan sama sekali tidak mendapat transfer berkas (ia sudah punya shell di dalam enclosure).
Pelintasan papan klip bersifat per pengguna dan per arah. Menempel dari host ke rig diizinkan secara default; menyalin dari rig ke host meminta konfirmasi (izin sepuluh menit, atau selalu izinkan di Pengaturan → Server → Rigs → Akses papan klip). Kedua pilihan itu independen dan tidak pernah menjadi pengaturan ruang kerja.
| Jalur | Rute | Membawa |
|---|---|---|
| Papan klip | GET/POST /rig/clipboard/<rigId> |
Teks, satu PNG/JPEG (≤16 MB), dan path sistem tamu dari berkas yang ada di papan klip |
| Berkas | POST /rig/files/<rigId> |
Hingga 64 berkas, ≤256 MB masing-masing dan ≤512 MB per penyeretan, dengan titik jatuh dalam piksel sistem tamu yang opsional |
| Berkas | GET /rig/files/<rigId>?p=<base64url path> |
Byte satu berkas, ke luar |
- HTTP, bukan RPC. Soket RPC menutup koneksi pada frame masuk yang melebihi 256 KB — penjaga DoS yang tepat untuk perintah JSON dan fatal untuk tangkapan layar yang ditempel. Byte melintas di jenis rute yang sama dengan yang sudah dipakai frame rig dan audio rapat.
- Autentikasi adalah target bertanda tangan
rig-files:<workspaceId>/<rigId>plus keanggotaan ruang kerja — target tersendiri, sehingga URL yang dicetak untuk menonton sebuah mesin tidak dapat sekaligus menulis berkas ke dalamnya. - Pengambilalihan berlaku. Menulis papan klip dan menjatuhkan berkas bersifat memutasi dan ditolak selama orang lain memegang kendali; membaca papan klip dan membaca berkas keluar bersifat pengamatan dan tidak ditolak.
- Ke mana berkas yang dijatuhkan mendarat:
~/Drops(desktop),~/drops(terminal — di samping worktree, tidak pernah di dalamnya, sehingga penyeretan tidak pernah muncul sebagai perubahan yang tidak dilacak),/tmp/cc-drops(browser). Server yang memilih direktorinya; pemanggil tidak dapat menamainya. Berkas yang sudah ada tidak pernah ditimpa — nama yang bentrok mendarat sebagai2-name.ext. - Apa yang diberitahukan ke sistem tamu: halaman browser menerima
peristiwa drop sungguhan pada titik yang diminta
(
Input.dispatchDragEvent); desktop menerima berkasnya plus URI-nya di papan klipnya, karena tidak ada host yang dapat menyintesis penyeretan XDND ke toolkit sembarang tanpa daemon berhak istimewa di dalam sistem tamu. Balasannya menyatakan mana dari keduanya yang terjadi. - Menyeret keluar hanya untuk desktop dan membaca
XdndSelectionmilik sistem tamu selama penyeretan berlangsung. Payload yang identik dengan yang sudah dipegang sistem tamu saat penekanan dimulai diperlakukan sebagai seleksi basi dari penyeretan yang sudah selesai, bukan seleksi baru — X tidak punya langkah “penyeretan selesai”. - Persyaratan image: image desktop harus berprotokol 2 atau lebih baru (dibangun setelah dukungan papan klip ada). Image yang lebih lama menjawab 404 dan aplikasi menyuruh membangunnya ulang alih-alih melaporkan mesin yang rusak.
- Log audit mencatat bentuknya, tidak pernah isinya: baris
clipboard_read,clipboard_write,drop_files, danread_filemembawa jumlah, ukuran, dan path. Papan klip adalah tempat kredensial hidup selama beberapa detik setiap kalinya, dan tidak satu pun dari itu yang dicatat.
Pagar pengaman, peristiwa, penyimpanan
Bagian berjudul “Pagar pengaman, peristiwa, penyimpanan”- Alat rig mendeklarasikan kelas aksi
enclosureControl(plusnetworkEgressdanprocessSpawnpada alat use;mobile_usedanios_usejuga mendeklarasikanpackageInstall).rig_closemendeklarasikanenclosureControl;rig_listtidak mendeklarasikan apa pun. Diizinkan secara default; mode hanya-baca menolaknya sepenuhnya; dial otonomi per space dapat menurunkannya menjadi minta persetujuan lebih dulu. - Peristiwa domain:
RigClosedEvent(beserta alasan penutupannya),RigControlChanged(pengambilalihan / pengembalian),RigReaped(penggusuran karena idle, TTL, atau memori, beserta agen yang mengemudikannya). Membuka rig bukanlah peristiwa. Lihat peristiwa domain. - Penyimpanan:
rig_sessionsdanrig_action_logdi setiap basis data ruang kerja. Log tindakan mencatat setiap peristiwa masukan beserta principal-nya dan urutan monotonik per rig; teks yang diketik disunting menjadi panjang dan hash sebelum ditulis. - Direktori data:
rigs/images/(image qcow2 yang diimpor),rigs/smolvm/(status runtime per rig),rigs/smolvm-packs/(paket mesin yang sudah diekstrak),rigs/tls/(CA domain dev),rigs/run/(overlay dan seed QEMU). - Rute: tampilan langsung adalah tab di halaman space atau PR;
/settings/server/rigsadalah layar pengaturan Rigs.