Überblick
failproofai besteht aus zwei unabhängigen Subsystemen:- Hook-Handler – Ein schneller CLI-Subprozess, den Claude Code bei jedem Agenten-Tool-Aufruf aufruft. Er wertet Richtlinien aus und gibt eine Entscheidung zurück.
- Agent Monitor (Dashboard) – Eine Next.js-Webanwendung zur Überwachung von Agentensitzungen und Verwaltung von Richtlinien.
~/.failproofai/ und im .failproofai/-Verzeichnis des Projekts, laufen jedoch als separate Prozesse und kommunizieren ausschließlich über das Dateisystem.
Hook-Handler
Integration mit Claude Code
Wenn Siefailproofai policies --install ausführen, schreibt es Einträge wie diese in ~/.claude/settings.json:
failproofai --hook PreToolUse als Subprozess vor jedem Tool-Aufruf auf und übergibt dabei eine JSON-Nutzlast über stdin.
Nutzlastformat
PostToolUse-Ereignissen enthält die Nutzlast zusätzlich tool_result mit der Ausgabe des Tools.
Der Handler erzwingt ein stdin-Limit von 1 MB. Nutzlasten, die dieses überschreiten, werden verworfen, und alle Richtlinien erlauben implizit.
Antwortformat
Verweigern (PreToolUse):- Exit-Code:
2 - Begründung wird in stderr geschrieben (nicht stdout)
- Exit-Code:
0 - Leeres stdout
allow(message) ermöglicht es einer Richtlinie, informativen Kontext an Claude zurückzusenden, selbst wenn die Operation erlaubt ist. Der Hook-Handler schreibt folgendes JSON auf stdout (keine Konfigurationsdatei – dies ist die Antwort des Handlers an Claude Code, genau wie deny- und instruct-Antworten oben):
- Exit-Code:
0(Operation ist erlaubt) - Wenn mehrere Richtlinien
allowmit einer Nachricht zurückgeben, werden ihre Nachrichten mit Zeilenumbrüchen zu einem einzigenadditionalContext-String zusammengefügt - Wenn keine Richtlinie eine Nachricht liefert, ist stdout leer (wie zuvor)
Verarbeitungspipeline
src/hooks/handler.ts implementiert die vollständige Pipeline:
Laden der Konfiguration
src/hooks/hooks-config.ts implementiert das dreistufige Laden der Konfiguration.
enabledPolicies– deduplizierte Vereinigung aller drei DateienpolicyParams– pro Richtlinienschlüssel gewinnt die erste Datei, die ihn definiert, vollständigcustomPoliciesPath– die erste Datei, die diesen Wert definiert, gewinntllm– die erste Datei, die diesen Wert definiert, gewinnt
readHooksConfig() (nur global) zum Lesen und Schreiben, da es nicht mit einem Projekt-cwd aufgerufen wird.
Richtlinienauswertung
src/hooks/policy-evaluator.ts führt Richtlinien der Reihe nach aus.
Für jede Richtlinie:
- Das
params-Schema der Richtlinie nachschlagen (falls vorhanden). policyParams[policy.name]aus der zusammengeführten Konfiguration lesen.- Benutzerdefinierte Werte über die Schema-Standardwerte legen, um
ctx.paramszu erzeugen. policy.fn(ctx)mit dem aufgelösten Kontext aufrufen.- Ist das Ergebnis
deny, sofort abbrechen und diese Entscheidung zurückgeben. - Ist das Ergebnis
instruct, die Nachricht sammeln und fortfahren. - Ist das Ergebnis
allow, zur nächsten Richtlinie übergehen.
- Wurde ein
denyzurückgegeben, die deny-Antwort ausgeben. - Wurden
instruct-Rückgaben gesammelt, eine einzelne instruct-Antwort mit allen zusammengefügten Nachrichten ausgeben. - Andernfalls eine allow-Antwort ausgeben (leeres stdout, Exit-Code 0).
Eingebaute Richtlinien
src/hooks/builtin-policies.ts definiert alle 39 eingebauten Richtlinien als BuiltinPolicyDefinition-Objekte:
params akzeptieren, deklarieren ein PolicyParamsSchema mit Typen und Standardwerten für jeden Parameter. Der Richtlinienauswerter fügt aufgelöste Werte in ctx.params ein, bevor fn aufgerufen wird. Richtlinienfunktionen lesen ctx.params ohne Null-Prüfung, da Standardwerte immer zuerst angewendet werden.
Die Mustererkennung innerhalb von Richtlinien verwendet geparste Befehlstoken (argv), keine reine Zeichenkettensuche. Dies verhindert Umgehungsversuche durch Shell-Operator-Injektion (z. B. kann ein Muster für sudo systemctl status * nicht durch Anhängen von ; rm -rf / an den Befehl umgangen werden).
Benutzerdefinierte Richtlinien
src/hooks/custom-hooks-registry.ts implementiert eine globalThis-basierte Registrierung:
src/hooks/custom-hooks-loader.ts lädt die Richtliniendatei des Benutzers:
customPoliciesPathaus der Konfiguration lesen; überspringen, falls nicht vorhanden.- Auf absoluten Pfad auflösen; prüfen, ob die Datei existiert.
- Alle
from "failproofai"-Importe zum tatsächlichen dist-Pfad umschreiben, damitcustomPoliciesauf dieselbeglobalThis-Registrierung verweist. - Transitive lokale Importe rekursiv umschreiben, um ESM-Kompatibilität sicherzustellen.
- Temporäre
.mjs-Dateien schreiben und die Einstiegsdatei perimport()laden. getCustomHooks()aufrufen, um registrierte Hooks abzurufen.- Alle temporären Dateien in einem
finally-Block bereinigen.
~/.failproofai/hook.log protokolliert und der Loader gibt ein leeres Array zurück. Eingebaute Richtlinien sind nicht betroffen.
Benutzerdefinierte Richtlinien werden nach allen eingebauten Richtlinien ausgewertet. Ein deny einer benutzerdefinierten Richtlinie bricht weitere benutzerdefinierte Richtlinien ab (alle eingebauten wurden jedoch zu diesem Zeitpunkt bereits ausgeführt).
Aktivitätsprotokollierung
Nach jedem Hook-Ereignis hängt der Handler eine JSONL-Zeile an~/.failproofai/hook-activity.jsonl an:
Dashboard-Architektur
Das Dashboard ist eine Next.js 16-Anwendung, die den App Router mit React Server Components und Server Actions verwendet.- Seitenkomponenten rufen
lib/projects.tsundlib/log-entries.tsauf, um Projekt-/Sitzungsdaten direkt aus dem Dateisystem zu lesen (keine API-Schicht für Lesezugriffe). - Die Policies-Seite verwendet Server Actions für alle Mutationen (Umschalten, Parameter-Aktualisierung, Installieren/Entfernen).
- Der Sitzungsbetrachter parst das JSONL-Transkriptformat von Claude und rendert eine Zeitleiste mit Nachrichten und Tool-Aufrufen.
- Keine Datenbank – alle persistenten Zustände liegen in einfachen Dateien (
~/.failproofai/,~/.claude/projects/). - Server Actions für Mutationen – kein REST-API für CRUD-Operationen erforderlich.
- React Server Components für Leseseiten – schnelleres erstes Laden, kein Client-Bundle für das Datenabrufen.
- Client-Komponenten nur dort, wo Interaktivität benötigt wird (Richtlinien-Umschalter, Aktivitätssuche, Log-Betrachter).

