Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Exemple pratique : le bot de mise à jour automatique StageX

stagehand est un bot ZeroClaw en production. Il surveille le flux de versions en amont, incrémente un paquet StageX, le compile, vérifie qu’il est reproductible par digest, pousse la modification, ouvre une pull request en brouillon et annonce le résultat. Aucun humain n’intervient avant que la PR existe.

Il s’agit du déploiement de référence de SOP : le pipeline est un SOP déterministe, le flux de versions arrive sur un canal AMQP, et l’agent déclenche le SOP à l’aide de l’outil sop_execute. AMQP peut également piloter le moteur SOP directement via un fan-in en direct ; cet exemple utilise par choix le modèle agent-fires-it, où le canal injecte chaque version dans la boucle de l’agent et où l’agent lance l’exécution. C’est cette séparation qui rend le modèle réutilisable.

Chaque commande, clé de configuration, nom d’outil, valeur d’état et clé d’audit ci-dessous correspond à une définition concrète dans le code source.

1. Le build

stagehand nécessite que les canaux AMQP et Matrix soient compilés. Les deux sont protégés par des feature flags et désactivés par défaut.

sh

cargo build --release --features channel-amqp,channel-matrix

Le résultat est un binaire zeroclaw qui charge les types de canaux amqp et matrix. Un binaire compilé sans channel-amqp rejette un bloc de canal amqp au démarrage et journalise un avertissement au lieu de le charger.

2. Les artefacts

Trois éléments résident sous la racine d’installation de ZeroClaw :

ArtefactEmplacementRôle
Configuration ZeroClaw~/.zeroclaw/L’agent, les canaux AMQP + Matrix et les paramètres sop.
sops/stagex-update/<install>/shared/sops/stagex-update/Le pipeline : SOP.toml (métadonnées) + SOP.md (les huit étapes).
skills/stagex-update/<install>/shared/skills/stagex-update/La colle qui déclenche la SOP lors d’un événement de release.

La configuration relie l’agent à deux canaux (amqp.anitya, matrix.announce), l’exécute en autonomie complète de sorte qu’il effectue les commits, les push et ouvre la PR sans point de contrôle, et fait pointer [sop] vers shared/sops en mode d’exécution deterministic. L’agent ne fusionne jamais ; un mainteneur adopte la branche et fusionne via un commit signé.

Le canal AMQP

Le canal amqp.anitya consomme le flux public de Fedora Messaging. Il lie la clé de routage de mise à jour de version d’Anitya sur l’échange amq.topic et se connecte via amqps:// avec TLS mutuel client ; le broker de Fedora exige un certificat client, le canal présente donc les client_cert et client_key configurés. Le canal valide sa configuration au chargement : amqp_url doit utiliser amqp:// ou amqps://, une URL amqps:// nécessite ca_cert, client_cert et client_key doivent être fournis ensemble, l’échange ne doit pas être vide, et au moins une clé de routage doit être liée.

Le corps JSON de chaque livraison est mappé dans le message entrant de l’agent par content_template, dont les espaces réservés {dotted.path} sont résolus par rapport au corps, transformant une livraison de release en “New release: bzip2 1.0.9 (was 1.0.8). Bump the StageX package for bzip2.” Le chemin pointé thread_id_field corrèle les réponses avec l’événement d’origine. La livraison est de type at-least-once par défaut (durable_ack = true) : le canal n’acquitte une release qu’après qu’elle a été remise de manière durable à la boucle de l’agent, de sorte qu’un plantage avant le démarrage de l’exécution entraîne une nouvelle livraison de l’événement au lieu de le supprimer silencieusement. C’est important pour un pipeline à effets de bord sans surveillance ; une release perdue laisserait un paquet discrètement à la traîne. Les identifiants et les certificats sont fournis au moment du déploiement et ne sont jamais commités : le jeton de push Codeberg est une variable d’environnement lue par le shell de l’agent, le jeton d’accès Matrix est défini sur l’instance en cours d’exécution, et les certificats CA et client Fedora sont placés sur l’hôte.

3. Validation

La surface zeroclaw sop se compose de trois sous-commandes. Il n’existe pas de sous-commande run ; les exécutions démarrent à partir d’un déclencheur ou de l’outil sop_execute.

sh

zeroclaw sop list
zeroclaw sop validate stagex-update
zeroclaw sop show stagex-update

La validation signale des avertissements pour un nom ou une description vides, l’absence de déclencheurs, l’absence d’étapes (un fichier SOP.md manquant ou vide) et les écarts dans la numérotation des étapes. Un avertissement d’étapes manquantes signifie que l’exécution échouerait au moment de l’exécution. Lancez les mêmes vérifications depuis l’interface de terminal zerocode lors de vos itérations ; la CLI constitue la vérification reproductible au moment du déploiement.

4. Déploiement

Le bot s’exécute comme un démon de longue durée afin de rester connecté au broker et au salon Matrix.

sh

zeroclaw daemon

Sur un hôte toujours actif, il s’exécute en tant que service géré qui redémarre avec la machine (voir Service & daemon) :

sh

zeroclaw service install
zeroclaw service start

Le canal AMQP se connecte au broker, lie sa clé de routage et consomme les livraisons. Le bot reste inactif jusqu’à ce que l’upstream publie une release.

5. Le parcours d’une release

Anitya publie une livraison de mise à jour de version. Le canal AMQP la reçoit, applique le content_template et transmet à l’agent un message entrant indiquant le paquet, la nouvelle version et l’ancienne version. L’agent déclenche le pipeline :

