Teil 9. Feature-Validierung: Von Spezifikationen zu Fakten
Feature-Validierung ist keine Formalität nach dem Code. Es ist ein separater Arbeitsmodus, in dem eine textliche Spezifikation in überprüfbare Fakten verwandelt wird. Die Spezifikation erklärt die Absicht, beweist aber nicht von selbst, dass sie umgesetzt wurde. Ein Fakt ist eine Aussage, die Maschine oder Mensch ohne erneute Interpretation langer Prosa überprüfen kann.
Kurze Formel:
Spezifikationen leiten.
Fakten ermöglichen den Merge.
flowchart LR
A["Textliche Spezifikation<br/>Absicht und Grenzen"] --> B["Faktensammlung<br/>validation.md"]
B --> C["Prüfungen<br/>Befehle, Tests, manuelle Szenarien"]
C --> D{"Fakten bestätigt?"}
D -- "ja" --> E["Branch kann gemergt werden"]
D -- "nein" --> F["Code korrigieren<br/>oder Spezifikation präzisieren"]
F --> BBei der Arbeit mit Agenten, die Code schreiben, ist das kritisch. Das Modell kann dieselbe textliche Spezifikation in verschiedenen Sitzungen oder Versionen unterschiedlich lesen. Ein Test, ein Exit-Code, ein HTTP-Status, ein Datenbankinvariant oder ein expliziter Vertrag sind weniger von Interpretation abhängig. Deshalb sollte validation.md nicht nur eine Checkliste sein, sondern eine Sammlung von Fakten für den Merge-Zulass.
Was ist ein Fakt
Ein Fakt ist eine ausführbare oder eindeutig überprüfbare Aussage:
npm run typecheckendet mit Code 0;GET /gibt 200 zurück;- die Antwort enthält
<h1>AgentClinic</h1>; - ein abgelaufener JWT gibt 401 zurück;
- das Einfügen eines Feedbacks ohne Nachricht schlägt die Validierung fehl;
- eine Migration kann zweimal ausgeführt werden, ohne das Schema unerwartet zu ändern;
- für jeden Startagenten gibt die Detailseite eine zugehörige Liste von Krankheiten zurück.
Schlechter Prüfpunkt:
Stelle sicher, dass die Seite gut aussieht.
Besser:
Bei einer Breite von 375px überlappen sich Kopfzeile, Hauptinhalt und Fußzeile nicht.
Die Hauptüberschrift bleibt ohne horizontales Scrollen sichtbar.
Ebenen der Faktensammlung
Verwenden Sie vier Ebenen.
Beispiele prüfen konkrete Ein-/Ausgabe-Paare:
curl -s http://localhost:3000 | rg "<<h1>AgentClinic</h1>"
Invarianten beschreiben etwas, das immer wahr sein muss:
Jeder Feedback-Eintrag hat eine nicht leere Nachricht.
Eigenschaften prüfen eine Klasse von Fällen:
Jede Bewertung außerhalb des Bereichs 1..5 wird abgelehnt.
Verträge fixieren eine Vorbedingung, eine Aktion und eine Nachbedingung:
Wenn die Sitzung nicht authentifiziert ist,
bei Anfrage GET /dashboard
leitet die Antwort auf /login um.
Nicht jedes Feature erfordert alle vier Ebenen. Aber jedes Feature sollte mindestens einige maschinell überprüfbare Fakten haben.
Welche Faktentiefe nötig ist — nach Risikoart
Nicht alle Features sind gleich. Ein einfaches UI-Banner und eine Datenbankmigration erfordern unterschiedliche Prüfdichte. Die minimal ausreichende Faktentiefe lässt sich anhand einer Matrix wählen:
| Feature-Typ / Risiko | Beispiel | Invariant | Eigenschaft | Vertrag | Manueller Fakt |
|---|---|---|---|---|---|
| Visuell / UI-Änderung | obligatorisch | obligatorisch | |||
| CRUD-Route | obligatorisch | obligatorisch | |||
| Formularvalidierung / Eingabe | obligatorisch | obligatorisch | obligatorisch | ||
| Datenmigration | obligatorisch | obligatorisch | |||
| Autorisierung / Zugriff | obligatorisch | obligatorisch | |||
| Zahlung / Seiteneffekt | obligatorisch | obligatorisch | |||
| Integration mit externer API | obligatorisch | obligatorisch | obligatorisch | ||
| Hintergrundaufgaben / Scheduler | obligatorisch | obligatorisch |
So liest man die Tabelle:
- Beispiel — konkretes Ein-/Ausgabe-Paar (ein Befehl, ein curl, ein bestandener Test).
- Invariante — etwas, das nach einer Aktion immer wahr ist. Bei einer Migration: "Wiederholter Lauf ändert das Schema nicht". Bei Hintergrundaufgaben: "Nach erfolgreichem Lauf sinkt der Zähler nicht".
- Eigenschaft — prüft eine Klasse von Fällen. Bei Validierung: "Jede Bewertung außerhalb von 1..5 wird abgelehnt". Bei Autorisierung: "Jede Anfrage ohne Sitzung gibt 401 zurück".
- Vertrag — formale Verknüpfung "bei Bedingung X führt Aktion Y zu Z".
- Manueller Fakt — etwas, das ein Mensch mit Augen oder Händen prüft. Obligatorisch für UI, weil die automatische Prüfung der visuellen Hierarchie oft unzureichend ist.
Ziel der Matrix ist es nicht, sie in einen Pflicht-Checklist zu verwandeln, sondern zu helfen, erkennen, was man übersehen hat. Wenn ein Feature vom Typ "Datenmigration" nur mit einem Beispiel, aber ohne Invariante durchläuft — das ist ein Signal, validation.md neu zu schreiben.
Struktur von validation.md
Beispiel:
# Validierung — Feedback-Formular
## Faktensammlung
### F1 — TypeScript kompiliert
- Befehl: `npm run typecheck`
- Erwartung: Exit-Code 0
- Verantwortlich: automatische Prüfung
- Status: Entwurf
### F2 — Tests bestehen
- Befehl: `npm test`
- Erwartung: Exit-Code 0
- Verantwortlich: automatische Prüfung
- Status: Entwurf
### F3 — Leere Nachricht wird abgelehnt
- Befehl: `npm test -- feedback`
- Erwartung: POST /feedback mit leerer Nachricht gibt 400 zurück
- Verantwortlich: automatische Prüfung
- Status: Entwurf
### F4 — Korrektes Feedback wird gespeichert
- Befehl: `npm test -- feedback`
- Erwartung: Korrekter POST /feedback fügt eine Zeile hinzu und leitet auf /feedback um
- Verantwortlich: automatische Prüfung
- Status: Entwurf
### F5 — Seite bleibt auf Mobilbildschirm benutzbar
- Prüfung: /feedback bei 375px Breite öffnen
- Erwartung: Formularfelder und Senden-Button sind ohne horizontales Scrollen sichtbar
- Verantwortlich: manuelle Prüfung
- Status: Entwurf
## Fertigstellungskriterien
- Alle automatischen Fakten bestehen.
- Manuelle Fakten sind geprüft.
- Fakten, die nicht umsetzbar sind, sind aus dem Scope entfernt oder mit Erklärung in den Entwurf zurückgesetzt.
- Roadmap und Änderungsprotokoll sind vor dem Merge aktualisiert.
Der Lebenszyklus hilft, Absicht und Beweis nicht zu vermischen:
Entwurf: Fakt vorgeschlagen, aber noch nicht fixiert;obligatorisch: Fakt als obligatorisch für das Feature akzeptiert;umgesetzt: es gibt einen Test, Befehl oder manuelle Bestätigung;zurückgestellt: Fakt bewusst in eine spätere Phase verschoben.
Beginnen Sie mit den Unterschieden
git status --short
git diff --stat main...HEAD
Bitten Sie Qwen Code, nicht nur die Spezifikationskonformität zu prüfen, sondern auch die Status der Faktensammlung:
/clear
Vergleiche diesen Branch mit @specs/2026-05-01-hello-hono/validation.md.
Zeige:
1. Fakten, die umgesetzt sind und bestehen;
2. Fakten, die fehlen;
3. Fakten, die mehrdeutig sind und umgeschrieben werden müssen;
4. Entscheidungen in der Implementierung, die nicht in requirements.md beschrieben sind;
5. veraltete Spezifikationsaussagen.
Ändere noch keine Dateien.
Wenn Qwen Code für einen Prüfpunkt nicht bestanden/nicht bestanden bestimmen kann, ist das kein Fakt, sondern eine Prosa-Wunschvorstellung. Schreiben Sie ihn um.
Validierung mit menschlicher Beteiligung
Ein Agent kann mechanische Abweichungen finden, aber ein Mensch muss produkt- und architekturbezogene bewerten:
- entspricht die Seite der Mission;
- ist der Scope nicht zu sehr ausgeweitet;
- gibt es unausgesprochene Abhängigkeiten;
- ist einem neuen Entwickler klar, warum die Dateien so organisiert sind;
- gibt es für jedes risikoreiche Verhalten einen Fakt;
- sind wichtige Entscheidungen nicht nur im Chat verblieben.
Typisches Beispiel: Nach der ersten Implementierung wird oft klar, dass die Seitenstruktur nicht als monolithische Komponente, sondern als Sammlung von Header, Main, Footer gebraucht wird. Das ist nicht nur "Code korrigieren": plan.md und die Fakten in validation.md müssen aktualisiert werden, damit eine zukünftige Sitzung nicht zur alten Interpretation zurückkehrt.
Prompt zur gleichzeitigen Korrektur von Code, Spezifikation und Fakten
Die Implementierung braucht eine klarere Seitenstruktur.
Aktualisiere @specs/2026-05-01-hello-hono/plan.md und fordere:
- Komponente Layout;
- Komponente Header;
- Komponente Main;
- Komponente Footer;
- Einbindung von static/style.css aus Layout.
Aktualisiere @specs/2026-05-01-hello-hono/validation.md mit Fakten, die prüfen:
- die Antwort enthält Header/Main/Footer-Landmarks;
- /static/style.css wird vom Server ausgeliefert;
- npm run typecheck endet mit Code 0.
Aktualisiere dann die Implementierung, damit sie dem neuen Plan und den Fakten entspricht.
Halte die Änderungen innerhalb der Grenzen dieses Features.
So verhindern Sie gleichzeitig Spezifikationsdrift und Faktendrift.
Automatische Prüfungen
Minimum:
npm run typecheck
Wenn Tests bereits vorhanden:
npm test
Wenn ein Entwicklungsserver läuft:
npm run dev
curl -s http://localhost:3000
curl -s http://localhost:3000/static/style.css
In validation.md notieren Sie exakte Befehle und erwartete Ergebnisse. Schreiben Sie nicht "prüfen, dass es funktioniert", wenn Sie einen Befehl und den erwarteten Exit-Code schreiben können.
Manuelle Fakten
Manuelle Fakten sind nicht schwächer als automatische, wenn sie konkret sind. Schwache manuelle Prüfung:
Prüfe die Benutzeroberfläche.
Ordentlicher manueller Fakt:
Bei 375px Breite zeigt die Seite /feedback das Namensfeld, das Nachrichtenfeld,
den Senden-Button und die drei letzten Einträge ohne horizontales Scrollen und Überlappungen.
Manuelle Fakten sind nützlich für Ton, visuelle Hierarchie, grundlegende Barrierefreiheitsprüfung und das Erkennen von Scope-Creep. Aber wenn ein manueller Fakt in jedem Feature wiederholt wird, überlegen Sie, wie Sie ihn über Playwright oder Unit- und Integrationstests automatisieren können.
Validierung in CI
Fakten müssen bis zum Merge-Zulass gelangen. Für ein kleines Projekt reichen lokale Befehle. Für ein Team ist CI besser:
Ein Merge-Request darf nicht angenommen werden, solange:
- npm run typecheck nicht besteht;
- npm test nicht besteht;
- obligatorische Route-Tests nicht bestehen;
- die Faktensammlung in validation.md nicht aktualisiert ist.
Das ist die praktische Antwort auf die Kritik "Spezifikationen werden interpretiert". Die textliche Spezifikation leitet den Agenten, aber den Merge entscheiden die Fakten.
Evidence Bundle für den Merge
Wenn ein Feature zum Merge ansteht, sollte der Reviewer ein kompaktes Artefakt haben, anhand dessen er versteht: was genau umgesetzt wurde, welche Fakten bestanden, welche zurückgestellt. Dieses Artefakt nennt man praktischerweise "Evidence Bundle".
Das ist keine separate neue Datei — es ist ein Format für die Beschreibung eines Merge-Requests. Ein gutes Evidence Bundle besteht aus:
- Verweis auf den Spezifikationsordner (
specs/YYYY-MM-DD-feature/); - Liste der Fakten aus
validation.mdmit Status:bestätigt,fehlgeschlagen,zurückgestellt; - Spuren der Befehlsausführung: Befehlsnamen, Exit-Codes, letzte Ausgabezeile oder kurzer Auszug;
- Ergebnissen manueller Prüfungen: was genau der Mensch geprüft hat, auf welchem Bildschirm, was er gesehen hat;
- Liste von Entscheidungen, die während der Implementierung getroffen wurden und nicht in der ursprünglichen Spezifikation waren;
- Verweisen auf Commits, in denen diese Entscheidungen reflektiert sind.
Eine Vorlage für eine solche Merge-Request-Beschreibung findet sich in Anhang C. Die Hauptidee: Der Reviewer sollte nicht alles neu starten müssen, um sich von der Fertigkeit zu überzeugen. Er sollte am Evidence Bundle erkennen können, was der Autor genau gemacht und geprüft hat, und bei Zweifeln gezielt die nötigen Befehle wiederholen können.
Wenn im Evidence Bundle ein Punkt "Fakt nach Fehlschlag geändert" auftaucht, ist das kein Grund, ihn zu verstecken. Im Gegenteil: eine explizit erklärte Faktänderung ist ein normaler Teil von SDD, eine verborgene Änderung ist ein Antipattern (siehe Teil 20).
Aktualisierung der Roadmap
Nach Bestehen der Faktensammlung:
## Phase 1: Hello Hono (abgeschlossen)
- [x] Hono und tsx installieren.
- [x] Route GET / erstellen.
- [x] Minimales HTML mit Server-Rendering zurückgeben.
- [x] Typprüfungsskript hinzufügen.
Commit:
git add specs/roadmap.md specs/2026-05-01-hello-hono
git commit -m "Validate Hello Hono feature"
Merge:
git checkout main
git merge phase-1-hello-hono
git branch -d phase-1-hello-hono
Praxis
- Führen Sie alle automatischen Fakten aus.
- Bitten Sie Qwen Code, den Code mit
validation.mdzu vergleichen. - Schreiben Sie mehrdeutige Prüfpunkte als Fakten um.
- Korrigieren Sie Code oder Spezifikation, wenn sie auseinanderdriften.
- Markieren Sie die Faktstatus.
- Markieren Sie die Phase in der Roadmap.
- Führen Sie den Merge durch.
Kontrollfragen
- Warum sollte die textliche Spezifikation nicht der einzige Merge-Zulass sein?
- Worin unterscheidet sich ein Fakt von einer Prüfungswunschvorstellung?
- Wann kann eine manuelle Prüfung als Fakt gelten?
- Was tun, wenn Tests bestehen, aber die Implementierung nicht mit
requirements.mdübereinstimmt? - Warum ist "Spezifikationen leiten, Fakten ermöglichen den Merge" besser als einfach "schreiben Sie bessere Spezifikationen"?