CommunityCodierung & Entwicklunggithub.com

fangdididi/trigger-rehearsal

Simuliere die Trigger-Regeln eines Hintergrund- oder ereignisgesteuerten Agenten, bevor du sie aktivierst. Wandele die Regeln (aus Agent-Hub-Regeldateien, Routinen, CI-„on:“-Blöcken, Cron-Zeilen, No-Code-Automatisierungen) in ein einheitliches Regelblatt um, prüfe es auf Selbsttrigger-Schleifen, ungeschützte Ketten, fehlende Begrenzungen und doppelte Bearbeitung und spiele dann reale oder aufgezeichnete Ereignisse durch, um zu sehen, welche Ausführungen gestartet worden wären, was zusammengeführt, übersprungen, in die Warteschlange gestellt oder verworfen wurde und was es pro Tag kosten würde.

Was ist trigger-rehearsal?

Trigger Rehearsal ist ein Tool zur Risikoanalyse von Ereignis-Triggern für KI-Agenten (wie Claude Code, Cursor, Codex). Es übersetzt die tatsächlichen Konfigurationen von Agent-Hubs, CI-Workflows, Cron-Jobs oder No-Code-Automatisierungen in ein einheitliches `rules.json`-Format. Anschließend führt es eine statische Analyse (Linting) durch, um häufige Fallstricke wie Endlosschleifen (Self-Loops), fehlende Sicherheitsabfragen für sensible Aktionen (z. B. Löschen, Geld ausgeben) und Überschreitung von Budgetlimits zu identifizieren. Der Kern des Tools ist die dynamische Replay-Funktion: Es spielt einen Zeitraum (z. B. einen Tag) mit realen oder synthetischen Ereignissen gegen die Regeln ab und erzeugt einen detaillierten Bericht mit einer Zeitleiste aller gestarteten, übersprungenen, in der Warteschlange gestellten oder verworfenen Ausführungen. Das Ergebnis ist ein eindeutiges Urteil: `ARM` (sicher), `TRIM` (optimierbar) oder `HOLD` (nicht aktivieren). Der Exit-Code (0, 1, 2) ermöglicht die Integration in CI/CD-Pipelines, um Konfigurationsänderungen automatisch zu prüfen. Trigger Rehearsal zielt darauf ab, teure Überraschungen durch unbedachte Trigger-Regeln zu vermeiden, bevor sie in der Produktion auftreten. Es unterstützt beliebige ereignisgesteuerte Systeme, solange die Regeln in das `rules.json`-Schema übersetzt werden können.

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

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Trigger-Probe

Was das ist

Ein Agent, der sich selbst durch Ereignisse weckt, ist nur so sicher wie seine Trigger-Regeln. Der Agent selbst kann vorsichtig sein und trotzdem das Tagesbudget verbrennen, denn das Problem sitzt meist eine Ebene höher:

  • Eine Regel reagiert auf ein Ereignis, das ihre eigene Arbeit erzeugt, und feuert deshalb immer wieder;
  • Zwei Regeln speisen sich gegenseitig über ein zweites System (der Agent kommentiert, der Kommentar wird synchronisiert, die Synchronisation löst einen Webhook aus);
  • Eine laute Quelle sendet zehn Bearbeitungen in zwei Minuten und jede startet einen neuen Durchlauf;
  • Eine Cron-Zeile, die als „ab und zu prüfen“ gedacht war, feuert 288 Mal am Tag;
  • Zwei Regeln behandeln dasselbe Ereignis und erledigen die Arbeit doppelt;
  • Eine Regel, die Geld erstattet, löscht oder Nachrichten an Personen sendet, läuft, ohne jemanden zu fragen.

Nichts davon zeigt sich, wenn du den Agenten an einem Beispiel testest. Es zeigt sich, wenn echter Datenverkehr eintrifft. Trigger-Probe lässt echten Datenverkehr frühzeitig auf dem Papier eintreffen: Du schreibst die Regeln in einem einheitlichen Format auf, spielst einen Tag oder eine Woche Ereignisse durch und liest die Zeitleiste, bevor irgendetwas scharfgeschaltet ist.

Wann verwenden

  • Bevor du eine Regel aktivierst, die es einem Agenten erlaubt, Arbeit zu starten, ohne dass eine Person eine Eingabe tippt.
  • Beim Hinzufügen einer Regel zu einer bestehenden Menge (eine neue Regel kann einen Kreislauf schließen, der vorher offen war).
  • Wenn ein Hintergrund-Agent viel häufiger oder viel seltener als erwartet lief.
  • Bei der Wahl von Entprellfenstern, Parallelitätslimits und Tagesobergrenzen, wenn du Zahlen statt Schätzungen möchtest.
  • Wenn ein Prüfer fragt: „Was passiert, wenn dieses Repository 50 Issues in einer Stunde erhält?“

