Wie Agents Never Sleep funktioniert
Ein Durchgang durch einen unbeaufsichtigten Lauf, von Anfang bis Ende — der Mechanismus, kein Verkaufsgespräch.
Definition
Was ist unbeaufsichtigte Agent-Ausführung?
Unbeaufsichtigte Agent-Ausführung bedeutet, dass ein Coding-Agent einen Ticket-Backlog abarbeitet, ohne dass jemand jeden Schritt beobachtet — kein Mensch anwesend, um eine klärende Frage zu beantworten. Das funktioniert nur, wenn der Agent eine feste Regel dafür hat, was er tut, sobald er unsicher ist: annehmen und weitermachen, diese eine Entscheidung aufschieben und zum nächsten Ticket übergehen, oder den gesamten Lauf stoppen. Agents Never Sleep (ANS) ist die Governance-Schicht, die diese Regel als dauerhaften, durchgesetzten Vertrag liefert, damit ein mehrdeutiges Ticket um 2 Uhr morgens nie die anderen neununddreißig einfriert.
1. Start-Preflight — bevor auch nur ein Token ausgegeben wird
Ein Headless-Lauf startet über den Launcher (bin/ans-run), ein deterministisches GO/NO-GO-Gate, das vor dem Start der Agent-CLI läuft — denn bis die eigenen Preflight-Checks des Agents laufen, sind die ersten Tokens bereits für einen möglicherweise zum Scheitern verurteilten Lauf ausgegeben.
Der Launcher prüft, in dieser Reihenfolge: Config-Vertrauen (die Datei .claude/agents-never-sleep.json des Repos muss einmal pro Nutzer explizit vertraut sein, verknüpft über ihren SHA-256-Wert — eine neue oder geänderte Konfiguration ohne jemanden in der Nähe zur Freigabe ist ein NO-GO); Identität (ein konfigurierter Zielnutzer, niemals ein unbeaufsichtigter Lauf, der als root weiterläuft); Agent-Auswahl (ein benannter Preset, verifiziert mit einer echten --version-Abfrage, damit Flag-Drift vor der Ausgabe erkannt wird, nicht danach); und eine Sperre auf dem Arbeitsverzeichnis — ein nicht blockierendes flock(2), sodass zwei gleichzeitige Starts auf demselben Repo immer genau einen Gewinner ergeben, automatisch vom Kernel bei jedem Absturz freigegeben.
Exit-Codes sind eindeutig: 0 gestartet, 64 NO-GO, 65 das Arbeitsverzeichnis ist bereits belegt. Autonomie-Flags — der Permission-Modus, der einen abgekoppelten Lauf tatsächlich ohne Hängenbleiben an einer Freigabeaufforderung fortsetzen lässt — sind nie ein Standard; ein Preset wird erst startfähig, sobald ein Mensch genau bestätigt hat, was dieses Flag gewährt.

2. Die Zustandsmaschine pro Ticket
Sobald der Lauf läuft, treibt der Agent eine Zwei-Befehl-Schleife gegen den Harness an: next fragt nach einem Ticket zum Bearbeiten, complete hält fest, was passiert ist. Jeder Aufruf ist ein frischer Subprozess über dauerhaftem, atomar geschriebenem Zustand — ein Absturz zwischen den beiden verliert nichts, weil nichts nur im Speicher lebt.
Jedes Ticket endet in genau einem von sieben Ergebniszuständen, so gewählt, dass die Reaktion am nächsten Morgen nie mehrdeutig ist:
- DONE — umgesetzt, deterministisches Gate grün.
- DONE_LOW_CONFIDENCE — Gate grün, aber die delegierte Prüfung eines risikoreichen Diffs äußerte Bedenken, schlug fehl oder lief nie; braucht Tageslicht-Prüfung.
- PARKED_DECISION — eine Entscheidung an einen Menschen delegiert; der Lauf ging weiter.
- PARKED_FOUNDATIONAL — eine grundlegende Unklarheit; abhängige Tickets werden bis zur Klärung unter Quarantäne gestellt.
- BLOCKED_ENV — die Umgebung blockierte den Fortschritt (eine Git-Sperre, ein nicht ausführbares Gate) — nicht die Schuld des Agents.
- FAILED_RETRYABLE — ein Gate fing einen Bug ab, den der Diff eingeführt hat; die Änderung wurde rückgängig gemacht; sicher, es erneut zu versuchen.
- FAILED_BUG_IN_AGENT — wiederholte Fehler deuten auf ein systematisches Problem hin; braucht einen menschlichen Blick.
3. Entscheiden — dann erst umsetzen
Bevor eine Datei angefasst wird, klassifiziert der Harness den Blast Radius des Tickets und entscheidet PROCEED, PARK oder HALT. Nur ein PROCEED-Ticket erreicht den Agenten zur Umsetzung; ein PARK wird vor jeder Änderung festgehalten, denn die Entscheidung selbst ist das Arbeitsergebnis.
Sobald ein PROCEED-Ticket übergeben wird, bearbeitet der Agent — der Ausführende in diesem Design — genau die Dateien dieses einen Tickets. Der Harness sichert zuerst das Arbeitsverzeichnis, damit alles, was der Agent tut, rückgängig gemacht werden kann.

