5 Lektionen mit Implementierungsschritten, Templates und Übungen.
Ein Golf-SaaS-Ökosystem als Ursprung. Die Community-App, die Social- und Gamification-Schicht für Golfclubs, steht bei 3.001 Commits. Die Buchungs-App, eine White-Label-PWA für Kursmanagement an Golfakademien, bei 1.803 Commits. Allein über diese beiden Repositorys fast 4.800 Commits echte, inkrementelle, produktionsgetestete Arbeit. Kein Prototyp, der einen Aktivitätsschub bekam und dann verstaubte.
Würde die Geschichte hier enden, wäre es eine solide Fallstudie aus der Golfbranche und nicht mehr. Ein zweites Golf-Community-Produkt auf einem vollständig separaten Server, gebaut unter derselben Guard-Philosophie und derselben Provisioning-Disziplin, zeigt erste Portabilität. Es teilt keinen Code mit der Haupt-App, aber dieselbe Art, betrieben zu werden.
Der eigentliche Beweis kommt von außerhalb Golf. Ein Handwerksbetrieb mit einem Voice Agent und einer Website, gebaut auf demselben Server, unter exakt demselben Guard- und Automatisierungssubstrat. Die Geschäftslogik von „Soll ich einen Kundenauftrag einplanen?" hat nichts gemeinsam mit „Soll ich einem Golfer eine Stunde buchen lassen?" Die Governance-Logik darunter, die Disziplin des Prüfens vor dem Handeln, ist identisch. Ein drittes Beispiel, eine gemeinnützige Community-Plattform für einen Mitgliederverband mit 406 Commits, ohne Revenue-Motiv, bestätigt: Die Disziplin ist kein Golf-Branchen-Artefakt und kein For-Profit-Artefakt.
Was übertragbar ist, bleibt die Governance-Schicht: die Guard-Kategorien, die Dispatch-Architektur, das Self-Healing-Muster, das Self-Learning-Muster und die Provisioning-Disziplin. Nichts davon interessiert sich dafür, ob die App Golfbuchungen, Auftragsplanung oder Community-Forumsbeiträge verwaltet. Was nicht übertragbar ist, bleibt die Geschäftslogik selbst und das regulatorische Domänenwissen einer neuen Branche.
Kernaussage: Der Test für echte Branchenunabhängigkeit: Nimm die geschäftsspezifischste Regel in deinem System und frage, ob ihr Entfernen irgendetwas außerhalb dieses einen Produkts kaputt macht. Wenn ja, ist Governance mit Geschäftslogik verflochten, nicht sauber getrennt.
Jede belastbare Zahl über ein Betriebssystem stammt aus einem Skript, nicht aus der Erinnerung, nicht aus einer groben Schätzung, nicht aus einem Pitch Deck. Ein Evidenz-Sammel-Skript fragt das Live-System direkt ab: zählt Repositorys über die GitHub CLI, zählt Guard-Dateien per Dateisystem-Scan, zählt Cron-Jobs aus der echten Crontab. Immer auf dieselbe Weise, das laufende System fragen, was wirklich da ist, statt sich selbst zu fragen, was man glaubt, dass da ist.
In einem produktionsreifen Referenzsystem: 13 Produktions-Apps, 2 Server, 23 GitHub-Repositorys, 269 Guard-Dateien, 269 Hook-Skripte, 221 Cron-Jobs, 85 Autonomie-Skripte, 92 Skills, 7 MCP-Server, 16.756 Vault-Dateien als Wissensbasis, 313 Guard-Blocks in den letzten 7 Tagen, ein Entwickler. Diese Zahlen sind reproduzierbar. Ein Fremder mit demselben Skript bekäme dieselbe Antwort.
269 Guard-Dateien und Hook-Registrierungspunkte sind aus einem Grund nicht dieselbe Zahl. Ein Hook-Registrierungspunkt ist eine Stelle im Ausführungsablauf, an der das System bei hinterlegter Logik eincheckt. Ein Guard ist ein spezifisches Stück dieser Logik in einer eigenen Datei. Mehrere Guards teilen sich einen Registrierungspunkt, das Profiling-System klassifiziert Befehle und lässt nur relevante Guards feuern. 221 Cron-Jobs beantworten direkt, wie eine Person 13 Apps betreibt: Health Checks, Backup-Verifikation, Log-Review, Deploy-Monitoring sind hier geplante Jobs, keine Punkte auf einer menschlichen Aufgabenliste.
„Ein Entwickler" bedeutet präzise: Eine Person entscheidet, was gebaut wird. Eine Person ist verantwortlich, wenn etwas kaputt geht. Eine Person überprüft und genehmigt, was ein Agent vorschlägt. Null Angestellte zwischen Entscheidung und Ausführung. Der Hebel, der diesen Betrieb für eine Person möglich macht, ist nicht überdurchschnittliche Tippgeschwindigkeit, sondern die Governance-Schicht, die Ausführung an Agenten delegiert, während Verantwortlichkeit und letztes Wort vollständig bei der Person bleiben.
Kernaussage: „Viel" ist keine handlungsfähige Zahl. Du kannst nicht sagen, ob es wächst oder schrumpft, und du kannst die Behauptung gegenüber einem Kunden oder dir selbst in sechs Monaten nicht verteidigen. Baue ein Evidenz-Skript, das deine Zahlen jederzeit aus dem Live-System regeneriert.
#!/bin/bash # evidence-collect.sh: fragt das Live-System, statt zu schaetzen echo "Guard-Dateien: $(find guards/ -name '*.sh' | wc -l)" echo "Cron-Jobs: $(crontab -l | grep -cv '^#')" echo "Skills: $(find skills/ -maxdepth 1 -type d | wc -l)" echo "Repositorys: $(gh repo list --limit 1000 | wc -l)" echo "Guard-Blocks (7 Tage): $(grep -c 'BLOCKED' logs/guard-*.log)" # Ausgabe in datierte Markdown-Datei mit dem exakten Befehl, # der jede Metrik produziert hat. Reproduzierbarkeit ist der Punkt.
Ein produktionsreifes System mit 269 Guard-Dateien begann nicht als System. Es begann mit einer einzelnen Datei, dann einem Guard, dann einem zweiten Guard drei Tage später, weil der erste nicht ausreichte. Wer jetzt denkt, hunderte Guards seien nötig, bevor ein Agent an eine Codebase darf, hat den Faden verloren. Nötig sind drei, und zwar heute.
Der erste Baustein ist eine CLAUDE.md, die keine Wunschliste ist. Der häufigste Fehler ist, die Instruktionsdatei als Stimmungsdokument zu behandeln, „bitte schreib sauberen Code" statt einer harten Regel. Agenten folgen expliziten, überprüfbaren Regeln weitaus zuverlässiger als einer Tonalität. Jede Zeile sollte entweder eine harte Regel sein, die niemals gebrochen werden darf, oder ein Verweis darauf, wo spezifischere Regeln leben.
GuardRail ist ein kostenloses Open-Source-Starter-Set mit rund 20 Guards für die häufigsten Fehlermodi: Force-Pushes auf geschützte Branches, Secrets in Commits, Löschung von Dateien oder Containern ohne Bestätigung. Vor der Installation gilt: Lade eine konkret versionierte Release-Datei aus dem offiziellen Repository, prüfe Commit, Prüfsumme oder Signatur, installiere zuerst in einem Wegwerfprojekt ohne Secrets und Remotes, übernimm erst danach dieselbe geprüfte Version ins echte Repository.
Drei konkrete Guards für Tag 1: Ein Force-Push-Guard, der Force-Pushes auf geschützte Ziel-Refs blockiert. Ein Secret-Exposure-Guard, der Credential-Muster in Befehlsausgabe erkennt, bevor sie das Terminal oder einen Commit erreichen. Und ein Prod-Write-Guard, der die Zielidentität aus vertrauenswürdiger Konfiguration bezieht und jeden Schreibzugriff auf Produktionsdaten außerhalb eines autorisierten Workflows blockiert. Ein Suchmuster nach dem Wort „prod" genügt dafür ausdrücklich nicht, Aliase und anders benannte Verbindungen würden es umgehen.
Kernaussage: Jede harte Regel in der Instruktionsdatei sollte am selben Tag einen Guard hinter sich haben. Instruktion ohne Durchsetzung ist eine Wunschliste, nur als Regel verkleidet. Eine Pull-Request-Prüfung findet nach dem Force-Push statt. Ein Guard blockiert davor.
# Project Rules ### Hard Rules (non-negotiable) 1. Never run git push --force on main or master. 2. Never modify production database rows directly. Use an authorized, reviewed admin workflow. 3. Never commit files matching *.env, *credentials*, *secret*. 4. Never delete a branch, container, or database without explicit confirmation in this session. 5. Always run the test suite before proposing a commit is done. ### Workflow - Feature branches only. No direct commits to main. - Every PR needs a passing build before merge. ### Where to look first - Architecture overview: docs/ARCHITECTURE.md - Known issues and their fixes: docs/KNOWN_ISSUES.md
Ein Guard-Skript ohne Hook-Registrierung ist Papier. Die konkrete Verdrahtung hängt vom Agenten-Werkzeug ab. In Claude Code geschieht sie über die Datei .claude/settings.json, die Guard-Skripte an Lifecycle-Punkte bindet. matcher bestimmt, welches Werkzeug den Guard auslöst: Bash fängt Shell-Befehle ab, Edit und Write fangen Dateiänderungen ab. PreToolUse bedeutet vor der Ausführung, nicht danach.
Jeder Guard hat die gleiche Grundform: ein Skript, das die vorgeschlagene Aktion empfängt, sie prüft und entweder mit Exit 0 erlaubt oder mit Exit non-zero und einer klaren Nachricht blockiert. Diese mechanische Idee wurde konzeptionell nie komplizierter, sie bekam nur breitere Abdeckung und besseres Pattern-Matching.
Der häufigste Grund, warum ein Guard schweigt, ist fehlende Verdrahtung. Das Skript existiert, ist ausführbar, aber kein Hook-Eintrag zeigt darauf. Drei Prüfungen in dieser Reihenfolge: Ist das Skript ausführbar (chmod +x gesetzt)? Zeigt die Hook-Konfiguration exakt auf den richtigen Pfad, relativ zum Projektverzeichnis? Passt der Matcher zum tatsächlich genutzten Werkzeug, denn ein Bash-Matcher fängt keine Edit-Operation ab.
Es lockt, GuardRail zu installieren, die Ausgabe zu überfliegen und korrekte Verkabelung anzunehmen, weil kein Fehler kam. Das reicht nicht. Löse den Block selbst aus und beobachte ihn. Führe den Test ausschließlich mit mitgelieferten Unit-Tests oder in einem neu erzeugten, lokalen Wegwerf-Repository ohne Remote aus. Übergib dem Guard Befehlsstrings als Test-Fixtures, führe den gefährlichen Befehl niemals gegen ein echtes Repository aus.
Kernaussage: Wenn alle drei Verdrahtungsprüfungen stimmen und der Guard trotzdem schweigt, füge echo "DEBUG: guard fired for $1" >&2 als erste Zeile ins Skript ein. Siehst du die Zeile nicht, liegt das Problem in der Verdrahtung, nicht im Guard selbst.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": ".guardrail/guards/force-push-guard.sh" },
{ "type": "command", "command": ".guardrail/guards/secret-scan-guard.sh" }
]
},
{
"matcher": "Edit",
"hooks": [
{ "type": "command", "command": ".guardrail/guards/prod-write-guard.sh" }
]
}
]
}
}
# Test-Fixtures, NUR in Wegwerf-Repository ohne Remote:
# fixture 1: force push auf geschützte Ziel-Ref -> BLOCK
# fixture 2: synthetisches Token im Befehl -> BLOCK
# fixture 3: Write gegen markierte Mock-Produktion -> BLOCK
Ein System, das über fünf Anbieter und sechs Leistungsstufen routet, ist kein Tag-1-Ziel. Am ersten Tag genügen genau zwei Modelle: ein schnelles, günstiges als Standard und ein leistungsfähiges, zu dem bewusst gewechselt wird, wenn anspruchsvolles Schlussfolgern erforderlich ist, bei Architekturentscheidungen, Sicherheitsprüfungen und allem, wo Fehler teuer werden.
Der gesamte Mechanismus kann als einzelne Funktion starten, die eine Aufgabenkategorie entgegennimmt und eine Leistungsstufe zurückgibt. Absichtlich unspektakulär. Was zählt, ist die Disziplin, aus Gewohnheit aufzuhören, ein Modell per Hand auszuwählen, und stattdessen jedes Mal zu fragen: „Welche Leistungsstufe braucht diese Aufgabe wirklich?" Diese eine Frage, konsequent gestellt, bildet konzeptionell den Großteil dessen ab, was ein System mit sechs Leistungsstufen automatisch und bei höherem Volumen tut.
Vor dem ersten Aufruf gegen echten Code gehören drei Kostenhinweise dazu: Starte mit einem einzigen Anbieter und einem einzigen API-Schlüssel, Multi-Provider-Routing ist eine spätere Optimierung. Setze ein monatliches Budget und ein Rate-Limit, bevor der Agent zum ersten Mal läuft. Bewahre API-Schlüssel in einem Secret-Manager oder einer geschützten Umgebungsvariable auf, niemals im Repository, denn genau dafür existiert bereits der dritte Guard aus Lektion 18.
Drei häufige Tag-1-Fehler tauchen zuverlässig auf. Erstens, Guards zu früh zu clever machen, eine einzelne Regex für jeden möglichen Fall statt drei enger Guards für je eine Sache. Zweitens, den Test überspringen und korrekte Verkabelung nur annehmen. Drittens, harte Regeln in die Instruktionsdatei schreiben, die von nichts durchgesetzt werden, also Instruktion ohne Guard dahinter.
Kernaussage: Nichts vom Tag-1-Setup dauert mehr als einen Nachmittag. Was Monate dauert, ist alles, was sich ansammelt, sobald echte Arbeit durchläuft. Schreibe heute die fünf Aktionen auf, die wirklich wehtun würden, wenn sie unbeaufsichtigt passieren, und stelle sicher, dass jede einen getesteten Guard hat.
#!/usr/bin/env bash
# model-router.sh: wählt eine Modell-Stufe für eine Aufgabe
TASK_TYPE="$1"
case "$TASK_TYPE" in
quick|format|lint)
echo "fast-model"
;;
architecture|security|judgment)
echo "capable-model"
;;
*)
echo "fast-model"
;;
esac
# Aufrufer fordert eine Stufe an, nie einen Modellnamen direkt.
# Ein Anbieterwechsel wird so zur Ein-Zeilen-Änderung im Router.
Modul 4 abgeschlossen
Du hast jetzt: die Fallstudie der Branchenunabhängigkeit verstanden, ein reproduzierbares Evidenz-Skript für deine eigenen Zahlen gebaut, deine ersten drei Guards installiert und verdrahtet, und ein einfaches Model-Routing eingerichtet.
Weiter mit Modul 5: EU AI Act und Compliance