Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

SOP Fan-In: Resumen

Un fan-in es una fuente de eventos externa que inicia ejecuciones de SOP. Cada fuente entrega eventos al motor de SOP a través de dispatch_sop_event, que compara cada evento con los desencadenadores de cada SOP cargado e inicia ejecuciones para los que coinciden.

Una instancia de ZeroClaw puede enlazar varias entradas al mismo tiempo: un tema MQTT, una ruta del sistema de archivos y una clave de enrutamiento AMQP pueden alimentar el mismo motor sin procesos separados. Cada origen tiene una guía dedicada a continuación.

Cómo funciona dispatch

  • Una ruta de matcher: un solo matcher evalúa cada tipo de trigger, por lo que el matching se comporta igual independientemente del origen.
  • Auditoría de inicio de ejecución: las ejecuciones iniciadas se persisten mediante SopAuditLogger.
  • Ejecución headless: los disparadores cron y las entregas de webhook llevan sus ejecuciones hasta completarse. El tick de mantenimiento entrega cada ExecuteStep o DeterministicStep de cron que se haya iniciado al controlador de ejecución headless, y la ruta de webhook entrega cada ExecuteStep iniciado a ese mismo controlador (el dispatch ya ejecuta los pasos deterministas). El controlador ejecuta el paso como el propio agente del SOP. Las fuentes que todavía no tienen un controlador activo registran las acciones de ExecuteStep como pendientes mediante process_headless_results, en lugar de ejecutarlas.
  • Propiedad en modo headless: un paso headless se ejecuta como el agente indicado en agent del paso; si no lo tiene, se usa el agent del SOP. Ese agente debe estar configurado y habilitado. No existe un turno de agente ambiental del que heredar una identidad, por lo que un procedimiento sin propietario se rechaza en el momento de la creación y se deniega al despacharlo; nunca se ejecuta como otro agente configurado. Un SOP manual es el único caso que se guarda sin propietario, porque sop_execute proporciona uno; el endpoint de ejecución del panel, que no tiene un agente detrás, se niega a iniciar dicho procedimiento.
  • Alcance de herramientas en modo headless: un turno headless de un paso se restringe exactamente igual que un turno en vivo: las herramientas de control del SOP (sop_execute, sop_advance, sop_approve) siempre se eliminan para que un paso no pueda dirigir su propia ejecución, y el scope declarado del paso se aplica además cuando sop.step_scope_enforce está activado. Un agente hijo generado desde el paso hereda las mismas exclusiones.
  • Entrada no confiable: el texto del tema y del payload están limitados, normalizados, filtrados por prompt-guard y enmarcados antes de llegar al contexto del modelo.

Fuentes

Cada tipo de desencadenador SOP, sus campos y su estado de envío, proyectados directamente desde el registro SopTrigger:

TipoCamposNotas
mqtttopic, condition opcionalLlegada de mensajes MQTT. En vivo: entregado por el listener de MQTT.
webhookpathSolicitud HTTP entrante. En producción: rutas de gateway /sop/* y rutas /webhook con prioridad SOP.
cronexpressionDisparo basado en tiempo. En vivo: enviado por el tick de mantenimiento SOP (rutas daemon / channel-start).
peripheralboard, signal, condition opcionalSeñal de hardware. Definida y coincidente, pero ningún oyente periférico la alimenta.
filesystempath, opcional condition, opcional eventsCambio en Filesystem. En vivo: entregado por el monitor de Filesystem.
calendarcalendar_source, opcional calendar_ids, opcional conditionEstado del evento del calendario. Definido y emparejado, pero ningún sondeador lo alimenta en vivo.
channelchannel, opcional alias, opcional conditionMensaje entrante o evento de plataforma de forge en un canal configurado (telegram, discord, slack, Git, …). En vivo: entregado por el orquestador del canal cuando el despacho SOP del canal está habilitado. El productor de forge de Git establece un tema de evento de la forma <channel>.<alias>:<event_type> y coloca event_type en la carga útil, de modo que una condition redactada filtra eventos de forge por tipo sin una segunda forma de activación.
manualningunoEjecución iniciada por el agente mediante la herramienta sop_execute. No es una fan-in externa.
amqprouting_key, condition opcionalAMQP delivery. Live: entregado por el consumidor AMQP en un modo de despacho SOP.

Cada fuente tiene una guía dedicada en la barra lateral. Las fuentes en vivo (entregadas por un listener en ejecución o una solicitud autenticada a la puerta de enlace) inician ejecuciones a medida que llegan los eventos; los activadores de cron se despachan mediante el ciclo periódico de mantenimiento de SOP del demonio; las ejecuciones iniciadas por agentes comienzan desde dentro de un turno del agente mediante sop_execute; las fuentes restantes definidas pero no conectadas (periféricos y calendario) validan y coinciden, pero todavía no tienen ninguna fuente de eventos en vivo que se enrute al despachador.

Valores predeterminados de seguridad

PreocupaciónMecanismo
Autenticación de webhookAutenticación bearer para el emparejamiento de Gateway, además de gateway.webhook_secret/X-Webhook-Secret opcional; /sop/* y /webhook comparten el mismo limitador de velocidad. Se debe configurar al menos un control para el envío de SOP, y todos los controles configurados deben superar la validación. Los secretos de alias independientes de [channels.webhook] nunca autorizan estas rutas
Protección contra ataques de repetición de webhooksX-Idempotency-Key opcional, con un espacio de nombres por ruta SOP y con espacios de nombres independientes para /sop/* y /webhook. Las claves se reservan antes del despacho e indican que se hará como máximo un intento, no que se haya iniciado una ejecución anterior.
Transporte MQTTmqtts:// con use_tls = true para transporte TLS
Raíces del FilesystemLas raíces amplias (/, /home, /etc, /var, /proc, /sys, /dev, /tmp) se rechazan en la validación de la configuración a menos que allow_broad_roots; los globos de inclusión/exclusión delimitan los eventos
Filesystem symlinksLas rutas de eventos de symlink se rechazan antes de leer cualquier metadato, hash o contenido de forma predeterminada; follow_symlinks = true habilita esta opción, pero aún requiere que el destino canónico resuelva dentro de una raíz vigilada
Entrada de activación no confiableEl texto del tema y del payload están limitados, normalizados, filtrados por prompt-guard y enmarcados antes del contexto del modelo
Bloque de activación no segurountrusted_input_guard = "block" rechaza eventos no confiables inseguros con BlockedUnsafe; warn por defecto audita y permite
Validación de CronLas expresiones cron no válidas fallan de forma segura durante el análisis y la construcción de la caché
Propiedad sin interfaz gráficaUn SOP headless debe declarar un agent propietario que esté configurado y enabled; la creación bloquea el guardado y el driver rechaza el paso en lugar de tomar prestado otro agente configurado. Una ejecución manual iniciada desde el dashboard se rechaza de la misma manera.
Ámbito de la herramienta sin interfazLos turnos headless de cada paso siempre excluyen las herramientas de control del SOP y respetan el scope declarado por el paso bajo step_scope_enforce; los agentes secundarios generados desde el paso heredan esas exclusiones
Duración del controlador sin interfazLos drivers de cron y webhook pertenecen a la generación del daemon que los inició: primero se drenan (30 s) y luego se abortan y se unen (join, 5 s) antes de que una recarga reconstruya la configuración y el motor de SOP. Un driver que no alcanza ningún punto de await durante ese período de gracia sigue en ejecución y se traslada a la siguiente generación, y se registra en el log en lugar de desvincularse.
Despacho headlessLas fuentes sin un registro de ejecución activo muestran el progreso en lugar de ejecutar automáticamente ExecuteStep

Solución de problemas

SíntomaCausa probableCorregir
SOP nunca comienza a partir de una fuente en vivodesajuste de patrón de activación o una condition fallidaVerifica que el patrón del desencadenador coincida con el evento entregado; comprueba la condition contra la carga útil
SOP se inició, pero un paso no se ejecutóUn origen sin controlador activo (periférico, calendario) llegó a ExecuteStepUsa cron, un webhook u otra fuente en vivo, ejecuta un bucle de agente para ExecuteStep o diseña la ejecución para que se pause en las aprobaciones
Inicio de SOP de cron; falla en cada ejecución con “no owning agent”el procedimiento no declara ningún agent, y una ejecución headless no tiene ninguno del que heredarEstablezca agent en SOP.toml (o en el paso) con un alias de agente configurado
Cron SOP falla en cada ejecución con “which is disabled”El agente propietario está configurado con enabled = falseVuelve a habilitar el agente o apunta agent a uno que esté habilitado
Botón de ejecución del panel devuelve 422 para un SOP manualthe procedure’s execute steps declare no owner, and a dashboard run has no agent turn to inherit one fromConfigure agent en SOP.toml (o en el paso), o inicie el procedimiento desde un agente con sop_execute
Un paso de cron no puede llamar a una herramienta que usó de forma interactivala scope del paso lo excluye bajo step_scope_enforce, o es una herramienta de control de SOPAmplía el scope del paso; las herramientas de control del SOP siguen excluidas por diseño
El desencadenador del webhook nunca se activadiscrepancia en la ruta exacta del desencadenador, subsistema SOP no disponible o autenticación rechazadaEjecuta zeroclaw daemon con sop.sops_dir configurado, haz que coincida exactamente con la ruta completa de la solicitud y proporciona los encabezados bearer/secret configurados
El desencadenador de periférico o de calendario nunca se activafuente de eventos no conectada al despachadorUsa una fuente activa (Webhook, MQTT, Filesystem, AMQP) o inicia la ejecución con sop_execute
El desencadenador de Cron nunca se activael ciclo de mantenimiento no se está ejecutando (no se ejecuta zeroclaw daemon ni zeroclaw channel start; el comando independiente gateway start no lo ejecuta), sops_dir no está definido o está vacío, o maintenance_interval_secs = 0Ejecute zeroclaw daemon (o zeroclaw channel start) con sop.sops_dir establecido en un valor no vacío (sin establecer de forma predeterminada; el valor documentado es shared/sops) y sop.maintenance_interval_secs distinto de cero (predeterminado 60)

Ver también