4. Das deterministische Gate — die einzige harte Sperre
Ein Gate ist ein Shell-Befehl — deine Testsuite —, der nach der Änderung läuft. Exit 0 ist grün; ungleich null ist rot. Das ist das Einzige im gesamten Lauf, das ein Ticket hart blockieren kann; alles andere (eine delegierte Modellprüfung, ein Fachblick) ist beratend und kann nur einen Vertrauensstempel verweigern, niemals Arbeit rückgängig machen oder den Lauf stoppen.
Ein rotes Gate wird klassifiziert, nicht nur gemeldet: Ein Fehler, der eindeutig vom Diff eingeführt wurde, wird auf den letzten grünen Commit zurückgesetzt und als FAILED_RETRYABLE festgehalten; ein Fehler, der vorbestehend, flaky oder umgebungsbedingt wirkt, senkt das Vertrauen, behält aber die Arbeit; ein Gate, das gar nicht laufen kann (eine Sperre, ein Timeout, eine nicht interaktiv beantwortbare Eingabeaufforderung), wird als BLOCKED_ENV festgehalten — nie ein stiller Stopp. ANS löscht oder überspringt niemals einen fehlschlagenden Test, um Grün zu erzwingen.
---
id: fix-flaky-webhook-retry
title: Retry webhook delivery on 5xx with backoff
blast_radius: medium # optional hint — the harness auto-classifies from the diff
gate: pytest tests/webhooks/ -x
---
The webhook sender should retry on 5xx responses with exponential backoff
(max 3 attempts). Cover it with a test that simulates two 500s then a 200.
Illustratives Beispiel — ein Ticket ist eine Markdown-Datei mit einem optionalen YAML-Front-Matter-Block; der Text selbst ist der einzige Pflichtteil, und gate benennt den Befehl, der über Erfolg oder Misserfolg dieses Tickets entscheidet.
5. ASK / PARK / HALT — die Entscheidungspunkte
Drei unterschiedliche Reaktionen auf Unsicherheit, nie zu einer zusammengefasst. ASK ist verboten, sobald ein Lauf unbeaufsichtigt ist — es ist niemand da, um zu antworten, also wird es automatisch zu PARK. Damit bleiben zwei echte Optionen:
- PARK — dieses eine Ticket oder diese Entscheidung aufschieben und direkt zum nächsten unabhängigen Ticket übergehen. Das ist normal und gesund, kein Stopp. Ein Park hält immer fest, warum, welche Interpretationen infrage kommen, und die genaue menschliche Entscheidung, die am nächsten Morgen wartet. Echte Beispiele für ein Hard-PARK: in welche Richtung eine Datenbankmigration gehen soll, eine Änderung an einem öffentlichen oder gemeinsam genutzten API-Vertrag, alles, was eine Sicherheits- oder Mandantentrennungsgrenze berührt, und alles rund um Geld, Abrechnung oder Preisgestaltung.
- HALT — den gesamten Lauf stoppen. Reserviert für wirklich irreversible Gefahr ohne jedes Sicherheitsnetz — zum Beispiel keine Versionskontrolle vorhanden und auch keine, die sich anlegen ließe. HALT ist bewusst selten; die meiste Unsicherheit ist ein PARK, kein HALT.
Die Disziplin hinter der Wahl ist der Blast Radius: Benennung, interne Struktur, Log-Formulierung oder eine Wahl zwischen zwei gleichwertigen lokalen Implementierungen dürfen PROCEEDen (annehmen, loggen, weitermachen, reversibel). Alles mit großem Blast Radius, oder alles wirklich nicht Klassifizierbare, wird zurückgestellt. Ein falsch zurückgestelltes kleines Item kostet eine Fünf-Sekunden-Entscheidung am Morgen; eine falsch angenommene große Sache kostet eine Nacht falscher Arbeit in die falsche Richtung.

