Spec-driven Softwareentwicklung mit KI-Agents: Theorie, Praxis, Sicherheit
414
Commits
129
Tasks
46
Tage
~40h
Coding-Zeit
Fallstudie: HafCoin, Coin-basiertes Buchungssystem für Haus am Fluss
(19 Mieter, 400 m²) BetterLabs GmbH · christine@betterlabs.ch · pawel@betterlabs.ch
Das Problem: Warum monolithische KI-Generierung scheitert
Je grösser der Scope, desto schlechter das Ergebnis. Das ist kein Gefühl und
es ist messbar.
Error Compounding
Fehler in langen Generierungen sind nicht unabhängig. Eine falsche Annahme
früh im Kontext propagiert in alle folgenden Entscheidungen, und das Modell
kann sich nicht selbst korrigieren, sobald der Kontext verschmutzt ist. Kleine
Schritte begrenzen den Bereich, in dem sich ein Fehler ausbreiten kann.
Context Rot
Jedes Modell degradiert mit wachsendem
Kontext. Agents akkumulieren Rauschen. Ab ~100k Tokens bevorzugen sie Wiederholung
statt Synthese.
Sieht richtig aus, kompiliert, besteht oberflächliche Checks. Ist aber
semantisch falsch. Je breiter der Scope, desto höher die Rate.
Die Evidenz
SWE-Bench Pro (Scale AI):
Beste Agents (GPT-5, Opus 4.1) lösen
23% der Long-Horizon-Tasks.
Auf dem kürzeren SWE-Bench Verified:
70%+
Lost in the Middle:30%+ Accuracy-Verlust wenn kritische Info in der
Kontextmitte liegt
Prompt Chaining: Gewinnt
77/100 Vergleiche gegen All-in-One-Prompts
Unsere Erfahrung in diesem Projekt: präzise Specs vor dem Start sparen ein
Vielfaches an Nacharbeit. Die 8 Tage Spec-Arbeit vor dem Marathon-Tag (40 Commits)
waren kein Overhead, sondern Voraussetzung. Das Tempo war vertretbar, weil der Harness
die komplette Suite pro Commit fuhr.
Die These: Spec-Driven Agentic Engineering
Nicht der Agent wird besser. Die
Arbeit wird besser strukturiert.
Specs als Forcing Function
Spezifikationen zwingen implizite Entscheidungen an die Oberfläche. Was der
Mensch nicht aufschreibt, füllt das Modell mit generischen Priors. Meistens
falsch für domänenspezifische Regeln.
Kleine Tasks, begrenzter Blast Radius
Jeder Task ist so geschnitten, dass ein Agent ihn in einem Durchlauf umsetzen kann.
Fehler bleiben lokal. Frischer Kontext pro Task, kein Context Rot.
Tests als Sicherheitsnetz
Die Testsuite ist kein Nachgedanke, sondern das Fundament. Sie wächst mit jedem
Task und sichert den nächsten Agent-Durchlauf ab.
Der Ingenieur verschiebt sich vom Autor zum Reviewer, Architekten und Spec-Schreiber.
Das erfordert andere Fähigkeiten und wirft offene Fragen auf: Review-Qualität
bei fremdem Code, Skill-Entwicklung für Junioren, Delegation ohne Kontrollverlust.
Der Workflow: Vier Schritte vom Konzept zum Code
/prototype, /generate-tasks,
/implement-task sind eigene Claude Code Skills, keine
Bordmittel.
1
Spec schreiben
docs/10-business/*.md
Datenmodell, Abläufe, Geschäftsregeln, Randfälle. Die Spec zwingt
implizite Entscheidungen an die Oberfläche.
2
Prototyp erzeugen
/prototype
Klickbares Alpine.js-Prototype aus der Spec. Stakeholder erleben das Verhalten,
Lücken werden sichtbar.
3
Tasks generieren
/generate-tasks
Spec vs. Codebase analysieren, Mehrdeutigkeiten finden, in Schichten zerlegen: Schema
→ Domain → API → UI → Test.
4
Task umsetzen
/implement-task
Ein Task pro Durchlauf. Implementieren, Tests laufen lassen, Security-Review, Commit.
Mensch reviewed.
↻
Kein linearer Prozess.
Der Prototyp deckt Lücken auf → Spec wird verfeinert.
/generate-tasks findet Widersprüche → zurück
zur Spec. Selbst /implement-task erzeugt manchmal neue
Spec-Aufgaben. Jeder Übergang ist ein Quality Gate.
Schritt 1: Die Spec als Forcing Function
Was der Mensch nicht aufschreibt, füllt das Modell mit generischen Priors. Bei
domänenspezifischen Regeln liegen diese fast immer falsch.
Was eine Spec enthält
✓ Datenmodell mit Typen und Constraints
✓ Benutzerabläufe Schritt für Schritt
✓ Geschäftsregeln mit SHALL/SHOULD/MAY
✓ Randfälle und Fehlerzustände
✓ Sicherheitsüberlegungen
✓ Nicht-funktionale Anforderungen
Specs sind portabler als Prompt-Engineering. Dieselben Specs lassen sich mit
verschiedenen Modellen verwenden. Prompt-Tricks sind an ein Modell und eine Version
gebunden.
Beispiel: HafCoin Storno-Regeln
### Stornierung Kostenlose Stornierung ≥24h vor Beginn. Keine Rückerstattung
bei Stornierung <24h. Admin kann jederzeit stornieren (volle
Rückerstattung). Coins werden als «refund» zurückgebucht.
Stornierte Buchungen bleiben im Audit Trail.
Ohne Spec würde das Modell vermutlich eine generische «jederzeit
stornierbar»-Logik bauen. Die 24h-Regel, Admin-Ausnahme und Refund-Buchung auf
den Audit Trail würden fehlen.
Ein Claude Code Skill generiert aus der Markdown-Spec ein klickbares, interaktives
Single-File-Prototype.
Feedback vor der ersten Zeile Produktionscode.
So funktioniert es
/prototype docs/10-business/04-bookings.md
→ Generiert eine HTML-Datei mit Alpine.js
→ In-Memory State (keine Datenbank, kein Backend)
→ Stakeholder öffnet die Datei im Browser und klickt durch
→ Findet Lücken, Spec wird verfeinert
Der Prototyp macht abstrakte Spec-Regeln greifbar. Ein «Coin-Abzug bei
Buchung» im Markdown liest sich anders als ein sichtbar schrumpfender Kontostand
im Browser.
HafCoin: Was entdeckt wurde
ProfilProfilseite brauchte Password-Änderung und Firmendaten-Anzeige.
Spec erweitert
RechnungenCHF-Beträge für Pauschale-Buchungen fehlten in Spec
NavigationKalender-Abonnement brauchte zwei Feed-Optionen statt einer
Der Prototyp wird verworfen. Sein Wert liegt in den Lücken, die er aufdeckt. Ob
das billiger ist als klassische UX-Forschung, hängt vom Projekt ab.
Schritt 3: Tasks generieren
/generate-tasks liest die Spec, analysiert die bestehende
Codebase und zerlegt die Arbeit in schichtspezifische, abhängigkeitsgeordnete Tasks.
Was der Skill tut
Findet Mehrdeutigkeiten, fehlende Informationen, Konflikte mit bestehendem Code
Zerlegt in Schichten: Schema → Domain → API → UI → Test
Ordnet Abhängigkeiten: Domain braucht Schema, API braucht Domain
Jeder Task bekommt testbare Akzeptanzkriterien
↻
Wenn die Analyse Mehrdeutigkeiten findet, geht es zurück zur Spec. Kein
«weiter trotzdem».
Beispiel: Passwort-Reset → 5 Tasks
1
TASK-121 schema
Token-Tabelle und Enum-Migration
2
TASK-122 domain
Token-Logik: erzeugen, validieren, einlösen
3
TASK-123 api
Server Actions und E-Mail-Template
4
TASK-124 ui
UI-Seiten und Login-Link
5
TASK-125 test
E2E-Tests für den gesamten Flow
Schritt 4: Task umsetzen
/implement-task TASK-138: ein Task pro Agent-Durchlauf. Klare
Eingabe, klares Ergebnis, reviewbar in Minuten.
200–400 LOC pro Code Review
(Erfahrungswert, HafCoin-Praxis)
~4 kognitive Chunks gleichzeitig
verarbeitbar
(Cowan 2001)
1–2 Tage pro Task
(Agile Consensus)
Frischer Kontext pro Subtask
(Chroma, Liu et al.)
KI-Agents senken die Transaktionskosten pro Task. Mit Reinertsens Logik verschiebt
das das Optimum nach links: kleinere Tasks als bei rein menschlicher Arbeit.
Das Sicherheitsnetz: Tests als Harness
Eine dreistufige Testsuite läuft bei jeder
Änderung automatisch. Sie prüft, ob der Agent-Code korrekt ist, und schützt
bestehende Funktionalität vor Regressionen.
Unit-Tests
Vitest · src/domain/
Isolierte Geschäftslogik: Coin-Berechnung, Storno-Regeln, Quartals-Verfall. Jede
Domain-Funktion hat eine Spec. Der Test ist ihr automatisierter Beweis.
Integrationstests
Vitest · echte PostgreSQL
Server Actions gegen eine echte Datenbank. Unsere bewusste Entscheidung: keine Mocks.
Wenn der Agent eine Migration falsch schreibt, scheitert der Test, nicht erst die
Produktion. Bei grösseren Projekten ist das ein Trade-off gegen Laufzeit.
E2E-Tests
Playwright · Browser
Simulieren echte Nutzer: einloggen, buchen, Coins prüfen, stornieren. Decken
Regressionen auf, die kein Unit-Test finden kann: das kaputte Formular, der fehlende
Button.
/implement-task erzeugt nicht nur Code, sondern auch Tests,
und lässt die gesamte bestehende Suite laufen. Mit jedem Inkrement wird
das Netz dichter. Erst das macht das Tempo vertretbar.
Der Harness in der Praxis
Wofür der Harness sorgt
Tests verifizieren gegen Spec-Akzeptanzkriterien. Nicht das Bauchgefühl des
Reviewers entscheidet, ob der Code stimmt, sondern die Suite.
Die gesamte Suite läuft bei jedem Task. Regressionen werden sofort entdeckt,
nicht erst beim nächsten Release.
Der Mensch muss nicht jede Zeile lesen. Die Tests sind gegen die Spec geschrieben
und damit nachvollziehbar.
HafCoin: Das wachsende Netz
npm run test
Vitest: Unit- und Integrationstests
npm run test:e2e
Playwright: Browser-basierte End-to-End-Tests
npm run test:gherkin
Cucumber: Akzeptanztests in Gherkin-Syntax
Bewusste Entscheidung: echte Datenbank, keine Mocks. Funktioniert bei 129 Tasks. Bei
10'000+ Tests wäre das ein Laufzeit-Problem. Für diese Projektgrösse
ist der Trade-off richtig.
Evolutionär, nicht One-Shot
Specs verhindern keine falschen Entscheidungen. Aber sie machen falsche Entscheidungen
billig rückgängig zu machen. Die eigentliche
Entdeckungsarbeit passiert im User-Testing und Prototyping, nicht in der Spec selbst.
HafCoin: 3 Sackgassen, 3 Lektionen
Auth-Kehrtwende
Custom Auth → Auth.js v5. Pivot in 4 Stunden, am selben Tag.
Buchungs-UX
3 Iterationen, 24 Tage. 572 LOC gelöscht. Einfachste Lösung gewann.
No-Show entfernt
Komplett gebaut, komplett gelöscht. User-Testing hat es gezeigt.
572 Zeilen Code zu löschen tut nicht weh, wenn sie in Minuten entstanden sind.
Kleine Tasks machen Pivots billig. Der Harness schützt den Rest während der
Entfernung.
Beispiel: Die Auth-Kehrtwende
SACKGASSE
23. März 2026
Morgens:
Entscheid dokumentiert: «Kein Auth.js, wir bauen Custom Auth.»
Begründung: Rolling Timeout, Session Limits, Forced Password Change
«unverzichtbar».
Nachmittags:
Erkenntnis: Diese 4 Features erhöhen Komplexität
unverhältnismässig zum Sicherheitsgewinn für ein internes
Gebäudesystem mit 19 Mietern.
Kleine Tasks machen Pivots billig. Ein ADR dokumentiert das Warum. Die Spec wird
angepasst, nicht der Code drumherum.
Beispiel: Buchungs-UX, 3 Iterationen
24 TAGE
Die einfachste Lösung gewann. Aber es brauchte Exploration, um sie zu finden.
1
Wizard
· 24. März
Dreistufiges Formular: Ressource wählen → Datum → Zeit. 632 LOC.
Funktioniert, aber zu viele Klicks für eine einfache Buchung.
2
Split-Pane
· 26. März
Zweigeteilte Ansicht: Raumliste links, Buchungs-Timeline rechts. Höhere
Informationsdichte, aber zu komplex für das Nutzungspattern.
3
Pauschale-Buttons
· 18. April
Drei Buttons pro Raum: Vormittag, Nachmittag, Ganzer Tag. Ein Klick →
vorgefüllter Dialog. 572 LOC Wizard-Code gelöscht. Die einfachste
Lösung.
Drei Iterationen über 24 Tage kosten Zeit. Aber jede war in Stunden gebaut und in
Minuten entfernt. Ob frühere UX-Forschung das verkürzt hätte, bleibt
offen.
Beispiel: No-Show, gebaut und gestrichen
GESTRICHEN
Ein Feature, das auf dem Papier logisch war, aber in der Realität scheiterte.
Was gebaut wurde
✓ DB-Schema: no_show Status in Enums
✓ Repository: markNoShow() Funktion
✓ Server Action: markNoShowAction()
✓ Admin-UI: Tabs, Filter, Badges
✓ E2E-Tests: TASK-037
Was User-Testing zeigte
«Nicht erschienen kann entfernt werden, da wir das nicht tracken
können.»
Das Gebäude hat keinen Mechanismus, um die tatsächliche Raumnutzung zu
erfassen. Das Feature war technisch korrekt, aber real unmöglich zu bedienen.
Test mit echten Nutzern. Entferne ohne Reue. Nach dem Entfernen läuft die gesamte
Suite und bestätigt, dass nichts kaputt ging.
grep -r "no.show\|noShow\|no_show" → 0 Treffer
Fünf Prinzipien
1
Spec before Code
– was nicht aufgeschrieben ist, wird halluziniert
2
Prototype before Implementation
– Feedback vor der ersten Zeile Produktionscode
3
Kleine Tasks begrenzen den Blast Radius
– frischer Kontext, reviewbar in Minuten
4
Tests sind der Harness, nicht ein Nachgedanke
– ohne Sicherheitsnetz ist das Tempo unverantwortlich
5
Falsche Entscheidungen billig machen
– Specs verhindern keine Fehler, aber sie machen Rückbau billig
HafCoin ist ein Existenzbeweis, kein Universalrezept. Ein Projekt, ein Team, 19 Nutzer,
internes Buchungstool. Nicht getestet: >100 Stakeholder, Legacy-Codebases,
regulatorische Anforderungen. Die 40h Coding-Zeit beschleunigen den billigsten Schritt.
Die restlichen 46 Tage gingen in Spec-Arbeit, Review, User-Testing und Denkzeit.