GateGuard — Fakten-erzwingendes Pre-Action-Tor
Ein PreToolUse-Hook, der Claude zwingt, vor dem Editieren zu recherchieren. Statt Selbstbewertung („Bist du sicher?“) werden konkrete Fakten gefordert. Der Akt der Untersuchung schafft ein Bewusstsein, das Selbstbewertung nie erreicht hat.
Wann aktivieren
- Arbeiten an einer Codebasis, bei der Dateiänderungen mehrere Module betreffen
- Projekte mit Datendateien, die bestimmte Schemata oder Datumsformate haben
- Teams, bei denen KI-generierter Code zu bestehenden Mustern passen muss
- Jeder Workflow, bei dem Claude eher rät als untersucht
Kernkonzept
LLM-Selbstbewertung funktioniert nicht. Frage „Hast du gegen Richtlinien verstoßen?“ und die Antwort ist immer „Nein.“ Dies ist experimentell bestätigt.
Aber die Frage „Liste alle Dateien auf, die dieses Modul importieren“ zwingt das LLM, Grep und Read auszuführen. Die Untersuchung selbst schafft Kontext, der die Ausgabe verändert.
Dreistufiges Tor:
1. VERWEIGERN — blockiere den ersten Edit/Write/Bash-Versuch
2. ERZWINGEN — sage dem Modell genau, welche Fakten es sammeln soll
3. ERLAUBEN — erlaube den Wiederholungsversuch nach Vorlage der Fakten
Kein Wettbewerber tut alle drei. Die meisten hören beim Verweigern auf.
Nachweise
Zwei unabhängige A/B-Tests, identische Agenten, gleiche Aufgabe:
| Aufgabe | Mit Tor | Ohne Tor | Abstand |
|---|---|---|---|
| Analytics-Modul | 8,0/10 | 6,5/10 | +1,5 |
| Webhook-Validator | 10,0/10 | 7,0/10 | +3,0 |
| Durchschnitt | 9,0 | 6,75 | +2,25 |
Beide Agenten produzieren Code, der läuft und Tests besteht. Der Unterschied ist die Designtiefe.
Tortypen
Edit / MultiEdit-Tor (erster Edit pro Datei)
MultiEdit wird identisch behandelt — jede Datei im Batch wird einzeln getorct.
Vor dem Editieren von {dateipfad} präsentiere diese Fakten:
1. Liste ALLE Dateien auf, die diese Datei importieren/benötigen (durchsuche den Baum — Glob/Grep, oder find/grep via Bash)
2. Liste die öffentlichen Funktionen/Klassen auf, die von dieser Änderung betroffen sind
3. Wenn diese Datei Datendateien liest/schreibt, zeige Feldnamen, Struktur
und Datumsformat (verwende geschwärzte oder synthetische Werte, keine rohen Produktionsdaten)
4. Zitiere die aktuelle Benutzeranweisung wörtlich
Write-Tor (erste neue Datei)
Vor dem Erstellen von {dateipfad} präsentiere diese Fakten:
1. Nenne die Datei(en) und Zeile(n), die diese neue Datei aufrufen werden
2. Bestätige, dass keine bestehende Datei denselben Zweck erfüllt (durchsuche den Baum — Glob/Grep, oder find/grep via Bash)
3. Wenn diese Datei Datendateien liest/schreibt, zeige Feldnamen, Struktur
und Datumsformat (verwende geschwärzte oder synthetische Werte, keine rohen Produktionsdaten)
4. Zitiere die aktuelle Benutzeranweisung wörtlich
Destruktives Bash-Tor (jedes destruktive Kommando)
Auslöser: rm -rf, git reset --hard, git push --force, drop table, usw.
1. Liste alle Dateien/Daten auf, die dieses Kommando ändern oder löschen wird
2. Schreibe eine einzeilige Rollback-Prozedur
3. Zitiere die aktuelle Benutzeranweisung wörtlich
Routine-Bash-Tor (einmal pro Sitzung)
1. Die aktuelle Benutzeranfrage in einem Satz
2. Was dieses spezifische Kommando überprüft oder erzeugt
Parallele Batches und teilweise Anwendung
Das Erstkontakt-Tor bewertet jeden Tool-Aufruf unabhängig. Wenn mehrere Edits an einer Datei, die noch nicht berührt wurde, in einem parallelen Batch gesendet werden, wird der erste Aufruf verweigert und die Verweigerung markiert die Datei als geprüft, sodass die Geschwister-Edits in diesem Batch angewendet werden. Es wird nichts zurückgesetzt: Die Datei kann die Geschwister-Edits ohne den verweigerten enthalten.
Die Verweigerungsnachricht nennt die Datei und warnt, dass Batch-Geschwister bereits angewendet worden sein könnten. Behandle es wörtlich:
- Sende abhängige Edits an eine noch nicht berührte Datei sequenziell, nicht in einem parallelen Batch. Eine Definition und ihre erste Verwendung, oder ein Import und seine Aufrufstelle, dürfen nicht im selben Batch reisen.
- Stelle nach einer Erstkontakt-Verweigerung die Fakten dar, wiederhole den verweigerten Edit und lies die Datei erneut, bevor du auf etwas anderem aus dem Batch aufbaust.
Eine batchweite Sperre ist nicht möglich: Hooks sehen Tool-Aufrufe einzeln, daher kann das Tor nicht wissen, welche Aufrufe gleichzeitig eingetroffen sind.
Schnellstart
Option A: Den ECC-Hook verwenden (keine Installation)
Der Hook unter scripts/hooks/gateguard-fact-force.js ist in diesem Plugin enthalten. Aktiviere ihn über hooks.json.
Wenn GateGuard Setup- oder Reparaturarbeit blockiert, starte die Sitzung mit
ECC_GATEGUARD=off. Für Hook-Level-Steuerung verwende weiterhin
ECC_DISABLED_HOOKS mit der GateGuard-Hook-ID.
In langen Sitzungen geben nur die ersten GATEGUARD_FACT_FORCE_FULL_DENIALS
Fakten-erzwingende Verweigerungen (Standard: 3) den vollständigen Vier-Fakten-Block aus;
spätere Verweigerungen werden auf eine einzelne Zeile mit der Verweigerungsnummer
reduziert, damit nahezu identische Blöcke nicht den Kontextfenster füllen und
Wiederholungsschleifen des Modells verstärken (#2142). Die Wiederholung derselben
Datei oder desselben Befehls nach Vorlage der Fakten löst das Tor nie erneut aus.
Abgestufte Steuerungen
ECC_GATEGUARD=off (oder GATEGUARD_DISABLED=1) schaltet das Tor vollständig aus.
Die Variablen in dieser Tabelle tun dies nicht — jede schränkt ein Verhalten ein,
während die lasttragenden destruktiven Bash-Prüfungen weiterlaufen:
| Variable | Standard | Effekt |
|---|---|---|
GATEGUARD_BASH_ROUTINE_DISABLED | nicht gesetzt (Tor an) | Deaktiviert nur das Routine-Bash-Tor. Das destruktive Bash-Tor (rm -rf, git reset --hard, drop table, dd if=, …) bleibt unberührt. |
GATEGUARD_EXEMPT_GLOBS | nicht gesetzt (keine Ausnahmen) | Kommagetrennte Globs; ein passendes Edit/Write/MultiEdit-Ziel überspringt die Erstkontakt-Fakten-Erzwingung. Gedacht für Bäume mit geringem Importwert (Tests, generierte Artefakte, Scratch-Verzeichnisse), bei denen „wer importiert dies / welches Schema“ kein Signal liefert. |
GATEGUARD_FACT_FORCE_FULL_DENIALS | 3 | Wie viele Verweigerungen den vollständigen Vier-Fakten-Block ausgeben, bevor spätere auf eine einzelne Zeile kondensieren. 0 kondensiert ab der allerersten Verweigerung. |
GATEGUARD_BASH_EXTRA_DESTRUCTIVE | nicht gesetzt | Zusätzliche destruktive Kommandomuster als Regex-Quelltext, die zum integrierten Satz hinzugefügt werden. Eine fehlerhafte Regex wird als nicht gesetzt behandelt (integrierte gelten weiterhin) und einmalig nach stderr protokolliert. |
GATEGUARD_STATE_DIR | ~/.gateguard | Wo der sitzungsbezogene Tor-Zustand gespeichert wird. Wenn der Zustand nicht persistiert werden kann, erlaubt das Tor die Operation, anstatt zu schleifen, und nennt diese Variable in der Warnung. |
GATEGUARD_BASH_ROUTINE_DISABLED akzeptiert 1, true, on, enabled,
enable oder yes (Groß-/Kleinschreibung und Leerzeichen werden ignoriert); jeder
andere Wert belässt das Tor an.
Das Tor vollständig ausschalten
| Variable | Effekt |
|---|---|
ECC_GATEGUARD=off | Deaktiviert GateGuard für die Sitzung. Akzeptiert 0, false, off, disabled oder disable. |
GATEGUARD_DISABLED=1 | Gleicher Effekt. Erkennt nur 1 — die obigen Schreibweisen gelten hier nicht. |
Für Hook-Level-Steuerung verwende weiterhin ECC_DISABLED_HOOKS mit der GateGuard-Hook-ID.
Glob-Semantik für GATEGUARD_EXEMPT_GLOBS
Muster stimmen mit dem gesamten projektrelevanten Zielpfad überein. Das Projektstammverzeichnis
ist CLAUDE_PROJECT_DIR, fallback auf das cwd des Hook-Payloads, dann das Arbeitsverzeichnis
des Hook-Prozesses. Relative Globs befreien niemals Ziele außerhalb dieses Stammverzeichnisses.
Explizite absolute Globs stimmen mit dem gesamten absoluten Zielpfad überein und können
absichtlich Pfade außerhalb des Projekts befreien.
Sowohl Muster als auch Pfade verwenden /-Trennzeichen und Abgleich in Kleinschreibung. *
stimmt innerhalb eines Segments, ** segmentübergreifend und ? für ein Nicht-Trennzeichen.
**/ schließt null Verzeichnisse ein, daher stimmt **/tests/** auch mit tests/foo.js überein.
Fehlerhafte Muster werden verworfen, ohne eine Ausnahme zu gewähren.
Seit 2.2.1 deckt services/** nur den Services-Baum des Projekts ab, und
*.md nur seine Markdown-Dateien im Stamm. Verwende **/*.md für alle Markdown-Dateien
innerhalb des Projekts. Bestehende unverankerte Ausnahmen müssen möglicherweise angepasst werden:
{
"env": {
"GATEGUARD_BASH_ROUTINE_DISABLED": "1",
"GATEGUARD_EXEMPT_GLOBS": "**/tests/**,tests/**,**/*.test.*,**/docs/**,**/dist/**"
}
}
Option B: Vollständiges Paket mit Konfiguration
pip install gateguard-ai
gateguard init
Dies fügt .gateguard.yml für projektspezifische Konfiguration hinzu (benutzerdefinierte Nachrichten, Ignorierpfade, Tor-Umschalter).
Anti-Patterns
- Verwende stattdessen keine Selbstbewertung. „Bist du sicher?“ bekommt immer „Ja.“ Dies ist experimentell bestätigt.
- Überspringe nicht die Datenschema-Prüfung. Beide A/B-Test-Agenten nahmen ISO-8601-Daten an, wenn reale Daten
%Y/%m/%d %H:%Mverwendeten. Die Überprüfung der Datenstruktur (mit geschwärzten Werten) verhindert diese gesamte Fehlerklasse. - Tore nicht jeden einzelnen Bash-Befehl. Routine-Bash torct einmal pro Sitzung. Destruktives Bash torct jedes Mal. Diese Balance vermeidet Verlangsamung, während echte Risiken abgefangen werden.
Best Practices
- Lasse das Tor natürlich auslösen. Versuche nicht, die Tor-Fragen vorab zu beantworten — die Untersuchung selbst ist es, die die Qualität verbessert.
- Passe die Tor-Nachrichten an deine Domäne an. Wenn dein Projekt spezifische Konventionen hat, füge sie den Tor-Aufforderungen hinzu.
- Verwende
.gateguard.yml, um Pfade wie.venv/,node_modules/,.git/zu ignorieren.
Verwandte Skills
safety-guard— Laufzeit-Sicherheitsprüfungen (komplementär, nicht überschneidend)code-reviewer— Post-Edit-Review (GateGuard ist Pre-Edit-Untersuchung)