Lewati ke konten

Rigs

Hanya fakta. Untuk model di baliknya, baca Rigs dan lingkungan terisolasi; untuk membuka mesin, ikuti panduannya.

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 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 ignoreCache milik 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 membutuhkan ffmpeg di 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.
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.

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.

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.

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.

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.

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.

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 Deskripsi
rig_list Daftar rig milik sebuah ruang kerja beserta permukaan, status, tampilan, dan pengendalinya
rig_close Hancurkan rig dan buang disknya
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
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 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.test atau name.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. Tanpa openssl di host berarti tidak ada jalur HTTPS; HTTP polos tetap dirutekan.
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.

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 sebagai 2-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 XdndSelection milik 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, dan read_file membawa jumlah, ukuran, dan path. Papan klip adalah tempat kredensial hidup selama beberapa detik setiap kalinya, dan tidak satu pun dari itu yang dicatat.
  • Alat rig mendeklarasikan kelas aksi enclosureControl (plus networkEgress dan processSpawn pada alat use; mobile_use dan ios_use juga mendeklarasikan packageInstall). rig_close mendeklarasikan enclosureControl; rig_list tidak 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_sessions dan rig_action_log di 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/rigs adalah layar pengaturan Rigs.