Nicht für: die Überprüfung, was der Agent innerhalb eines Durchlaufs tut (das ist eine Frage zu Prompt oder Skill) oder den Lasttest der Ereignisquelle selbst.

Das Regelblatt

Alles wird in rules.json übersetzt. Halte die Übersetzung ehrlich: eine Blatt-Regel pro echter Regel, und notiere die Schutzmaßnahmen, die wirklich existieren, nicht die, die du hinzufügen möchtest.

{
  "tz": "Europe/Berlin",
  "run_s": 180,
  "external_sources": ["github"],
  "budget": {"runs_per_day": 40, "cost_per_run": 0.15, "cost_per_day": 6},
  "rules": [
    {
      "name": "triage-neues-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": "morgen-zusammenfassung", "on": {"cron": "0 9 * * 1-5"}, "max_per_day": 1}
  ]
}
FeldBedeutung
on.source + on.typesWelche Ereignisse starten die Regel. Lasse types weg, um jeden Typ von dieser Quelle zu treffen.
on.cronEine fünfstellige Cron-Zeile in der Zeitzone des Blattes. Eine Regel hat entweder source oder cron.
whereEreignisfelder, die einem Wert entsprechen (oder in einer Liste sein) müssen.
keyEreignisfeld, das das Subjekt benennt (Issue-Nummer, Ticket-ID, URL). Wird verwendet, um Wiederholungen zusammenzuführen.
debounce_sWarte nach dem letzten Ereignis für ein Subjekt diese Zeit, dann führe einmal aus.
parallelWie viele Läufe dieser Regel gleichzeitig aktiv sein dürfen. Zusätzliche Läufe warten.
max_per_dayHarte Obergrenze pro lokalem Tag. Zusätzliche Läufe werden verworfen.
run_sTypische Lauflänge, für die Warteschlange verwendet. Fallback auf den Blattwert, dann 120.
unless_actor, unless_labelSchutzmaßnahmen: Überspringe Ereignisse, die von diesen Akteuren erstellt wurden oder dieses Label tragen.
emitsEreignisse, die der Lauf selbst erzeugt (Kommentare, Labels, Statusänderungen, Folgeereignisse). Gib den Akteur und die Labels an, die sie tragen werden.
sensitive + asksAktionen, die eine Person benötigen (löschen, ausgeben, neu starten, senden). asks: true bedeutet, der Lauf stoppt und fragt zuerst.
external_sourcesQuellen, die von der Außenwelt gespeist werden. Alles andere muss von einer Regel emittiert werden.
budgetOptionale Läufe pro Tag, Kosten pro Lauf und Kosten pro Tag, die für das Urteil verwendet werden.

Schritt für Schritt

  1. Sammle die echten Regeln. Lies die tatsächliche Konfiguration, nicht die Beschreibung davon. Agent-Hub-Regeldateien, gespeicherte Routinen, CI-Workflow-on:-Blöcke, Crontab-Zeilen, No-Code-Automatisierungsbildschirme. Notiere alles, was zurück in eine Quelle schreibt, die eine andere Regel beobachtet.
  2. Übersetze in rules.json. Starte mit python3 scripts/rehearse.py new rehearsal/. Frage für jede Regel drei Fragen und fülle die Felder aus: Was weckt sie, was schreibt ein Lauf zurück, und was stoppt sie, sich durch eigene Schreibvorgänge selbst zu wecken? Wenn die Antwort auf die dritte Frage „nichts“ ist, lasse die Schutzmaßnahme weg. Die Probe soll das ja einfangen.
  3. Linten. python3 scripts/rehearse.py lint rehearsal/rules.json. Behebe jedes HOLD vor dem Abspielen; REVIEW-Elemente können bis zu den Zahlen warten.
  4. Ereignisse sammeln. Am besten: Exportiere einen echten, geschäftigen Tag aus der Quelle (Webhook-Zustellungslog, Issue-Zeitleiste, Helpdesk-Audit-Log) in events.jsonl, ein JSON-Objekt pro Zeile mit mindestens t, source, type, plus die Felder, die dein key und where verwenden. Wenn keine Historie existiert, schreibe absichtlich einen kurzen synthetischen Ausbruch: zehn Bearbeitungen in drei Minuten, zwei Subjekte gleichzeitig, ein Ereignis, das von deinem eigenen Bot erstellt wurde.
  5. Über ganze Tage abspielen. 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. Übergib --from/--to, damit die Tageszahlen nicht durch ein kurzes Fenster aufgebläht werden.
  6. Lies die Zeitleiste, nicht nur das Urteil. Suche nach Läufen zum gleichen Subjekt Minuten auseinander (fehlende oder zu kurze Entprellung), Ketten mit wachsender Tiefe (Schleifen), langen Wartezeiten (Parallelität zu niedrig), Verwerfungen (Obergrenze zu niedrig für echte Arbeit, oder ein Zeichen, dass die Regel auf Rauschen feuert).
  7. Anpassen und wiederholen. Ändere einen Knopf nach dem anderen und spiele die gleichen Ereignisse erneut ab, damit der Unterschied klar von dieser Änderung herrührt.
  8. Entscheiden. AKTIVIEREN nur, wenn die letzte Wiedergabe bei einem realistischen Tag AKTIVIEREN ergibt. Bewahre das finale rules.json, die Ereignisdatei und report.md gemeinsam als Aufzeichnung darüber auf, warum die Regeln aktiviert wurden.

