SOP Fan-In : Vue d’ensemble
Un fan-in est une source d’événements externe qui lance les exécutions de SOP. Chaque source transmet des événements au moteur SOP via dispatch_sop_event, qui associe chaque événement aux déclencheurs de chaque SOP chargé et lance les exécutions pour celles qui correspondent.
Une instance ZeroClaw peut lier plusieurs fan-ins à la fois : un topic MQTT, un chemin de système de fichiers et une clé de routage AMQP peuvent tous alimenter le même moteur sans processus séparés. Chaque source dispose d’un guide dédié ci-dessous.
Comment fonctionne le dispatch
- Un seul chemin de matcher : un seul matcher évalue chaque type de trigger, de sorte que la correspondance se comporte de la même manière quelle que soit la source.
- Audit de début d’exécution : les exécutions démarrées sont persistées via
SopAuditLogger. - Exécution headless : les déclencheurs cron et les livraisons de webhooks mènent leurs exécutions à leur terme. Le tick de maintenance transmet chaque
ExecuteStepouDeterministicStepdémarré par un cron au pilote d’exécution headless, et la route webhook transmet chaqueExecuteStepdémarré à ce même pilote (le dispatch exécute déjà les étapes déterministes) ; le pilote exécute l’étape en tant qu’agent propre à la SOP. Les sources qui n’ont pas encore de pilote actif consignent les actionsExecuteStepcomme en attente viaprocess_headless_results, au lieu de les exécuter. - Propriété en mode headless : une étape headless s’exécute sous l’agent désigné par le champ
agentde l’étape, à défaut sous l’agentde la SOP, et cet agent doit être configuré et activé. Il n’existe aucun tour d’agent ambiant dont hériter d’une identité ; une procédure sans propriétaire est donc rejetée au moment de la rédaction et refusée au dispatch ; elle n’est jamais exécutée sous un autre agent configuré. Une SOP manuelle est le seul cas où une sauvegarde se fait sans propriétaire, carsop_executeen fournit un ; l’endpoint d’exécution du tableau de bord, qui ne dispose d’aucun agent derrière lui, refuse de lancer une telle procédure. - Portée des outils en mode headless : un tour d’étape headless est restreint exactement comme un tour en direct : les outils de contrôle SOP (
sop_execute,sop_advance,sop_approve) sont toujours retirés afin qu’une étape ne puisse pas piloter sa propre exécution, et lescopedéclaré par l’étape est appliqué par-dessus lorsquesop.step_scope_enforceest défini. Un agent enfant lancé depuis l’étape hérite des mêmes exclusions. - Entrée non fiable : le texte du sujet et du payload sont limités, normalisés, filtrés par prompt-guard et encadrés avant d’atteindre le contexte du modèle.
Sources
Chaque type de déclencheur SOP, ses champs et son statut de dispatch, projetés directement depuis le registre SopTrigger :
| Type | Champs | Notes |
|---|---|---|
mqtt | topic, condition optionnel | Arrivée du message MQTT. En direct : transmis par l’écouteur MQTT. |
webhook | path | Requête HTTP entrante. En production : routes de passerelle /sop/* et routes /webhook donnant la priorité au SOP. |
cron | expression | Déclenchement basé sur le temps. En direct : distribué par le tick de maintenance SOP (chemins daemon / démarrage de canal). |
peripheral | board, signal, condition optionnelle | Signal matériel. Défini et apparié, mais aucun écouteur périphérique ne l’alimente. |
filesystem | path, optionnel condition, optionnel events | Filesystem modification. Live : fourni par le surveillant de système de fichiers. |
calendar | calendar_source, optionnel calendar_ids, optionnel condition | État de l’événement de calendrier. Défini et correspondant, mais aucun poller ne l’alimente en temps réel. |
channel | channel, optionnel alias, optionnel condition | Message entrant ou événement forge/platform sur un canal configuré (telegram, discord, slack, git, …). Live : diffusé par l’orchestrateur de canal lorsque le dispatch SOP du canal est activé. Le producteur forge Git définit un sujet d’événement sous la forme <channel>.<alias>:<event_type> et place event_type dans la charge utile, afin qu’une condition définie filtre les événements forge par type sans nécessiter de seconde forme de déclencheur. |
manual | aucun | Exécution initiée par l’agent via l’outil sop_execute. Pas un fan-in externe. |
amqp | routing_key, optionnel condition | Livraison AMQP. En direct : livrée par le consommateur AMQP dans un mode de dispatch SOP. |
Chaque source dispose d’un guide dédié dans la barre latérale. Les sources en direct (transmises par un écouteur en cours d’exécution ou une requête authentifiée via la passerelle) lancent des exécutions à mesure que les événements arrivent ; les déclencheurs cron sont distribués par le cycle périodique de maintenance SOP du daemon ; les exécutions initiées par un agent démarrent depuis l’intérieur d’un tour d’agent via sop_execute ; les autres sources définies mais non connectées (périphérique et calendrier) sont validées et mises en correspondance, mais aucune source d’événements en direct ne les achemine encore vers le répartiteur.
Valeurs par défaut de sécurité
| Inquiétude | Mécanisme |
|---|---|
| Authentification des webhooks | Authentification bearer de pairing du Gateway, avec gateway.webhook_secret/X-Webhook-Secret facultatifs ; /sop/* et /webhook utilisent le même limiteur de débit. Au moins un contrôle doit être configuré pour la distribution SOP, et tous les contrôles configurés doivent réussir. Les secrets d’alias distincts de [channels.webhook] n’autorisent jamais ces routes. |
| Protection contre le rejeu des webhooks | Clé X-Idempotency-Key facultative, avec un espace de noms par chemin SOP ainsi que des espaces de noms distincts pour /sop/* et /webhook. Les clés sont réservées avant le déclenchement et signifient qu’il y aura au plus une tentative, sans prouver qu’une exécution précédente a commencé |
| Transport MQTT | mqtts:// avec use_tls = true pour le transport TLS |
| Filesystem racines | Racines étendues (/, /home, /etc, /var, /proc, /sys, /dev, /tmp) refusées lors de la validation de la configuration à moins que allow_broad_roots ; les globs d’inclusion/exclusion définissent la portée des événements |
| Filesystem liens symboliques | Les chemins d’événements de liens symboliques sont rejetés avant toute lecture de métadonnées, de hachage ou de contenu par défaut ; follow_symlinks = true active l’option mais exige toujours que la cible canonique se résolve à l’intérieur d’une racine surveillée |
| Entrée du déclencheur non fiable | Les textes de topic et de payload sont plafonnés, normalisés, filtrés par le prompt-guard et encadrés avant le contexte du modèle |
| Bloc déclencheur non sécurisé | untrusted_input_guard = "block" refuse les événements non fiables non sécurisés avec BlockedUnsafe ; par défaut warn audite et autorise |
| Validation de Cron | Les expressions cron invalides échouent de manière sécurisée lors de l’analyse et de la construction du cache. |
| Propriété headless | Un SOP headless doit déclarer un agent propriétaire configuré et enabled ; la création bloque l’enregistrement et le pilote refuse l’étape plutôt que d’emprunter un autre agent configuré. Une exécution manuelle lancée depuis le tableau de bord est refusée de la même manière. |
| Portée de l’outil sans interface | Les tours d’étape headless excluent toujours les outils de contrôle SOP et respectent le scope déclaré par l’étape sous step_scope_enforce ; les agents enfants lancés depuis l’étape héritent de ces exclusions |
| Durée de vie du pilote sans interface | Les pilotes cron et webhook appartiennent à la génération du démon qui les a démarrés : ils sont d’abord vidés (30 s), puis interrompus et joints (5 s) avant qu’un rechargement reconstruise la configuration et le moteur SOP. Un pilote qui n’atteint aucun point d’attente (await) pendant ce délai de grâce continue de s’exécuter et est reporté dans la génération suivante, avec un journal plutôt que d’être détaché. |
| Répartition headless | Les sources sans journal de pilote en direct exécutent la progression au lieu d’exécuter automatiquement ExecuteStep |
Dépannage
| Symptôme | Cause probable | Corriger |
|---|---|---|
| SOP ne démarre jamais à partir d’une source en direct | non-correspondance du motif de déclenchement ou une condition en échec | Vérifier que le motif de déclenchement correspond à l’événement livré ; vérifier la condition par rapport à la charge utile |
| SOP démarré mais une étape ne s’est pas exécutée | Une source sans pilote actif (périphérique, calendrier) a atteint ExecuteStep | Utilisez cron, un webhook ou une autre source en direct, exécutez une boucle d’agent pour ExecuteStep, ou concevez l’exécution de manière à ce qu’elle se mette en pause en attente d’approbations |
| Le SOP cron démarre, puis échoue à chaque exécution avec « no owning agent » | la procédure ne déclare aucun agent, et une exécution headless n’en a aucun à hériter | Définissez agent dans SOP.toml (ou sur l’étape) avec un alias d’agent configuré |
| Le SOP cron échoue à chaque exécution avec « which is disabled » | l’agent propriétaire est configuré avec enabled = false | Réactivez l’agent, ou définissez agent sur un agent activé |
Le bouton d’exécution du tableau de bord renvoie 422 pour un SOP manuel | les étapes execute de la procédure ne déclarent aucun propriétaire, et une exécution depuis le tableau de bord n’a aucun tour d’agent dont elle pourrait hériter. | Définissez agent dans SOP.toml (ou sur l’étape), ou démarrez la procédure depuis un agent avec sop_execute |
| Une étape cron ne peut pas appeler un outil qu’elle a utilisé de manière interactive | the step’s scope excludes it under step_scope_enforce, or it is a SOP control tool | Élargissez le scope de l’étape ; les outils de contrôle SOP restent exclus par conception. |
| Le déclencheur de webhook ne se déclenche jamais | incompatibilité du chemin de déclenchement exact, sous-système SOP indisponible ou authentification refusée | Exécutez zeroclaw daemon avec sop.sops_dir configuré, faites correspondre exactement le chemin complet de la requête et fournissez les en-têtes bearer/secret configurés |
| Le déclencheur du périphérique ou du calendrier ne se déclenche jamais | source d’événements non raccordée au répartiteur | Utilisez une source en direct (Webhook, MQTT, Filesystem, AMQP) ou démarrez l’exécution avec sop_execute |
| Le déclencheur Cron ne se déclenche jamais | cycle de maintenance non exécuté (ni zeroclaw daemon ni zeroclaw channel start ; le lancement autonome de gateway start ne l’exécute pas), sops_dir non défini/vide, ou maintenance_interval_secs = 0 | Exécutez zeroclaw daemon (ou zeroclaw channel start) avec sop.sops_dir défini sur une valeur non vide (non défini par défaut ; la valeur documentée est shared/sops) et sop.maintenance_interval_secs différent de zéro (valeur par défaut : 60) |
Voir aussi
- Syntaxe : le format complet de
SOP.tomletSOP.md - Comment les SOP s’exécutent
- Canaux : Vue d’ensemble: le côté transport de MQTT, du système de fichiers et d’AMQP