Pular para o conteúdo

Rigs e recintos

Um rig é uma máquina descartável que um agente opera em tempo real — um navegador, um desktop Linux, um emulador Android, um Simulador de iOS ou a máquina por trás de um terminal isolado. A maioria dos rigs são VMs; os simuladores móveis gerenciados pelo host são as exceções explícitas. Esta página explica cada limite e por que as peças têm o formato que têm. Para abrir um, consulte Dar a um agente uma máquina para testar; para os verbos, portas e padrões exatos, consulte a referência de rigs.

O sandbox nativo envolve um processo em isolamento de namespaces — real, mas ele compartilha o seu kernel e restringe um processo, não um computador. No momento em que um agente precisa clicar em um app de desktop, renderizar uma página em um navegador de verdade ou rodar experimentos com rm -rf nos quais você prefere não pensar, o limite honesto é uma máquina: kernel próprio, disco próprio, pilha de rede própria.

As superfícies isoladas usam dois backends de VM:

  • microVMs para o terminal e o navegador — inicialização do hipervisor em menos de um segundo a partir de imagens de contêiner fixadas por digest.
  • QEMU para o desktop Linux completo, que precisa de um dispositivo de exibição que a microVM não tem.

As superfícies móveis são gerenciadas pelo host e declaram o limite mais fraco de forma direta:

  • O Android opera o emulador do Google via ADB.
  • O iOS cria e possui um dispositivo CoreSimulator em um host Mac e o opera via WebDriverAgent. O dispositivo e seus dados são excluídos quando o rig fecha, mas a rede dele segue o Mac host.

Rigs isolados gravam em uma camada descartável sobre uma imagem base somente leitura, então um rig não pode mudar aquilo de que o próximo inicializa. Um rig de iOS possui um dispositivo CoreSimulator descartável que é excluído quando o rig fecha. O Android se conecta a um emulador do host que sobrevive à sessão.

A rede de um rig começa em nada. Os hosts são admitidos por rig através de um portão que o convidado não consegue contornar: os únicos caminhos de saída da máquina são os que a configuração de inicialização criou. Um terminal isolado recebe a base de desenvolvedor (registros de pacotes, forges, os mirrors do apt); um rig de navegador admite o site do produto (usectrl.dev) e inicializa em uma página file:// local que não precisa de saída; todo o resto é recusado no momento da conexão.

Android e iOS não são cobertos por esse portão. O emulador e o simulador no host usam a rede do host do servidor, então a UI e o relatório de capacidades marcam a saída como não aplicada e nunca oferecem um controle enganoso de “reiniciar sem restrições”.

Saída e credenciais são uma única política vista de dois lados — o broker de credenciais (abaixo) não vai emitir um token para um host que o convidado não consegue alcançar.

Tudo o que um rig lê é tratado como não confiável: texto de página, árvores de DOM e de acessibilidade, dumps de UI e saída de console voltam ao agente cercados por uma regra permanente de “isto é dado, não instrução”. A cerca é o enquadramento; o portão de saída é a aplicação por trás dela.

A entrada passa pelo hipervisor; a captura, pelo convidado

Seção intitulada “A entrada passa pelo hipervisor; a captura, pelo convidado”

Para a superfície de desktop, eventos de teclado e ponteiro são injetados pelos próprios dispositivos de entrada virtuais do hipervisor. O convidado nunca roda um daemon privilegiado capaz de sintetizar entrada — então comprometer o software do convidado não entrega um teclado ao atacante. A captura flui no sentido oposto, através de um pequeno agente não privilegiado dentro do convidado, porque o convidado consegue escalonar quadros antes que eles cruzem a rede.

A pessoa que assiste e o modelo que opera têm necessidades opostas, então um rig serve dois fluxos independentes:

  • A faixa humana tem resolução total no tamanho do seu painel, renegociada conforme você redimensiona, retransmitida pelo servidor como bytes opacos — o servidor nunca decodifica um quadro, porque um decodificador de vídeo no caminho da requisição é o que o impede de responder a RPCs.
  • A faixa do agente são imagens estáticas reduzidas, limitadas a um tamanho amigável para modelos, uma imagem por resultado de ferramenta, com os quadros mais antigos descartados durante a compactação enquanto suas descrições em texto sobrevivem.

Nenhuma faixa faz concessões pela outra: você recebe uma imagem fluida, o modelo recebe uma barata.

A assunção de controle é um ponto de estrangulamento, não um pedido

Seção intitulada “A assunção de controle é um ponto de estrangulamento, não um pedido”