Urteile

  • AKTIVIEREN: Keine HOLD- oder REVIEW-Funde. Sicher, wie geschrieben aktiviert zu werden.
  • TRIM: Etwas verschwendet Läufe oder kann Arbeit überspringen (kein key, keine Obergrenze, Überschneidung, Obergrenze hat echte Ereignisse verworfen, knapp am Budget). Nur nach dem Trimmen aktivieren, oder mit einem schriftlichen Grund.
  • HOLD: Nicht aktivieren. Selbstschleife, ungeschützter Kreislauf, eine Kette, die tiefer als Stufe 5 gelaufen ist, eine sensible Aktion ohne Nachfrage, über Budget oder eine defekte Cron-Zeile.

Der Exit-Code folgt dem Urteil (0, 1, 2; 3 bedeutet fehlerhafte Eingabe), sodass eine Probe eine Konfigurationsänderung in CI absichern kann.

Beispiel

Ein Support-Team möchte einen Agenten, der Helpdesk-Tickets beantwortet. Ihr Blatt (in examples/loopy/) hat eine Antwort-Regel, die eine Antwort postet, die das Ticket aktualisiert, was dieselbe Regel triggert. Eine Wiedergabe eines normalen Tages ergibt:

HOLD   self-loop            antworte-ticket: Eigene Ausgabe der Regel stimmt mit eigenem Trigger überein, ohne unless_actor/unless_label-Schutz
HOLD   runaway              antworte-ticket: Kette wurde immer wieder ausgelöst und überschritt Stufe 5 (3 Kürzungen)
HOLD   sensitive-unasked    rückerstattung-prüfen: Deklariert sensible Aktionen ['refund'], aber 'asks' ist nicht wahr
HOLD   over-runs-budget     -: 100.0/Tag bei einem Budget von 30/Tag
REVIEW cron-tight           posteingang-abfrage: bis zu 720 Auslösungen/Tag
VERDICT HOLD

Drei Ticket-Aktualisierungen wurden zu 18 Antwort-Läufen. Die Behebung ist klein: füge "unless_actor": ["support-bot"] zur Antwort-Regel hinzu, setze "asks": true für die Rückerstattungs-Regel und ersetze die Zwei-Minuten-Abfrage durch ein Skript, das inbox.changed nur dann emittiert, wenn sich der Posteingang wirklich geändert hat (siehe examples/loopy/rules.fixed.json). Die nächste Wiedergabe desselben Tages reduziert die Läufe von 100 auf 4 und das Urteil wird zu TRIM. Der eine verbleibende Fund ist, dass Antworten und Rückerstattungsprüfung beide ein Rückerstattungs-Ticket sehen, was hier beabsichtigt ist, also wird es mit einem einzeiligen schriftlichen Grund neben dem Bericht akzeptiert.

Tipps

  • Die beste einzelne Schleifenschutzmaßnahme ist eine Bedingung, die nach dem Lauf falsch wird: ein Label, das der Lauf hinzufügt und das die Regel ausschließt, oder ein Status, den die Regel nicht mehr matcht.
  • Systemübergreifende Schleifen sind diejenigen, die leicht übersehen werden. Wenn der Agent in System A schreibt und System A synchronisiert sich nach B, liste das synchronisierte Ereignis unter emits mit dem Akteur, den es zeigen wird.
  • Entprellung fügt absichtlich Verzögerung hinzu. Wähle das Fenster basierend darauf, wie lange eine Person braucht, um einen Bearbeitungsschub abzuschließen, und halte es kurz, wo jemand auf eine Antwort wartet.
  • Entprellung ist keine Deduplizierung von Aktionen. Für alles Unumkehrbare sollte der Lauf selbst vor dem Handeln immer noch prüfen: „Bereits erledigt?“.
  • Eine Tagesobergrenze ist eine Sicherung, kein Plan. Wenn die Wiedergabe eines normalen Tages sie erreicht, ist die Regel zu weit gefasst.
  • Pollen alle paar Minuten ist normalerweise günstiger als ein winziges Skript, das den Zustand vergleicht und bei Änderung ein Ereignis emittiert; der Agent wird nur geweckt, wenn es etwas Neues gibt.
  • Führe die Probe erneut durch, wann immer eine Regel hinzugefügt wird. Die meisten Schleifen werden durch die zweite Regel erzeugt, nicht durch die erste.

Verwandte Skills