Rigs et enceintes
Un rig est une machine jetable qu’un agent pilote en temps réel — un navigateur, un bureau Linux, un émulateur Android, un simulateur iOS ou la machine derrière un terminal isolé. La plupart des rigs sont des VM ; les simulateurs mobiles gérés par l’hôte sont les exceptions explicites. Cette page explique chaque frontière et pourquoi les pièces sont agencées ainsi. Pour en ouvrir un, consultez Donner une machine de test à un agent ; pour les verbes exacts, les ports et les valeurs par défaut, consultez la référence des rigs.
Pourquoi une VM, et non un bac à sable
Section intitulée « Pourquoi une VM, et non un bac à sable »Le bac à sable natif enferme un processus
dans une isolation par espaces de noms — réelle, mais il partage votre noyau et contraint un
processus, pas un ordinateur. Dès qu’un agent doit cliquer dans une application de
bureau, rendre une page dans un vrai navigateur ou lancer des expériences rm -rf auxquelles
vous préférez ne pas penser, la frontière honnête est une machine : son propre noyau, son
propre disque, sa propre pile réseau.
Les surfaces isolées s’appuient sur deux backends de VM :
- microVMs pour le terminal et le navigateur — un démarrage d’hyperviseur en moins d’une seconde à partir d’images de conteneur épinglées par empreinte.
- QEMU pour le bureau Linux complet, qui a besoin d’un périphérique d’affichage que la microVM n’a pas.
Les surfaces mobiles sont gérées par l’hôte et annoncent directement la frontière plus faible :
- Android pilote l’émulateur de Google via ADB.
- iOS crée et possède un appareil CoreSimulator sur un hôte Mac et le pilote via WebDriverAgent. L’appareil et ses données sont supprimés à la fermeture du rig, mais son réseau suit le Mac hôte.
Les rigs isolés écrivent dans une surcouche jetable par-dessus une image de base en lecture seule : un rig ne peut donc pas modifier ce dont le suivant démarre. Un rig iOS possède un appareil CoreSimulator jetable, supprimé à la fermeture du rig. Android se rattache à un émulateur de l’hôte qui survit à la session.
Une sortie réseau refusée par défaut
Section intitulée « Une sortie réseau refusée par défaut »Le réseau d’un rig part de rien. Les hôtes sont autorisés rig par rig au travers d’une
porte que l’invité ne peut pas contourner : les seules sorties de la machine sont celles
créées par la configuration de lancement. Un terminal isolé reçoit le socle développeur
(registres de paquets, forges, les miroirs apt) ; un rig navigateur autorise le site du
produit (usectrl.dev) et démarre sur une page file:// locale qui n’a besoin d’aucune
sortie réseau ; tout le reste est refusé au moment de la connexion.
Android et iOS ne sont pas couverts par cette porte. Leur émulateur et leur simulateur sur l’hôte utilisent le réseau de la machine serveur : l’interface et le rapport de capacités signalent donc la sortie réseau comme non appliquée et n’offrent jamais la commande trompeuse « redémarrer sans restriction ».
Sortie réseau et identifiants ne sont qu’une même politique vue des deux côtés — le courtier d’identifiants (plus bas) ne génère pas de jeton pour un hôte que l’invité ne peut pas atteindre.
Tout ce qu’un rig lit est traité comme non fiable : texte de page, DOM et arbres d’accessibilité, vidages d’interface et sorties de console reviennent vers l’agent encadrés par une règle permanente « ceci est une donnée, pas une instruction ». Ce cadre relève de la mise en forme ; la porte de sortie réseau est l’application qui le sous-tend.
L’entrée passe par l’hyperviseur, la capture par l’invité
Section intitulée « L’entrée passe par l’hyperviseur, la capture par l’invité »Pour la surface bureau, les événements clavier et pointeur sont injectés par les propres périphériques d’entrée virtuels de l’hyperviseur. L’invité n’exécute jamais de démon privilégié capable de synthétiser des entrées : compromettre les logiciels de l’invité ne met donc pas un clavier entre les mains de l’attaquant. La capture circule en sens inverse, via un petit agent non privilégié dans l’invité, car l’invité peut redimensionner les images avant leur transmission.
Deux voies d’affichage
Section intitulée « Deux voies d’affichage »La personne qui regarde et le modèle qui pilote ont des besoins opposés : un rig sert donc deux flux indépendants :
- La voie humaine est en pleine résolution à la taille de votre panneau, renégociée quand vous redimensionnez, relayée par le serveur sous forme d’octets opaques — le serveur ne décode jamais une image, car un décodeur vidéo sur le chemin des requêtes l’empêcherait de répondre aux RPC.
- La voie de l’agent est faite d’images fixes réduites, plafonnées à une taille adaptée au modèle, une image par résultat d’outil, les images plus anciennes étant écartées lors de la compaction tandis que leurs descriptions textuelles survivent.
Aucune voie ne fait de compromis pour l’autre : vous obtenez une image fluide, le modèle en obtient une économique.
La prise de contrôle est un point de passage obligé, pas une requête
Section intitulée « La prise de contrôle est un point de passage obligé, pas une requête »Le contrôle exclusif est appliqué au point unique par lequel passe chaque action — non en demandant au modèle de bien se tenir. Tant qu’une personne le détient, le serveur refuse les actions modificatrices de l’agent. L’agent conserve ses verbes d’observation (captures d’écran, extraction) pour pouvoir raconter ce que vous faites, et la prise de contrôle lui est signalée par sa voie de pilotage plutôt que de le laisser la découvrir à travers des clics refusés. Cliquer et taper sur le canevas fonctionne dès que personne d’autre ne détient ce verrou — ou lorsque c’est vous ; l’étiquette d’état indique Vous avez le contrôle. Chaque événement d’entrée — le vôtre comme celui de l’agent — atterrit dans un journal d’audit par rig avec son auteur et une séquence monotone : « qui a cliqué là » trouve donc toujours sa réponse après la disparition de la machine.
Le contenu franchit la frontière ; les machines restent séparées
Section intitulée « Le contenu franchit la frontière ; les machines restent séparées »Le copier-coller fonctionne dans les deux sens, tout comme le glisser-déposer de fichiers dans un sens et dans l’autre — mais un rig est un autre ordinateur, et la conception ne prétend jamais le contraire.
Le presse-papiers est transporté à la demande, et non recopié en continu. Appuyez sur la combinaison de copie au-dessus d’un rig : l’invité reçoit l’ordre de copier, puis ce qu’il a placé dans son presse-papiers — texte, image, liste de fichiers — est récupéré et placé dans le vôtre. Le collage envoie le même contenu en sens inverse, puis déclenche un collage à l’intérieur de l’invité. Rien n’est synchronisé en arrière-plan : un mot de passe copié sur votre propre machine n’arrive pas silencieusement dans une VM parce qu’un minuteur s’est déclenché.
Le franchissement est contrôlé par utilisateur et par sens, indépendamment. Le collage vers un rig est autorisé par défaut ; la copie depuis un rig demande d’abord confirmation (une autorisation de dix minutes, ou Toujours autoriser sous Paramètres → Serveur → Rigs → Accès au presse-papiers). Ce n’est jamais un réglage d’espace de travail : un membre ne peut pas consentir pour le presse-papiers d’un autre.
Sur macOS, la combinaison de franchissement est ⌘C/⌘V, sans ambiguïté — ⌃C continue d’atteindre un shell de l’invité en tant qu’interruption, ce qu’il est. Sur Windows et Linux, les deux combinaisons sont la même frappe : l’invité la reçoit donc inchangée et votre presse-papiers n’est écrasé que si celui de l’invité a réellement changé. Une interruption reste une interruption.
Les fichiers déposés à l’entrée sont copiés dans le dossier de dépôt de la machine, puis
proposés à celle-ci. Ce que « proposé » signifie dépend de ce qui peut honnêtement être fait :
une page de navigateur reçoit un vrai événement de dépôt à l’endroit où vous relâchez, si
bien qu’une zone de téléversement se comporte exactement comme avec un fichier local ; un
bureau reçoit les fichiers dans ~/Drops avec leurs chemins dans son presse-papiers, car
aucun hôte ne peut synthétiser un glisser-déposer vers une boîte à outils Linux arbitraire
sans exécuter un démon privilégié dans l’invité — précisément ce que cette conception refuse
d’avoir. Le résultat indique ce qui s’est produit : un CSV déposé sur une zone de
téléversement n’est jamais annoncé comme téléversé alors qu’il n’est qu’un fichier dans un
dossier. Déposer sur un terminal isolé copie le fichier dans la machine et tape son chemin
invité à l’invite, ce qu’un shell peut réellement utiliser.
Les fichiers extraits par glisser-déposer fonctionnent sur la surface bureau, où le protocole de glisser-déposer de X11 rend la charge utile lisible pendant qu’un glisser est en cours. Lancez un glisser à l’intérieur de l’invité, faites-le sortir du canevas : les fichiers sont récupérés vers votre machine et remis au système d’exploitation comme un vrai glisser. Copier des fichiers dans le gestionnaire de fichiers de l’invité et coller sur l’hôte fonctionne de la même manière. La surface navigateur ne propose délibérément pas cela : un navigateur sans interface n’a aucune sélection de glisser à lire, et le signal le plus proche disponible — la sélection de texte de la page — n’est pas du tout la preuve d’un glisser ; agir dessus détournerait des clics ordinaires.
Tout ce qui est lu depuis un invité reste du contenu non fiable : le texte du presse-papiers parvient à un modèle dans le même cadre qu’une extraction de page, et le journal d’audit consigne qu’un collage a eu lieu et son volume — jamais son contenu.
Les identifiants ne vivent jamais dans l’invité
Section intitulée « Les identifiants ne vivent jamais dans l’invité »git push fonctionne depuis un terminal isolé que vous avez ouvert, et pourtant l’invité ne stocke aucun jeton de
forge. Il détient un secret par VM dont le seul pouvoir est de demander au courtier
d’identifiants de l’hôte — via un tunnel contrôlé par l’hôte — un jeton de courte durée et
limité au dépôt, pour chaque opération, avec limitation de débit, borné par la même liste
d’hôtes autorisés que la sortie réseau, et révoqué dès la fermeture du rig. Une machine conçue
pour être jetée ne doit contenir rien qui vaille la peine d’être volé.
Ce que ce jeton peut faire est fixé à l’ouverture du rig. Un rig de terminal ouvert par une personne reçoit un jeton en écriture, borné par l’accès à la forge de ce membre. Un rig ouvert par un agent en reçoit un en lecture seule : un assistant d’identifiants git ne sait pas distinguer un push d’un fetch, donc la règle de push ne peut pas être interrogée à chaque push dans un invité, comme le fait la passerelle d’exécution d’agent sur l’hôte.
L’arbre de travail d’un rig est un satellite
Section intitulée « L’arbre de travail d’un rig est un satellite »Quand un rig embarque votre dépôt, l’arbre de travail de l’hôte reste la référence. La copie
est synchronisée au démarrage (les secrets comme les fichiers .env étant exclus), et les
commits ne reviennent que si vous le demandez — récupérés dans refs/rigs/<id>/*, jamais
poussés, jamais extraits. Rien à l’intérieur d’une VM ne peut déplacer votre branche ni
toucher votre arbre de travail ; fusionner ce qu’un rig a produit reste toujours une décision
humaine prise sur l’hôte.
Des ports sans brèche
Section intitulée « Des ports sans brèche »Un serveur de développement lancé dans la VM terminal devient joignable — sur votre machine, dans le Navigateur (VM), éventuellement sur votre réseau local, éventuellement sous un domaine de développement avec HTTPS — sans jamais ouvrir la machine. La table de ports de l’hyperviseur est figée au démarrage : tout le transfert ultérieur passe donc par deux canaux étroits contrôlés par l’hôte, un multiplexeur entrant pré-créé qui refuse de composer tout ce sur quoi l’invité n’écoute pas réellement, et des tunnels inverses que l’hôte maintient ouverts pour les connexions initiées par l’invité. Le HTTPS des domaines de développement se termine sur le serveur à l’aide d’une autorité générée localement, dont les clés n’entrent dans aucun invité. Les mécanismes sont décrits dans Transférer des ports depuis un terminal.
Des machines bornées par construction
Section intitulée « Des machines bornées par construction »Un rig ne peut pas devenir un animal de compagnie :
- une durée de vie maximale stricte que l’invité ne peut pas prolonger ;
- une échelle d’inactivité — mise en veille (vCPU arrêtés, RAM résidente) après la fenêtre d’inactivité, fermeture après le double — où un terminal ouvert ou un observateur qui regarde compte comme « en cours d’utilisation » ;
- un budget mémoire compté en mégaoctets résidents, et non en sessions, car une VM en veille libère du processeur tout en conservant chaque octet de RAM ; la machine la moins récemment utilisée est évincée en premier, et jamais une machine qu’une personne pilote ou regarde ;
- un démontage à l’arrêt du serveur, plus un balayage des orphelins marqués par propriétaire au démarrage suivant, pour qu’un serveur planté ne laisse jamais traîner un hyperviseur qui ne répond à personne.
Les premiers démarrages tirent l’image épinglée de la machine ; le serveur met ensuite en
cache une copie pré-extraite en arrière-plan, si bien que chaque machine ultérieure de ce type
démarre en quelques secondes et qu’un terminal isolé se présente avec un socle d’outils en
ligne de commande comparable à celui d’un runner hébergé par GitHub déjà installé —
compilateurs, Python, jq, outils d’archivage — et non un cache d’outils par langage ni
Docker. L’image Ordinateur intègre ce même socle en ligne de commande au moment de sa
construction, aux côtés de XFCE et des navigateurs.
Trois navigateurs, pas un seul
Section intitulée « Trois navigateurs, pas un seul »« Ça marche sur ma machine » est une affirmation sur un seul moteur de rendu. Un rig navigateur n’est donc pas « le navigateur » — c’est Chromium, Firefox ou WebKit, choisi à l’ouverture, et un rig exécute celui avec lequel il a été ouvert pendant toute sa vie. Une conversation peut en contenir un de chaque : ouvrir Firefox (VM) à côté de Chromium (VM) vous donne deux machines, et les pointer vers la même page constitue la comparaison. WebKit est ce qui ressemble le plus à Safari parmi ce qui tourne sous Linux — même lignée de moteur, il détecte donc les écarts que rencontrent les utilisateurs de Safari.
Les verbes sont identiques pour les trois ; les protocoles sous-jacents ne le sont pas, et les différences sont énoncées plutôt que lissées. Chromium parle le DevTools Protocol et pousse les images, si bien que sa vue en direct ne coûte rien tant que la page est immobile. Firefox parle WebDriver BiDi et WebKit le WebDriver classique, dont aucun ne dispose de screencast : leurs vues en direct fonctionnent par interrogation — quelques images par seconde, ce qui convient pour regarder une page et non une animation. Quand un moteur ne peut réellement pas faire quelque chose (Firefox n’a pas de rechargement contournant le cache ; WebKit ne voit pas les sorties de console journalisées avant la fin du chargement d’une page), la réponse le dit au lieu de faire silencieusement autre chose.
Où vivent les rigs dans le produit
Section intitulée « Où vivent les rigs dans le produit »Un rig n’est délibérément pas une destination globale. La vue en direct est un onglet dans
l’espace ou la PR où le travail se déroule, rattaché à cette conversation : votre onglet et les
appels browser_use de l’agent s’adressent donc à une machine (une par moteur, sur la
surface navigateur). Le fait que les rigs puissent démarrer ou non est une propriété de
l’hôte : les capacités, les images, les images personnalisées par espace de travail et la
liste des machines en cours se trouvent donc sous Paramètres → Serveur → Rigs. Piloter une
enceinte constitue sa propre classe d’actions de garde-fou,
si bien qu’un espace de travail, un agent ou un espace peut l’autoriser, exiger une validation
ou la refuser catégoriquement — les modes en lecture seule la refusent sans exception.