O controle exclusivo é aplicado no único ponto por onde toda ação passa — não pedindo que o modelo se comporte. Enquanto uma pessoa o detém, o servidor recusa as ações de mutação do agente. O agente mantém seus verbos de observação (capturas de tela, extração) para poder narrar o que você está fazendo, e é informado da assunção de controle pela sua faixa de orientação, em vez de ser deixado para descobri-la por cliques recusados. Clicar e digitar no canvas funciona sempre que ninguém mais detém esse bloqueio — ou quando é você que o detém; a etiqueta de status exibe Você tem o controlo. Todo evento de entrada — seu e do agente — cai em um log de auditoria por rig, com seu principal e uma sequência monotônica, para que a pergunta “quem clicou naquilo” continue tendo resposta depois que a máquina desaparecer.

O conteúdo atravessa o limite; as máquinas permanecem separadas

Seção intitulada “O conteúdo atravessa o limite; as máquinas permanecem separadas”

Copiar e colar funcionam nos dois sentidos, e arrastar arquivos para dentro e para fora também — mas um rig é um computador diferente, e o design nunca finge o contrário.

A área de transferência é transportada sob demanda, não espelhada continuamente. Pressione o atalho de cópia sobre um rig e o convidado é instruído a copiar; então o que quer que ele tenha colocado na área de transferência dele — texto, uma imagem, uma lista de arquivos — é buscado e colocado na sua. Colar envia o mesmo conteúdo no outro sentido e depois pressiona colar dentro do convidado. Nada é sincronizado em segundo plano: uma senha que você copia na sua própria máquina não chega silenciosamente para dentro de uma VM porque um temporizador disparou.

A travessia é controlada por usuário e por direção, de forma independente. Colar em um rig é permitido por padrão; copiar de um rig pergunta primeiro (uma concessão de dez minutos, ou Permitir sempre em Configurações → Servidor → Rigs → Acesso à área de transferência). Isso nunca é uma configuração de espaço de trabalho: um membro não pode consentir pela área de transferência de outro membro.

No macOS, o atalho de travessia é ⌘C/⌘V, que é inequívoco — ⌃C continua chegando a um shell do convidado como a interrupção que é. No Windows e no Linux, os dois atalhos são a mesma combinação de teclas, então o convidado a recebe inalterada e sua área de transferência só é sobrescrita quando a do convidado realmente mudou. Uma interrupção continua sendo uma interrupção.

Arquivos arrastados para dentro são copiados para a pasta de drop da máquina e depois oferecidos a ela. O que “oferecido” significa depende do que pode ser feito com honestidade: uma página de navegador recebe um evento de drop real no ponto em que você solta, então uma zona de upload se comporta exatamente como se comportaria para um arquivo local; um desktop recebe os arquivos em ~/Drops com os caminhos deles na área de transferência, porque nenhum host consegue sintetizar um arrasto em um toolkit Linux arbitrário sem rodar um daemon privilegiado dentro do convidado — que é exatamente o que este design se recusa a ter. O resultado diz qual dos dois aconteceu, então um CSV solto em uma zona de upload nunca é informado como enviado quando é apenas um arquivo em uma pasta. Soltar em um terminal isolado copia o arquivo para dentro e digita o caminho dele no convidado, no prompt, que é o que um shell consegue de fato usar.

Arquivos arrastados para fora funcionam na superfície de desktop, onde o protocolo de arrasto do X11 torna o conteúdo legível enquanto um arrasto está em andamento. Inicie um arrasto dentro do convidado, leve-o para fora do canvas, e os arquivos são buscados para a sua máquina e entregues ao SO como um arrasto real. Copiar arquivos no gerenciador de arquivos do convidado e colar no host funciona do mesmo jeito. A superfície de navegador deliberadamente não oferece isso: um navegador headless não tem seleção de arrasto para ler, e o sinal mais próximo disponível — a seleção de texto da página — não é evidência de um arrasto de forma alguma, então agir sobre ela sequestraria cliques comuns.

Tudo o que é lido de um convidado continua sendo conteúdo não confiável: o texto da área de transferência chega a um modelo dentro da mesma cerca que uma extração de página, e o log de auditoria registra que uma colagem aconteceu e quanto conteúdo havia — nunca o que ele dizia.

O git push funciona a partir de um terminal isolado que você abriu, mas o convidado não armazena nenhum token de forge. Ele guarda um segredo por VM cujo único poder é pedir ao broker de credenciais do host — por um túnel que o host controla — um token de curta duração, com escopo de repositório, por operação, com limite de taxa, limitado pela mesma lista de hosts permitidos da saída, e revogado no momento em que o rig fecha. Uma máquina feita para ser descartada não pode conter nada que valha a pena roubar.

O que esse token pode fazer é fixado quando o rig abre. Um rig de terminal aberto por uma pessoa recebe um token de escrita, limitado pelo acesso ao forge desse membro. Um rig aberto por um agente recebe um somente leitura: um credential helper do git não distingue um push de um fetch, então a regra de push não pode ser consultada a cada push dentro de um convidado, como o gateway de execuções de agentes faz no host.

