CommunityProgramación y desarrollogithub.com

fangdididi/trigger-rehearsal

Ensaya las reglas de activación de un agente reactivo o dirigido por eventos antes de activarlas. Convierte las reglas (de un hub de agentes, rutinas, CI, cron, automatizaciones) en una hoja de reglas neutral, la analiza en busca de bucles, cadenas sin protección, límites faltantes y doble procesamiento, y reproduce eventos reales o grabados para mostrar cada ejecución que habría comenzado, lo que se fusionó, omitió, encoló o descartó, y su costo.

¿Qué es trigger-rehearsal?

Trigger Rehearsal es una herramienta de simulación y validación de reglas de activación para agentes de IA dirigidos por eventos. Su propósito principal es detectar problemas peligrosos como bucles de auto-activación, cadenas de reacción descontroladas, activaciones por ruido, y límites de concurrencia presupuestaria antes de que las reglas se activen en producción. El agente traduce cualquier configuración de reglas existente (desde archivos de reglas de hubs de agentes como Claude Code, Cursor, o Codex, hasta CI `on:`, cron lines, o automatizaciones visuales) a un formato neutral `rules.json`. Luego aplica un linting para encontrar problemas (HOLD), reproduce eventos históricos o sintéticos a lo largo de días completos, y genera un informe detallado con veredictos (ARM, TRIM, HOLD) y líneas de tiempo. Es especialmente útil para equipos que implementan agentes autónomos en repositorios o sistemas de soporte, donde un error en las reglas puede resultar en costos elevados, trabajo duplicado o acciones no deseadas. La salida incluye métricas como costo por ejecución, límites diarios y profundidad de cadena, permitiendo ajustes precisos antes de activar cualquier regla.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/fangdididi/trigger-rehearsal/tree/HEAD

Installed? Explore more Programación y desarrollo skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Ensayo de Activación

Qué es esto

Un agente que se activa a sí mismo mediante eventos es tan seguro como sus reglas de activación. El agente en sí mismo puede ser cuidadoso y aún así quemar el presupuesto de un día, porque el problema suele estar un nivel arriba:

  • una regla reacciona a un evento que su propio trabajo produce, por lo que se dispara una y otra vez;
  • dos reglas se alimentan mutuamente a través de un segundo sistema (el agente comenta, el comentario se sincroniza, la sincronización lanza un webhook);
  • una fuente ruidosa envía diez ediciones en dos minutos y cada una inicia una ejecución nueva;
  • una línea cron pensada como "revisa de vez en cuando" se dispara 288 veces al día;
  • dos reglas manejan el mismo evento y hacen el trabajo dos veces;
  • una regla que reembolsa, elimina o envía mensajes a personas se ejecuta sin preguntar a nadie.

Ninguno de estos problemas se muestra cuando pruebas el agente con un solo ejemplo. Aparecen cuando llega tráfico real. Trigger Rehearsal hace que el tráfico real llegue antes, en papel: escribes las reglas en un formato neutral, reproduces un día o una semana de eventos a través de ellas, y lees la línea de tiempo antes de que cualquier cosa esté armada.

Cuándo usarlo

  • Antes de activar cualquier regla que permita a un agente comenzar a trabajar sin que una persona escriba un prompt.
  • Al agregar una regla a un conjunto existente (una nueva regla puede cerrar un bucle que antes estaba abierto).
  • Cuando un agente en segundo plano se ejecutó mucho más, o mucho menos, de lo esperado.
  • Al elegir ventanas de debounce, límites de paralelismo y topes diarios, y quieres números en lugar de suposiciones.
  • Cuando un revisor pregunta "¿qué pasa si este repositorio recibe 50 issues en una hora?"

No para: verificar lo que el agente hace dentro de una ejecución (eso es una pregunta de prompt o habilidad), ni hacer pruebas de carga de la fuente de eventos en sí misma.

La hoja de reglas

Todo se traduce a rules.json. Mantén la traducción honesta: una regla de hoja por regla real, y escribe las protecciones que realmente existen, no las que planeas agregar.