// tool: sop_execute
// args: { "name": "stagex-update", "payload": "{\"project\":{\"name\":\"bzip2\"},\"version\":\"1.0.9\",\"old_version\":\"1.0.8\"}" }

sop_execute démarre un SopRun avec un déclencheur manuel et transmet le payload dans le contexte d’exécution. Le cycle de vie à partir d’ici est identique à celui de toute autre exécution ; la source du déclencheur est la seule chose qui diffère.

6. L’exécution

Comme [sop] s’exécute en mode deterministic, les étapes s’exécutent séquentiellement sans aller-retour avec le LLM entre elles. La sortie de chaque étape est transmise à la suivante, et seule l’étape de génération du correctif fait appel au modèle, qui est local, de sorte que le code source du paquet ne quitte jamais l’hôte. Une étape de point de contrôle marque une pause pour approbation humaine ; ce pipeline s’exécute d’une traite jusqu’à la PR en brouillon.

running → completed

Les huit étapes, extraites de la section ## Steps de la SOP :

#ÉtapeCe que cela faitOutils
1RésoudreMapper le projet en amont au paquet StageX réel ; lire la version actuelle ; arrêter si elle n’est pas strictement plus récente.shell, file_read
2Incrément de version + hachageDéfinissez la nouvelle version, exécutez make fetch, écrivez le hash source correct, relancez la récupération jusqu’à ce que tout soit correct.shell, file_write
3GénérerCompiler uniquement ce paquet ; réessayer une fois en cas d’échec de hachage.shell
4Corriger si défectueuxEn cas d’échec de build, actualisez ou récupérez un correctif à l’aide du modèle local ; signalez les véritables ruptures d’API.shell, file_read, file_write, http_request
5Repro du digestmake digests, lancer une deuxième compilation, vérifier que le digest est inchangé.shell
6Commit + pushValidez (commit) sur une branche par paquet et par version ; poussez vers le fork.shell, git_operations
7Ouvrir une PR en brouillonRemplissez le modèle de PR, joignez les empreintes (digests), marquez comme prêt uniquement après une compilation reproduite sans erreur.http_request
8AnnoncerPubliez le résultat dans le salon Matrix : paquet, delta de version, statut de reproduction, digest, URL de la PR.shell

L’agent termine chaque étape par un appel à sop_advance rapportant le résultat :

// tool: sop_advance
// args: { "run_id": "<run-id>", "status": "completed", "output": "Passage de bzip2 1.0.8 → 1.0.9 ; hachage de la source recalculé et vérifié." }

status est l’une des valeurs completed, failed ou skipped. Lorsque la dernière étape est avancée, l’exécution passe à l’état completed et son horodatage completed_at est défini.

La progression est visible depuis un tour d’agent à tout moment :

// tool: sop_status
// args: { "sop_name": "stagex-update", "include_metrics": true }

Sécurité en mode headless

Lorsqu’une livraison arrive sans qu’aucune boucle d’agent active ne pilote les étapes, le runtime enregistre l’exécution et journalise chaque action en attente plutôt que d’abandonner silencieusement le travail. L’exécution attend un tour d’agent pour la faire avancer.

7. La piste d’audit

SopAuditLogger persiste chaque transition dans le backend Memory configuré sous la catégorie sop. Une exécution de mise à jour laisse ces clés :

CléContenu
sop_run_<run-id>Instantané complet de l’exécution, écrit au démarrage et mis à jour à la fin.
sop_step_<run-id>_1_8Un résultat par étape : statut, sortie, horodatages.
sop_approval_<run-id>_<step>Un enregistrement d’approbation de l’opérateur, lorsqu’une étape de point de contrôle en requiert un.
sop_timeout_approve_<run-id>_<step>Un enregistrement d’approbation automatique par expiration de délai, lorsqu’une approbation de point de contrôle expire.

include_metrics: true sur sop_status ajoute des agrégats spécifiques aux SOP ; include_gate_status: true ajoute l’état de la phase de confiance et de l’évaluateur de portes. Ces données proviennent de sop_status, pas de Prometheus. Le point de terminaison /metrics, lorsque le backend d’observabilité est prometheus, expose uniquement les familles générales zeroclaw_*.

8. Les garanties

Chaque garantie remonte au pipeline :

  • Le code source ne quitte jamais l’hôte. L’étape de recherche dans les sources des correctifs s’exécute avec un modèle local, de sorte que le code source des paquets n’atteint jamais un fournisseur distant.
  • Le build fait ses preuves. L’étape 5 effectue deux builds et compare les empreintes ; la PR n’est marquée comme prête que lorsque les deux correspondent.
  • Un humain est responsable du merge. Le bot s’arrête à l’étape « draft PR ouverte » ; un mainteneur adopte la branche et effectue le merge via un commit signé. Il n’effectue jamais de merge automatique.
  • L’exécution est reconstructible. L’instantané de l’exécution et chaque résultat d’étape sont persistés sous la catégorie sop, indexés par l’ID d’exécution.

9. Le motif

Un canal entrant ingère un événement, l’agent déclenche une SOP avec sop_execute, et un pipeline déterministe effectue le travail. Remplacez le flux AMQP par n’importe quel canal et les étapes par n’importe quelle procédure : le cycle de vie, les portes d’approbation et les clés d’audit restent identiques. Lorsqu’une étape nécessite un jugement humain, marquez-la comme point de contrôle et l’exécution se met en pause en attendant une approbation avant de continuer ; la seule différence avec le parcours sans intervention est la personne qui fait avancer l’exécution.