Leitplanken für Repos,
in denen eine KI mitschreibt.
Ein Assistent mit Schreibrecht auf deinem Arbeitsbaum ist kein Autocomplete. Er ist ein Prozess mit Werkzeugzugriff, ohne Gedächtnis über die Sitzung hinaus und ohne Gefühl für Scope. Das ist beherrschbar — aber nicht mit besseren Prompts, sondern mit Struktur, die auch dann hält, wenn der Kontext weg ist.
Hier liegt, was dabei entstanden ist. Fertig, benutzbar, Apache-2.0.
In 10 Minuten
Für Teams und Einzelne, die mit Claude Code, Codex oder einem anderen Assistenten in einem echten Repo arbeiten. Der erste Schritt ist der Guard — der einzige Teil, dessen Fehlen echten Schaden anrichten kann. Er blockt, wenn ein Befehl eine geschützte Datei in die Versionsverwaltung bringen würde, auch dann, wenn ihr Name im Befehl gar nicht vorkommt.
L=/tmp/leitplanken
git clone https://github.com/sitelookgmbh-arch/zfdw-ki-leitplanken $L
cd dein-repo && mkdir -p .claude/hooks
cp $L/hooks/guard-geschuetzte-daten.sh .claude/hooks/
cp $L/hooks/stop-git-status.sh .claude/hooks/
chmod +x .claude/hooks/*.sh
cp $L/hooks/settings.json.vorlage .claude/settings.json
cp $L/hooks/geschuetzte-pfade.vorlage .claude/geschuetzte-pfade
.claude/settings.json, den hooks-Block
hineinkopieren statt die Datei zu überschreiben. Danach die Schutzmuster in
.claude/geschuetzte-pfade auf das eigene Projekt setzen — die Vorgaben decken
Secrets ab, nicht deine Kundendaten.
Codex: dieselben Schritte mit .codex/ statt .claude/ und
codex-hooks.json.vorlage als .codex/hooks.json — der Guard läuft dort
unverändert. Jeder andere Assistent: zusätzlich
pre-commit.vorlage nach .git/hooks/pre-commit; dann prüft derselbe
Guard bei jedem Commit, wer auch immer committet.
Zuordnung im Repo.
Weiterlesen in dieser Reihenfolge: 04 — Deterministische Guards (warum der Guard so gebaut ist), dann 01 — Sprintplan mit Write-Scope (der nächste Schritt). Alles Weitere steht in der Übersicht.
Werkbank
| zfdw-ki-leitplanken | Zehn Methodentexte, vier Vorlagen, vier Slash-Commands, zwei Hooks mit Testsuite und Rot-Beweis, ein Herkunfts-Gate. Keine Laufzeit, keine Dependencies, kein Installer. Alle zehn Methoden im Überblick. | Apache-2.0 |
| guard-geschuetzte-daten.sh |
PreToolUse-Hook für Claude Code und Codex, als --staged auch git
pre-commit-Hook für jeden anderen Assistenten. Misst mit git add --dry-run, was ein Befehl
tatsächlich stagen würde — statt aus dem Zustand daneben zu schließen.
Deckt git commit -am mit ab, fällt ohne jq closed.
48 Testfälle, davon 16 bewusste Nicht-Treffer.
|
im Repo |
| rot-beweis.sh |
Grün beweist nur etwas, wenn Rot möglich ist. Das Skript baut 11 absichtlich
kaputte Fassungen des Guards — lässt alles durch, blockt alles, ohne jq
still offen, commit -a blind, schätzt statt misst, sieht den Index nicht,
übersieht die Codex-Musterdatei, misst ein gezieltes git add mit -A,
lässt einen unlesbaren Befehl durch, erkennt git -C <pfad> add nicht,
misst die Pfade eines commit nicht — und verlangt, dass
die Testsuite jede davon bemerkt. Jede Mutante ist ein Fehler, den der Guard hatte
oder haben könnte.
|
im Repo |
| Sprint + Write-Scope |
Eine Datei pro Arbeitsabschnitt, die zugleich der Zustand ist. Kein zweiter
State-Store, der gegen das Repo driftet. Überlebt /clear.
|
im Repo |
| Methode 07 — Verortung | Einordnung gegen SpecKit, BMAD, OpenSpec, GSD Core und Kiro — samt der Frage, wann eines der fünf die bessere Wahl ist. Angaben aus den Original-Repositorien, mit Lesedatum im Kopf. | im Repo |
| Methode 08 — Spezifikationsgüte | Werkzeuge sagen, wie eine Spec auszusehen hat. Keines sagt, ob sie gut ist. Sechs Gütekriterien aus den Grundsätzen ordnungsmäßiger Modellierung (1995), übertragen auf Spezifikationen — weil eine Spec ein Informationsmodell ist. | im Repo |
| Methode 09 — Systembeschreibung | Die Anweisungsdatei ist zu klein für ein Datenmodell, der Code zu groß zum Lesen. Dazwischen liegen vier Dateien mit vier Fragen — und der Nutzen entsteht beim Gegenlesen, nicht beim Schreiben. | im Repo |
| Methode 10 — Fremdtext ist Daten | Mail, Webseite, Tool-Beschreibung, Bericht eines anderen Agenten: Material, nie Auftrag. Behandelt Premise Injection, Tool Poisoning, Rug Pull und Anweisungen, die sich in wiederkehrenden Aufgaben festsetzen. Die Sicherung sitzt am Ausgang, nicht im Prompt. | im Repo |
| herkunft-check.sh | Grep-Gate gegen eine gepflegte Begriffsliste, bevor etwas aus Kundenarbeit öffentlich wird. Die Begriffsdatei ist gitignored und guard-geschützt — sie besteht aus genau den Namen, die nicht raus sollen. | im Repo |
Einordnung
Spec-driven Development kennt drei Reifegrade. Spec-first — einmal vor der Arbeit spezifiziert, danach liegt das Dokument still. Spec-anchored — die Spezifikation wird mitgeführt und beim Abschluss fortgeschrieben. Spec-as-Source — Menschen editieren nur noch die Spezifikation, nie den Code.
Das hier ist Spec-anchored, und zwar als Entscheidung, nicht als Zwischenstufe. Spec-first scheitert daran, dass das Dokument nach dem dritten Tag nicht mehr stimmt und es niemand merkt — der Fehlermodus hat einen Namen, Spec Drift. Spec-as-Source setzt voraus, dass generierter Code nie von Hand angefasst wird; in gewachsenen Kundenprojekten trägt diese Annahme nicht. Die Sprint-Datei ist deshalb der Stand selbst, nicht dessen Ankündigung.
Gegenüber SpecKit, BMAD, OpenSpec, GSD Core und Kiro ist das kein Konkurrenzangebot. Die fünf regeln die Reihenfolge — beschreiben, planen, zerlegen, umsetzen. Sie sagen nicht, welche Datei ein Abschnitt anfassen darf, welche Grenze in Code gehört und womit „fertig“ belegt ist. Genau das steht hier, und es läuft neben jedem der fünf.
Methode 07 — Verortung
zieht den Vergleich im Einzelnen, mit Lesedatum im Kopf, weil diese Seite schneller driftet als
der Rest. Zwei verbreitete Angaben stimmen dort nicht mehr: Das ursprüngliche GSD-Repository ist
archiviert und lebt als GSD Core weiter, und SpecKit ist mit dem
converge-Schritt nicht mehr linear.
Der Fall, an dem Textregeln scheitern
Jede CLAUDE.md enthält irgendwo den Satz „niemals secrets.json
committen“. Der funktioniert — solange der Dateiname im Befehl vorkommt. Er tut es hier nicht:
$ git add -A
Der Guard sieht deshalb nicht in den Befehl, sondern fragt das Werkzeug, was der Befehl bewirken würde:
# Nur Befehle, die ueberhaupt etwas stagen koennen: git add in jeder Form —
# und git commit -a, das Verfolgtes selbst stagt.
printf '%s' "$befehl" | grep -qE '(^|[;&|]|\s)git\s+(-[^ ]+\s+)*add(\s|$)' \
|| printf '%s' "$befehl" | grep -qE '(^|[;&|]|\s)git\s+commit([^;&|]*)?\s-[A-Za-z]*a' \
|| exit 0
# Kandidaten = was der Befehl TATSAECHLICH stagen wuerde. Gemessen, nicht
# geschaetzt: `git status` weiss nicht, ob eine Datei vom Befehl erfasst waere.
if printf '%s' "$befehl" | grep -qE '…add\s+(-u|--update)(\s|$)' \
|| printf '%s' "$befehl" | grep -qE '…commit…\s-[A-Za-z]*a'; then
roh=$(git add -u --dry-run 2>/dev/null) # -u / commit -a: nur Verfolgtes
else
roh=$(git add -A --dry-run 2>/dev/null) # sonst: auch Unverfolgtes
fi
kandidaten=$(printf '%s\n' "$roh" | sed -n "s/^add '\(.*\)'$/\1/p")
$ hooks/tests/test-guard.sh
Nicht-Treffer (duerfen NICHT blocken):
ok git add einer harmlosen Datei (Code 0)
ok Bulk-Add ohne geschuetzte Datei (Code 0)
Treffer (muessen blocken):
ok .env vorhanden, Bulk-Add -A (Code 2)
ok Add in Befehlskette (Code 2)
Gemessen statt geschaetzt:
ok commit -am stagt verfolgte Datei (Code 2)
ok add -u ignoriert unverfolgte .env (Code 0)
ok add -A erfasst dieselbe .env (Code 2)
Fail-closed ohne jq:
ok ohne jq blockt der Guard (Code 2)
...
48 bestanden, 0 fehlgeschlagen
Drei Härtungen sind im August aus der Praxis zurückgeflossen — in einem Arbeitsverzeichnis
waren über hundert unverfolgte Dateien gelandet, keine davon von
.gitignore erfasst. Messen statt schätzen: --dry-run
beseitigt einen Fehlalarm, der vorher garantiert kam — git add -u neben einer
herumliegenden, unverfolgten .env. git commit -am mit
abgedeckt: Es stagt selbst und lief vorher vorbei. Fail-closed ohne
jq: Fehlt das Werkzeug, blockt der Guard und nennt den
Installationsbefehl, statt still durchzulassen. Ein Guard, der auf einem frisch aufgesetzten
Rechner unbemerkt abgeschaltet ist, ist schlimmer als keiner.
Übernommen ist dabei die Technik, nicht der Fall: Dieser Guard kennt keine Kundendateien und
keine Kundenpfade — die stehen in der .claude/geschuetzte-pfade des jeweiligen
Projekts. Vor der Veröffentlichung läuft das Herkunfts-Gate darüber.
Dieselbe Unterscheidung trägt weiter, als sie zunächst aussieht: Regeln, die abgewogen werden dürfen, gehören in Text. Regeln, bei denen ein Verstoß eine Meldepflicht auslöst, gehören in Code, der nicht abwägt. Die meisten Projekte legen beides an denselben Ort und wundern sich über das Ergebnis.
Warum das offen liegt
Weil Werkzeuge, die man nicht lesen kann, keine Werkzeuge sind, sondern Versprechen. Und weil das, was hier steht, ohnehin nur durch Nachbauen besser wird.
Die Herkunft steht drin, wo es eine gibt: Der Sprint-Gedanke ist angeregt durch CC_GodMode von Dennis Westermann — dort eingebettet in ein großes Agenten-System, hier auf das eingedampft, was ohne Toolchain trägt. Was nicht übernommen wurde, ist genauso benannt wie das, was übernommen wurde. Das ist keine Höflichkeit, das ist Nachprüfbarkeit.
Alte Tugend, unverändert gültig: nimm, verbessere, gib zurück. Und dann rede darüber — nicht aus Eitelkeit, sondern weil ungeteiltes Wissen niemandem nützt und stillschweigend verrottet.
Alles unter Apache-2.0. Patentklausel drin, Namensnennung drin, kommerzielle Nutzung
ausdrücklich erlaubt — auch für die, die damit Geld verdienen wollen.
github.com/sitelookgmbh-arch/zfdw-ki-leitplanken
Mit sitelook
Alles hier ist frei nutzbar und ohne Hilfe einsetzbar. Wer es schneller oder an einem gewachsenen Projekt einführen will, kann das mit der sitelook GmbH tun:
Einführung im eigenen Repo
Guard, Anweisungsdatei und erster Sprint an einem bestehenden Projekt aufgesetzt — mit Schutzmustern für die eigenen Daten statt der Vorgaben.
Review des Agenten-Setups
Bestehende Hooks, Berechtigungen und Anweisungsdateien geprüft: Was wirkt, was nur dasteht, was fehlt — mit Rot-Beweis statt Augenschein.
Schulung
Die Methode für ein Team, an dessen eigenem Code. Kein Folienvortrag, sondern Arbeit am Repo.
Wer
Hinter Wirkarchitektur steht die sitelook GmbH in Neuss. Über sie läuft die Arbeit: Entwicklung, Beratung, Schulung — und die Rechnung. Gemacht wird sie von Martin Eggert.
Zu den Namen: Wirkarchitektur ist die Marke, zfdw-ki-leitplanken das Repo mit Methode und Werkzeugen (der Name stammt aus der Anfangszeit), und die sitelook GmbH der Träger, über den alles läuft.
Geschrieben wird hier aus der Praxis: Fachanwendungen und die Infrastruktur darunter — Blazor/.NET, nginx, Asset-Pull-Deploys, DNS, das übliche. Dazu eine Herkunft in der technischen Reportage, und aus ihr die eine Regel, die jeden Text auf dieser Seite prägt: Komplexe Sachverhalte werden verständlich, wenn man die Motivation der Beteiligten begreiflich macht. Deshalb beginnt jeder Methodentext mit dem Problem und kommt erst danach zur Regel — eine Regel ohne ihren Grund wird beim nächsten Zweifel wegdiskutiert.
Und ein Satz, älter als jedes Werkzeug hier: Einer ist keiner. Die Fehler liegen selten in den Teilen, fast immer in den Übergängen zwischen ihnen. Wer das einmal in einer laufenden Produktion gesehen hat, kennt das Muster, lange bevor es Write-Scope heißt.
Kontakt
Issues und Pull Requests gehen ins Repo — das ist der schnellere Weg. Für alles andere:
Kolophon
Handgeschriebenes HTML, ein Stylesheet, kein Build. Systemschriften, weil eine Webfont-Einbindung eine Anfrage an einen fremden Host wäre. Ausgeliefert als statische Dateien vom Edge.
Content-Security-Policy: default-src 'none'; style-src 'self';
img-src 'self' data:; form-action 'none'; base-uri 'none';
frame-ancestors 'none'
Referrer-Policy: no-referrer
Permissions-Policy: camera=(), microphone=(), geolocation=(),
interest-cohort=()
/_headers. default-src 'none' heißt: Was nicht ausdrücklich erlaubt ist, wird nicht geladen.Diese Seite: 21,3 kB HTML, 7,4 kB CSS — unkomprimiert; über die Leitung geht brotli-komprimiert etwa die Hälfte. 2 Anfragen insgesamt. Kein Skript, kein Cookie, kein Banner.