{
  "tz": "Asia/Shanghai",
  "run_s": 180,
  "external_sources": ["github"],
  "budget": {"runs_per_day": 40, "cost_per_run": 0.15, "cost_per_day": 6},
  "rules": [
    {
      "name": "triage-new-issue",
      "on": {"source": "github", "types": ["issues.opened", "issues.edited"]},
      "where": {"repo": "me/app"},
      "key": "subject",
      "debounce_s": 300,
      "parallel": 1,
      "max_per_day": 20,
      "unless_actor": ["my-bot"],
      "unless_label": "triaged",
      "emits": [{"source": "github", "types": ["issues.labeled"], "actor": "my-bot", "labels": ["triaged"]}],
      "sensitive": [],
      "asks": false
    },
    {"name": "morning-digest", "on": {"cron": "0 9 * * 1-5"}, "max_per_day": 1}
  ]
}
CampoSignificado
on.source + on.typesQué eventos inician la regla. Omite types para coincidir con cada tipo de esa fuente.
on.cronUna línea cron de cinco campos en la zona horaria de la hoja. Una regla tiene source o cron.
whereCampos del evento que deben ser iguales a un valor (o estar en una lista).
keyCampo del evento que nombra el asunto (número de issue, ID de ticket, URL). Se usa para fusionar repeticiones.
debounce_sEspera este tiempo tras el último evento para un asunto, luego ejecuta una vez.
parallelCuántas ejecuciones de esta regla pueden estar activas a la vez. Las ejecuciones extra esperan.
max_per_dayLímite máximo por día local. Las ejecuciones extra se descartan.
run_sDuración típica de ejecución, usado para colas. Recurre al valor de la hoja, luego a 120.
unless_actor, unless_labelProtecciones: saltar eventos hechos por estos actores, o que tengan esta etiqueta.
emitsEventos que la ejecución misma produce (comentarios, etiquetas, cambios de estado, eventos posteriores). Incluye el actor y las etiquetas que llevarán.
sensitive + asksAcciones que necesitan una persona (eliminar, gastar, reiniciar, enviar). asks: true significa que la ejecución se detiene y pregunta primero.
external_sourcesFuentes alimentadas por el mundo exterior. Cualquier otra cosa debe ser emitida por una regla.
budgetOpcional. Ejecuciones por día, costo por ejecución y costo por día usados para el veredicto.

Paso a paso

  1. Recopila las reglas reales. Lee la configuración real, no la descripción de ella. Archivos de reglas del hub de agentes, rutinas guardadas, bloques on: de flujos de trabajo CI, líneas crontab, pantallas de automatización sin código. Toma nota de cualquier cosa que escriba de vuelta a una fuente que otra regla observa.
  2. Traduce a rules.json. Comienza con python3 scripts/rehearse.py new rehearsal/. Por cada regla, haz tres preguntas y completa los campos: qué la despierta, qué escribe una ejecución de vuelta, y qué la detiene de despertarse por sus propias escrituras. Si la respuesta a la tercera es "nada", omite la protección. El ensayo está diseñado para detectar eso.
  3. Lintea. python3 scripts/rehearse.py lint rehearsal/rules.json. Corrige cada HOLD antes de reproducir; los elementos REVIEW pueden esperar a los números.
  4. Recopila eventos. Lo mejor: exporta un día real ocupado de la fuente (registro de entregas de webhook, línea de tiempo de issues, registro de auditoría de helpdesk) en events.jsonl, un objeto JSON por línea con al menos t, source, type, más los campos que usan tu key y where. Si no hay historial, escribe un breve estallido sintético a propósito: diez ediciones en tres minutos, dos asuntos a la vez, un evento hecho por tu propio bot.
  5. Reproduce durante días completos. python3 scripts/rehearse.py replay rehearsal/rules.json rehearsal/events.jsonl --from 2026-11-02T00:00:00Z --to 2026-11-03T00:00:00Z --md rehearsal/report.md. Pasa --from/--to para que los números por día no se inflen por una ventana corta.
  6. Lee la línea de tiempo, no solo el veredicto. Busca ejecuciones en el mismo asunto con minutos de diferencia (debounce faltante o corto), cadenas con profundidad creciente (bucles), esperas largas (paralelismo demasiado bajo), descartes (tope demasiado bajo para trabajo real, o señal de que la regla se dispara por ruido).
  7. Ajusta y repite. Cambia una perilla a la vez y reproduce los mismos eventos, para que la diferencia se deba claramente a ese cambio.
  8. Decide. ARMA solo cuando la última reproducción sea ARM en un día realista. Guarda el rules.json final, el archivo de eventos y report.md juntos como el registro de por qué se activaron las reglas.