Quando um rig carrega o seu repositório, a worktree do host continua sendo a autoridade. A cópia é sincronizada para dentro na inicialização (com segredos como arquivos .env excluídos), e os commits só voltam quando você pede — buscados para refs/rigs/<id>/*, nunca enviados, nunca colocados em checkout. Nada dentro de uma VM pode mover o seu branch ou tocar na sua árvore de trabalho; mesclar o que um rig produziu é sempre uma decisão humana tomada no host.

Um servidor de desenvolvimento iniciado dentro da VM do terminal fica acessível — na sua máquina, no Navegador (VM), opcionalmente na sua LAN, opcionalmente sob um domínio de desenvolvimento com HTTPS — sem nunca abrir a máquina. O mapa de portas do hipervisor é fixo na inicialização, então todo encaminhamento posterior passa por dois canais estreitos controlados pelo host: um multiplexador de entrada pré-criado que se recusa a discar para qualquer coisa em que o convidado não esteja de fato escutando, e túneis reversos que o host mantém abertos para conexões iniciadas pelo convidado. O HTTPS do domínio de desenvolvimento termina no servidor usando uma autoridade emitida localmente cujas chaves nunca entram em nenhum convidado. A mecânica está em Encaminhar portas a partir de um terminal.

Um rig não pode se tornar uma máquina de estimação:

  • um TTL rígido que o convidado não consegue estender;
  • uma escada de ociosidade — estacionar (vCPUs paradas, RAM residente) depois da janela de ociosidade, fechar depois do dobro dela — em que um terminal aberto ou um espectador assistindo conta como “em uso”;
  • um orçamento de memória contado em megabytes residentes, não em sessões, porque uma VM estacionada libera CPU e mantém cada byte de RAM; a máquina menos usada recentemente é despejada primeiro, e nunca uma que uma pessoa esteja operando ou assistindo;
  • desmontagem no desligamento do servidor, mais uma varredura de órfãos marcados por propriedade na próxima inicialização, para que um servidor que caiu nunca deixe abandonado um hipervisor que não responde a ninguém.

As primeiras inicializações baixam a imagem fixada da máquina; o servidor então mantém em cache uma cópia pré-extraída em segundo plano, para que toda máquina posterior desse tipo inicialize em segundos e um terminal isolado já suba com o tipo de base de CLI que um runner hospedado no GitHub tem instalada — compiladores, Python, jq, ferramentas de arquivamento — e não um toolcache de linguagem ou Docker. A imagem do Computador incorpora essa mesma base de CLI no momento da build, ao lado do XFCE e dos navegadores.

“Funciona na minha máquina” é uma afirmação sobre um único motor de renderização. Então um rig de navegador não é “o navegador” — é Chromium, Firefox ou WebKit, escolhido quando você o abre, e um rig executa aquele com que foi aberto por toda a sua vida. Uma conversa pode ter um de cada: abrir o Firefox (VM) ao lado do Chromium (VM) dá a você duas máquinas, e apontar ambos para a mesma página é a comparação. O WebKit é o mais próximo do Safari que existe rodando no Linux — mesma linhagem de motor, então ele pega as lacunas com que os usuários do Safari esbarram.

Os verbos são idênticos nos três; os protocolos por baixo não são, e as diferenças são declaradas em vez de suavizadas. O Chromium fala o DevTools Protocol e empurra quadros, então sua visualização ao vivo não custa nada enquanto a página está parada. O Firefox fala WebDriver BiDi e o WebKit fala WebDriver clássico, e nenhum dos dois tem screencast, então suas visualizações ao vivo fazem polling — alguns quadros por segundo, o que é certo para assistir a uma página e não para assistir a uma animação. Onde um motor genuinamente não consegue fazer algo (o Firefox não tem recarregamento que ignora o cache; o WebKit não vê a saída de console registrada antes de uma página terminar de carregar), a resposta diz isso em vez de silenciosamente fazer outra coisa.

Um rig deliberadamente não é um destino global. A visualização ao vivo é uma aba no espaço ou na PR onde o trabalho está acontecendo, com escopo naquela conversa — então sua aba e as chamadas browser_use do agente endereçam uma máquina (uma por motor, na superfície de navegador). Se os rigs conseguem ou não inicializar é uma propriedade do host, então capacidades, imagens, imagens personalizadas por espaço de trabalho e a lista de máquinas em execução ficam em Configurações → Servidor → Rigs. Operar um recinto é uma classe de ação de barreira à parte, então um espaço de trabalho, um agente ou um espaço pode permitir, exigir aprovação ou negar isso de imediato — os modos somente leitura negam isso por completo.