6. Der Watchdog — Einfrieren, dann ein fortsetzbarer Neustart
Ein Hänger ist ein anderer Fehlertyp als ein Stopp: Der Prozess lebt, tut aber nichts, und kein Hook, der auf einen vorzeitigen Stopp achtet, kann das erkennen. Eine anhaltende Provider-Überlastungswelle ist die realistische Ursache — der Lauf ist noch da, aber sein Heartbeat ist veraltet.
Der Watchdog ist ein Sidecar, der den unbeaufsichtigten Befehl als Kindprozess ausführt und dessen Heartbeat-Datei abfragt. Sobald der Heartbeat eine konfigurierte Schwelle überschreitet, beendet er den Kindprozess und startet ihn neu — und weil der ANS-Zustand dauerhaft ist, setzt der Neustart genau dort fort, wo der Lauf war; die teilweisen Änderungen des laufenden Tickets werden auf seinen letzten Snapshot zurückgesetzt, sodass nichts verloren geht oder doppelt gezählt wird. Nach einer begrenzten Anzahl Neustarts löst er einen Alarm aus und beendet sich, statt endlos neu zu starten. ans-run umschließt jeden abgekoppelten Start standardmäßig mit dem Watchdog.
Derselbe Sidecar räumt auch seine eigenen verwaisten Kindprozesse auf — etwa einen MCP-Server, den der Agent gestartet und nie beendet hat — streng nach Eltern-Kette-Abstammung von der eigenen Prozess-ID des Laufs, nie durch Abgleich eines Prozessnamens (ein Namensabgleich könnte einen unabhängigen Lauf auf derselben Maschine beenden). Ehrliche Grenze: Wird der Supervisor selbst zwangsweise beendet, kann er danach nicht mehr aufräumen — das reduziert Prozess-Leckage, beseitigt sie aber nicht.
7. Drain — weiterlaufen, bis nichts mehr zu tun ist
Der Agent ruft weiter next und dann complete auf, bis next einen Endstatus zurückgibt: DRAINED (der Backlog ist leer), HALTED (eine HALT-Bedingung ist eingetreten), oder LOW_YIELD (ein Circuit Breaker hat ausgelöst, weil die meisten letzten Tickets zurückgestellt oder blockiert werden, statt abgeschlossen zu werden — ein Signal, dass der Backlog selbst einen menschlichen Blick braucht, keine weiteren Versuche). Versuchs- und Schleifenobergrenzen zwingen jedes einzelne Ticket, das sonst den ganzen Lauf aufzehren würde, zu einem Park, damit ein verfluchtes Item nicht genau das Scheitern wiederholen kann, das dieses ganze Design vermeiden soll.
8. Der Morgenreport
Wenn der Lauf endet, schreibt er einen einzigen geordneten Report (night-report.md), statt dich das Geschehene aus Logs rekonstruieren zu lassen. Er nennt: was erledigt und vertrauenswürdig ist, was erledigt ist, aber Tageslicht-Prüfung braucht (eine risikoreiche Änderung, die die delegierte Prüfung nicht freigegeben hat), was zurückgestellt ist — jeweils mit den infrage kommenden Interpretationen und der genauen nächsten Aktion —, was durch die Umgebung blockiert ist, und etwaige blinde Flecken: eine abgeschwächte Garantie, eine nicht verfügbare Fähigkeit, ein Credential, das der Lauf nicht lesen konnte. Eine Nacht mit geringer Ausbeute wird im Report deutlich markiert, damit „der Lauf ist fertig“ nie mit „die Arbeit ist erledigt“ verwechselt wird.