Veredictos

  • ARM: sin hallazgos HOLD o REVIEW. Seguro de activar tal como está escrito.
  • TRIM: algo desperdicia ejecuciones o puede saltar trabajo (sin clave, sin tope, superposición, el tope descartó eventos reales, cerca del presupuesto). Activar solo después de recortar, o con una razón por escrito.
  • HOLD: no activar. Auto-bucle, ciclo sin protección, una cadena que superó la profundidad 5, una acción sensible sin preguntar, sobrepresupuesto, o una línea cron rota.

El código de salida sigue al veredicto (0, 1, 2; 3 significa entrada incorrecta), por lo que un ensayo puede controlar un cambio de configuración en CI.

Ejemplo

Un equipo de soporte quiere que un agente responda tickets de helpdesk. Su hoja (en examples/loopy/) tiene una regla de respuesta que publica una réplica, que actualiza el ticket, que coincide con la misma regla. Una reproducción de un día normal da:

HOLD   self-loop            answer-ticket: la salida propia de la regla coincide con su propio disparador sin protección unless_actor/unless_label
HOLD   runaway              answer-ticket: la cadena siguió disparándose más allá de la profundidad 5 (3 cortes)
HOLD   sensitive-unasked    refund-check: declara acciones sensibles ['refund'] pero 'asks' no es verdadero
HOLD   over-runs-budget     -: 100.0/día contra un presupuesto de 30/día
REVIEW cron-tight           inbox-poll: hasta 720 disparos/día
VEREDICTO HOLD

Tres actualizaciones de ticket se convirtieron en 18 ejecuciones de respuesta. La solución es pequeña: agrega "unless_actor": ["support-bot"] a la regla de respuesta, establece "asks": true en la regla de reembolso, y reemplaza la encuesta de dos minutos con un script que emite inbox.changed solo cuando la bandeja de entrada realmente cambió (ver examples/loopy/rules.fixed.json). La siguiente reproducción del mismo día baja de 100 ejecuciones a 4 y el veredicto pasa a TRIM. El único hallazgo restante es que la respuesta y la verificación de reembolso ven un ticket de reembolso, lo cual es intencionado aquí, así que se acepta con una razón escrita de una línea al lado del informe.

Consejos

  • La mejor protección contra bucles única es una condición que se vuelve falsa después de la ejecución: una etiqueta que la ejecución agrega y la regla excluye, o un estado que la regla ya no coincide.
  • Los bucles entre sistemas son los más fáciles de pasar por alto. Si el agente escribe en el sistema A y el sistema A se sincroniza con B, lista el evento sincronizado bajo emits con el actor que mostrará.
  • El debounce agrega retraso por diseño. Elige la ventana según cuánto tiempo tarda una persona en terminar un estallido de ediciones, y mantenla corta donde alguien espera una respuesta.
  • El debounce no es deduplicación de acciones. Para cualquier cosa irreversible, la ejecución en sí misma debería verificar "¿ya hecho?" antes de actuar.
  • Un tope diario es un fusible, no un plan. Si la reproducción de un día normal lo alcanza, la regla es demasiado amplia.
  • La encuesta cada pocos minutos suele ser más barata como un pequeño script que compara el estado y emite un evento al cambiar; el agente solo se despierta cuando hay algo nuevo.
  • Vuelve a ejecutar el ensayo cada vez que se agregue una regla. La mayoría de los bucles son creados por la segunda regla, no por la primera.

Skills relacionados