Rigs
Apenas factos. Para o modelo por trás deles, leia Rigs e recintos; para abrir uma máquina, siga o guia.
Superfícies e backends
Secção intitulada “Superfícies e backends”| Superfície | Controla | Backend | Valor | Saída contida |
|---|---|---|---|---|
| Terminal (exec) | Um shell sobre o canal exec da VM | microVM | smolvm |
Sim |
| Navegador | Chromium headless (CDP), Firefox (WebDriver BiDi) ou WebKit (W3C WebDriver) | microVM | smolvm |
Sim |
| Computador | Ambiente de trabalho X11: entrada através do hipervisor, captura através do agente do convidado | QEMU | qemu-hvf (macOS), qemu-kvm (Linux), qemu-tcg (alternativa não acelerada, nunca escolhida automaticamente) |
Sim |
| Android | Android sobre ADB | O emulador da Google | android-emulator |
Não — o emulador gere a sua própria rede |
| iOS | Simulador de iOS através do WebDriverAgent | CoreSimulator | ios-simulator |
Não — a rede segue o Mac anfitrião |
O terminal e a superfície computer_use partilham o valor de superfície
computer; o terminal distingue-se pelo seu marcador de imagem exec e nunca é
reutilizado como ambiente de trabalho controlável (nem vice-versa). Uma
conversa reutiliza uma única máquina de terminal.
Motores de navegador
Secção intitulada “Motores de navegador”| Motor | Valor | Protocolo | Vista em direto | Imagens fixas |
|---|---|---|---|---|
| Chromium | chromium (predefinido) |
Chrome DevTools Protocol | Transmissão de ecrã — o navegador envia fotogramas à medida que a página se repinta | JPEG |
| Firefox | firefox |
WebDriver BiDi | Imagens fixas por sondagem (o BiDi não tem transmissão de ecrã), limitadas a 6 fps | JPEG |
| WebKit | webkit |
W3C WebDriver (clássico) | Imagens fixas por sondagem, transcodificadas pelo ffmpeg do anfitrião | PNG |
Um rig executa um motor durante toda a sua vida. Uma conversa pode ter um rig por motor, que é o que torna possível uma comparação lado a lado: abrir o «Firefox (VM)» ao lado do «Chromium (VM)» são duas máquinas, e fechar uma deixa a outra a correr.
Passe engine a rig.open ou à ferramenta browser_use. Um nome desconhecido
é recusado em vez de assumir a predefinição — pedir um navegador e receber
silenciosamente outro responde a uma pergunta de compatibilidade com a resposta
errada.
Limites específicos de cada motor, declarados em vez de contornados:
- O Firefox não tem recarregamento que contorne a cache (rejeita
liminarmente o
ignoreCachedo BiDi), pelo que um recarregamento forçado é um recarregamento normal. - O WebKit também não tem recarregamento que contorne a cache, nem
alimentação de consola (a saída é capturada ao intercetar
console.*após cada navegação, pelo que tudo o que seja registado durante o carregamento se perde — todas as extrações de consola o dizem), e precisa deffmpegno anfitrião para a sua vista em direto. - Nenhum dos dois expõe uma árvore de acessibilidade da plataforma através
do seu protocolo, pelo que
extract (a11y)devolve uma aproximação derivada do DOM, identificada como tal. - Nenhum dos dois aceita uma largada de ficheiros real; ainda assim, é possível apontar um campo de ficheiro para caminhos dentro da máquina.
Imagens de máquina
Secção intitulada “Imagens de máquina”| Superfície | Imagem | Obtida |
|---|---|---|
| Terminal | ubuntu:24.04, fixada por digest |
Automaticamente no primeiro arranque, através da rede controlada da própria máquina |
| Navegador (Chromium, Firefox, WebKit) | debian:trixie-slim, fixada por digest, mais os pacotes do próprio motor |
Automaticamente no primeiro arranque, depois colocada em cache como um pacote pré-aquecido |
| Computador | Uma imagem qcow2 de ambiente de trabalho com Chromium, Firefox, WebKit e a mesma linha de base de CLI ao estilo de um runner alojado no GitHub que o terminal pré-aquece | Importar em Definições → Servidor → Rigs (transferências fixadas por checksum quando publicadas) |
| Android | As imagens de sistema da Google | Através do SDK do Android |
| iOS | Um runtime do Simulador do Xcode mais o WebDriverAgent fixado por checksum | Runtime através do Xcode; ponte de automatização em Definições → Servidor → Rigs |
Após o primeiro arranque de cada tipo de microVM, o servidor coloca em cache uma
cópia pré-extraída no diretório de dados e arranca todas as máquinas posteriores
a partir dela — incluindo imagens pré-aquecidas com os pacotes já instalados. O
terminal pré-aquece um conjunto de ferramentas de CLI ao estilo de um runner
alojado no GitHub (git, gcc, python3, jq, rsync, ferramentas de
arquivo e o resto da linha de base do apt; não o Docker nem caches de
ferramentas de linguagem). A qcow2 do Computador incorpora os mesmos nomes de
CLI no momento da compilação da imagem, ao lado do XFCE e dos três navegadores.
Cada navegador pré-aquece o seu motor. Os três motores partilham uma base Debian,
mas nunca partilham um pacote: a cache tem como chave a imagem, o motor e uma
revisão de áudio (audio-v1-<engine>), porque uma máquina pré-aquecida para um
motor — ou antes de o PulseAudio e o ffmpeg fazerem parte da carga de trabalho —
não tem nada do outro. O pacote do terminal tem como chave uma revisão do
conjunto de ferramentas (tools-v1) pelo mesmo motivo: um pacote pré-aquecido
antes de o compilador fazer parte da imagem não deve servir uma máquina que se
supõe tê-lo.
Não vale a pena adotar nenhuma imagem de automatização pré-construída — o
chromedp/headless-shell do Chromium compila o ALSA e o PulseAudio para fora,
pelo que nunca consegue emitir som; a única imagem Firefox mantida tem 33× o
tamanho da base Debian e continua a não incluir o socat; e não existe nenhuma
imagem WebKit mantida. Por isso, cada motor instala-se no primeiro arranque
(chromium, firefox-esr ou webkit2gtk-driver) e alcança os arquivos Debian
(deb.debian.org, security.debian.org, cloudfront.debian.net) ao fazê-lo. O
Chromium é o binário da distribuição lançado como chromium --headless=new.
Imagens personalizadas por espaço de trabalho
Secção intitulada “Imagens personalizadas por espaço de trabalho”| Chave de definição | Substitui |
|---|---|
rigs.smolvm.execImage |
A imagem do Terminal (VM) |
rigs.smolvm.browserImage |
A imagem do Navegador Chromium (VM) |
Escritas através do armazenamento de definições do espaço de trabalho, protegido por administrador (Definições → Servidor → Rigs → Imagens personalizadas (este espaço de trabalho)). O valor tem de ser uma referência de registo — caminhos locais, arquivos e strings com aspeto de flag são recusados, tanto no campo como de novo no arranque. Um valor guardado inválido é ignorado de forma ruidosa e a predefinição é que arranca. O registo da própria imagem (mais os conhecidos CDNs de blobs associados para o Docker Hub, o GHCR, o Quay, o GitLab e o GCR) é admitido através do portão de saída para o pull.
Contrato da imagem do terminal — bash presente; git, curl e socat
pré-instalados ou uma base apt Debian/Ubuntu (o recinto instala esses três
mais um conjunto de ferramentas de CLI ao estilo de um runner alojado no GitHub
no primeiro arranque: compiladores, Python 3, jq, ferramentas de arquivo,
rsync. Os caches de ferramentas de linguagem e o Docker não são instalados).
Contrato da imagem de navegador — uma base apt Debian/Ubuntu (ou os pacotes
já instalados) com bash e socat, mais um binário chromium que o próprio
servidor lança como chromium --headless=new com o DevTools no loopback do
convidado 9223, retransmitido para a porta 9222 do convidado. O PulseAudio e
o ffmpeg são instalados no primeiro arranque para o canal de áudio. Não construa
FROM chromedp/headless-shell: o headless.gn a montante compila o ALSA e o
PulseAudio para fora, pelo que esse binário não consegue emitir som. A
substituição aplica-se apenas a rigs Chromium — o comando de carga de
trabalho que arranca é o do Chromium, e entregá-lo ao Firefox ou ao WebKit
lançaria um binário que não existe. Um rig Firefox ou WebKit ignora-a de forma
ruidosa e arranca a sua imagem fixada.
Portas de automatização — cada máquina de navegador encaminha exatamente uma
porta de loopback do anfitrião para a 9222 do convidado. Por trás dela: o
DevTools do Chromium e o agente remoto do Firefox residem no loopback do
convidado 9223 com um relé socat à frente (ambos se ligam ao loopback
incondicionalmente); o driver do WebKit aceita um --host e liga-se ele próprio
à NIC do convidado. Além disso, o Firefox valida o cabeçalho Host em relação à
sua própria porta, pelo que o cliente envia a autoridade do lado do convidado em
vez daquela com que contactou.
Verbos de ação
Secção intitulada “Verbos de ação”Todas as ações são analisadas de forma total: uma carga malformada devolve uma mensagem que indica o campo, nunca uma exceção. Os verbos de observação (marcados com ○) continuam permitidos enquanto uma pessoa detém o controlo; os verbos que alteram estado são recusados.
computer_use
Secção intitulada “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.
As coordenadas são pixels do convidado no modo atual do convidado; cada captura
de ecrã indica o tamanho do ecrã. As combinações de teclas usam a grafia do X11
(ctrl+s, alt+Tab, Return).
clipboard_read aceita uma selection: clipboard (o que o ctrl+C preenche, a
predefinição), primary (selecionar-para-copiar do X11) ou xdnd (um
arrastamento em curso). Um resultado vazio é uma resposta normal para os três.
clipboard_write aceita apenas text — as imagens e os ficheiros circulam pelo
canal de ficheiros, porque os argumentos de uma ação são persistidos no registo
de auditoria e os bytes de imagem não têm nada a fazer lá. O conteúdo da área de
transferência é devolvido cercado como dados não fidedignos.
browser_use
Secção intitulada “browser_use”navigate (só http/https), reload (hard opcional), stop_loading,
click (seletor ou coordenada), fill, type, key (nomes de teclas do DOM),
scroll, mouse_move, drag, left_mouse_down, left_mouse_up,
extract○ (a11y | dom | console), screenshot○ (full_page
opcional), set_viewport (mín. 320×240), history, wait_for○ (seletor,
0,1–30 s), clipboard_read○, clipboard_write.
O conteúdo extraído da página é devolvido cercado como dados não fidedignos.
O navegador tem exatamente uma área de transferência, pelo que clipboard_read
não aceita selection. Ambos os verbos de área de transferência exigem um
contexto seguro: uma página servida por http:// simples não tem sequer API
de área de transferência, e o verbo di-lo em vez de comunicar uma área vazia —
use aí type, que insere no cursor sem passar por uma área de transferência.
mobile_use
Secção intitulada “mobile_use”tap, swipe (50–5000 ms), type, key (aliases back, home,
recents, enter, delete, backspace, tab, escape, search,
menu, volume_up, volume_down, power, ou qualquer KEYCODE_*),
screenshot○, ui_dump○, install_apk
(confinado à worktree do rig e ao diretório de dados do servidor), start_app,
stop_app, clear_app_data, uninstall_app, open_url e shell.
shell aceita uma lista argv e corre dentro do Android, nunca através de um
shell do anfitrião; abrange diagnósticos de programador como logcat, dumpsys
e pm grant.
mobile_use não tem verbos de área de transferência. Desde o Android 10, só a
aplicação em foco pode ler a área de transferência.
ios_use
Secção intitulada “ios_use”tap, swipe (50–5000 ms), type, key (enter, backspace, tab,
escape, teclas de seta ou um único caractere imprimível; modificadores
command, control, option e shift opcionais), home, lock, unlock,
screenshot○, ui_dump○, install_app (um diretório .app de simulador
confinado à worktree do rig ou ao diretório de dados do servidor), start_app, stop_app,
uninstall_app, open_url e spawn. spawn aceita argv e executa
dentro do simulador através do simctl; nunca invoca um shell do anfitrião.
As coordenadas são pontos do ecrã iOS, não pixels da captura de ecrã. A transmissão em direto mantém o tamanho fixo do simulador e coloca-o em letterbox em vez de redimensionar o dispositivo. A transferência de texto da área de transferência do anfitrião para o simulador e vice-versa usa a mesma política de permissões por utilizador e por sentido que os outros rigs; os ficheiros e as imagens não são aceites pelo canal de área de transferência do iOS.
Cada rig cria um dispositivo CoreSimulator e uma sessão WebDriverAgent próprios. Fechá-lo para o WebDriverAgent, encerra e elimina esse dispositivo e remove a sua entrada do registo. Os rigs de iOS só correm num servidor macOS com Xcode, um runtime iOS instalado e a ponte de automatização fixada. Não expõem áudio, microfone, largada de ficheiros, shell do anfitrião nem qualquer garantia de rede em recinto.
Ferramentas de gestão
Secção intitulada “Ferramentas de gestão”| Ferramenta | Descrição |
|---|---|
rig_list |
Lista os rigs de um espaço de trabalho com superfície, estado, ecrã e controlador |
rig_close |
Destrói um rig e descarta o respetivo disco |
Ciclo de vida
Secção intitulada “Ciclo de vida”| Fase | Significado |
|---|---|
provisioning |
A arrancar; o detalhe do estado indica textualmente o passo atual |
ready |
Acessível e a aceitar ações |
parked |
Em pausa por inatividade: vCPUs paradas, RAM ainda residente; a ação seguinte acorda-o |
closing |
A encerrar |
closed |
Desapareceu; a linha mantém-se para o registo de auditoria |
failed |
Morreu ou nunca chegou a arrancar; distinguível para que a interface possa oferecer nova tentativa |
| Motivo de fecho | Despoletado quando |
|---|---|
requested |
Uma pessoa ou um agente o pediu |
idleTimeout |
Inatividade superior a 2× a janela de inatividade, ou remoção por memória |
ttlExpired |
O tempo de vida rígido chegou ao fim |
conversationEnded |
A conversa proprietária terminou |
workspaceGone |
O espaço de trabalho foi eliminado ou a adesão foi perdida |
serverShutdown |
O servidor está a parar |
backendFailure |
O hipervisor morreu por baixo dele |
Predefinições e limites
Secção intitulada “Predefinições e limites”| Valor | Terminal | Navegador | Computador | Móvel |
|---|---|---|---|---|
| Memória | 512 MB | 2048 MB (Chromium); 2560 MB (Firefox, WebKit) | 4096 MB | 4096 MB |
| vCPUs | 2 | 2 | 4 | 4 |
| TTL rígido | 8 h | 2 h | 2 h | 2 h |
| Janela de inatividade | 45 min | 15 min | 15 min | 15 min |
| Ecrã de arranque | — | 1280×800 | 1280×800 | 1080×1920 |
- As imagens fixas do canal do agente estão limitadas a 1280×800; o canal humano negoceia até 2560×1600.
- O orçamento de memória residente do anfitrião para todos os rigs tem por predefinição 12 GB, contado em megabytes residentes (uma VM em pausa mantém a sua RAM). A remoção é por menos recentemente utilizada e nunca retira uma máquina que alguém esteja a controlar, a observar, ou na qual tenha um terminal aberto.
- Um terminal aberto ou um canal de observação fixam o rig contra a entrada em pausa e a limpeza por inatividade; o TTL rígido continua a aplicar-se.
Portas e domínios de desenvolvimento
Secção intitulada “Portas e domínios de desenvolvimento”| Porta | Onde | Reservada para |
|---|---|---|
7911 |
Convidado do terminal | O multiplexador de portas por onde passa cada encaminhamento |
9222, 9223 |
Convidado do navegador | O relé e o endpoint de automatização (o WebKit liga-se diretamente à 9222 e não usa relé) |
80, 443 |
Loopback do convidado do navegador | Os canais HTTP/HTTPS dos domínios de desenvolvimento |
- A descoberta sonda as portas TCP à escuta do convidado do terminal a cada ~4 s, do lado do servidor.
- No máximo 16 portas são encaminhadas automaticamente por rig; as restantes são listadas no registo, não encaminhadas.
- O encaminhamento do lado do anfitrião liga-se ao loopback, preferindo o próprio número de porta do convidado; Partilhar na rede local acrescenta uma porta LAN atribuída pelo sistema operativo.
- Os domínios de desenvolvimento têm de corresponder a
name.testouname.localhost(minúsculas, etiqueta com no máximo 63 caracteres). Um domínio corresponde a uma porta. - O HTTPS dos domínios de desenvolvimento usa uma AC local do servidor (EC
P-256, em
<dataDir>/rigs/tls/, chaves com 0600 e nunca num convidado) com um único certificado final wildcard para*.test/*.localhost. Semopensslno anfitrião não há canal HTTPS; o HTTP simples continua a ser encaminhado.
Predefinições de saída
Secção intitulada “Predefinições de saída”| Superfície | Lista de permissões predefinida |
|---|---|
| Terminal | A linha de base do programador da sandbox (forjas, registos de pacotes, fornecedores de modelos) + os espelhos apt do Ubuntu + o próprio anfitrião de forja da worktree |
| Navegador | usectrl.dev (o site do produto) — mais os arquivos Debian no primeiro arranque de cada motor, enquanto este instala os seus pacotes. A página inicial é um documento file:// local e não precisa de saída |
| Computador | Vazio — negar tudo — até quem chama conceder anfitriões |
| Móvel | Não imposta (rede gerida pelo emulador) |
Além disso, cada microVM recebe os anfitriões de registo da sua imagem, apenas para o pull. O conjunto de anfitriões permitidos do broker de credenciais deriva da mesma lista de permissões: não é emitido nenhum token para um anfitrião que o convidado não consegue alcançar.
Área de transferência e transferência de ficheiros
Secção intitulada “Área de transferência e transferência de ficheiros”Ambos os sentidos de copiar/colar, e arrastar ficheiros para dentro e para fora. Disponível para uma pessoa que controla um rig; um agente obtém a área de transferência através dos verbos acima e nenhuma transferência de ficheiros (já tem um shell dentro do recinto).
A passagem da área de transferência é por utilizador e por sentido. A colagem do anfitrião para o rig é permitida por predefinição; a cópia do rig para o anfitrião pergunta primeiro (uma autorização de dez minutos, ou permitir sempre em Definições → Servidor → Rigs → Acesso à área de transferência). As duas escolhas são independentes e nunca são uma definição do espaço de trabalho.
| Canal | Rota | Transporta |
|---|---|---|
| Área de transferência | GET/POST /rig/clipboard/<rigId> |
Texto, um PNG/JPEG (≤16 MB) e os caminhos no convidado dos ficheiros na área de transferência |
| Ficheiros | POST /rig/files/<rigId> |
Até 64 ficheiros, ≤256 MB cada e ≤512 MB por largada, com um ponto de largada opcional em pixels do convidado |
| Ficheiros | GET /rig/files/<rigId>?p=<base64url path> |
Os bytes de um ficheiro, de volta |
- HTTP, não RPC. O socket RPC fecha uma ligação perante um frame de entrada superior a 256 KB — uma proteção contra DoS adequada a comandos JSON e fatal para uma captura de ecrã colada. Os bytes circulam pelo mesmo tipo de rota que os fotogramas dos rigs e o áudio das reuniões já usam.
- A autenticação é o alvo assinado
rig-files:<workspaceId>/<rigId>mais a adesão ao espaço de trabalho — um alvo próprio, para que um URL emitido para observar uma máquina não possa também escrever ficheiros nela. - A assunção do controlo aplica-se. Escrever na área de transferência e largar ficheiros alteram estado e são recusados enquanto outra pessoa detém o controlo; ler a área de transferência e extrair um ficheiro são observação e não o são.
- Onde caem as largadas:
~/Drops(ambiente de trabalho),~/drops(terminal — ao lado da worktree, nunca dentro dela, para que uma largada nunca apareça como uma alteração não rastreada),/tmp/cc-drops(navegador). É o servidor que escolhe o diretório; quem chama não o pode indicar. Os ficheiros existentes nunca são substituídos — um nome em conflito chega como2-name.ext. - O que é dito ao convidado: uma página de navegador recebe um evento de
largada real no ponto pedido (
Input.dispatchDragEvent); um ambiente de trabalho recebe os ficheiros mais os respetivos URIs na sua área de transferência, porque nenhum anfitrião consegue sintetizar um arrastamento XDND para um toolkit arbitrário sem um daemon privilegiado dentro do convidado. A resposta indica qual dos dois aconteceu. - Arrastar para fora só funciona no ambiente de trabalho e lê a
XdndSelectiondo convidado enquanto um arrastamento está em curso. Uma carga idêntica à que o convidado já tinha quando o premir começou é tratada como uma seleção obsoleta de um arrastamento terminado, e não como uma nova — o X não tem um passo de «o arrastamento terminou». - Requisitos da imagem: a imagem do ambiente de trabalho tem de ser do protocolo 2 ou posterior (construída depois de o suporte da área de transferência ter chegado). Uma imagem mais antiga responde 404 e a aplicação diz para a reconstruir em vez de comunicar uma máquina avariada.
- O registo de auditoria regista a forma, nunca o conteúdo: as linhas
clipboard_read,clipboard_write,drop_fileseread_filecontêm contagens, tamanhos e caminhos. Uma área de transferência é onde as credenciais vivem alguns segundos de cada vez, e nada disso fica registado.
Barreiras, eventos, armazenamento
Secção intitulada “Barreiras, eventos, armazenamento”- As ferramentas de rig declaram a classe de ação
enclosureControl(maisnetworkEgresseprocessSpawnnas ferramentas de utilização;mobile_useeios_usedeclaram tambémpackageInstall).rig_closedeclaraenclosureControl;rig_listnão declara nenhuma. Permitida por predefinição; os modos só de leitura negam-na integralmente; o seletor de autonomia por espaço pode rebaixá-la para perguntar primeiro. - Eventos de domínio:
RigClosedEvent(com o seu motivo de fecho),RigControlChanged(assunção do controlo / devolução),RigReaped(inatividade, TTL ou remoção por memória, com o agente que a controla). Abrir um rig não é um evento. Consulte eventos de domínio. - Armazenamento:
rig_sessionserig_action_logem cada base de dados de espaço de trabalho. O registo de ações regista cada evento de entrada com o respetivo principal e uma sequência monotónica por rig; o texto escrito é reduzido a um comprimento e a um hash antes de ser gravado. - Diretório de dados:
rigs/images/(imagens qcow2 importadas),rigs/smolvm/(estado de execução por rig),rigs/smolvm-packs/(pacotes de máquina pré-extraídos),rigs/tls/(a AC dos domínios de desenvolvimento),rigs/run/(camadas sobrepostas e seeds do QEMU). - Rotas: a vista em direto é um separador numa página de espaço ou de PR;
/settings/server/rigsé o ecrã de definições de Rigs.