Thema: Praktischer Teil 7. Specification CI: Spezifikation als ausführbares Artefakt
Schwierigkeitsgrad: Mittelstufe
Geschätzte Lernzeit: 4–6 Stunden (Theorie + Praxis mit Runnable-Beispielen)
Voraussetzungen: Grundlegendes Verständnis von Git und GitHub Actions
Erfahrung mit Markdown-Anforderungsdokumenten (requirements.md, plan.md)
Vertrautheit mit JSON Schema
Abschluss von Teil 9 des ersten Bandes (Validierung von Fakten) und Teil 16 (Team-Review)
Grundlegendes Python zum Ausführen von Prüfskripten
Lernziele: Lokale Spezifikations-Gateway (Spec CI) einrichten, das Merge bei Verletzungen der Abdeckung, des Geltungsbereichs oder des Datenschemas blockiert
Reproduzierbaren Tracing-Graphen requirements → plan mit REQ-*-Identifikatoren und Feld implements aufbauen
Diagnosemeldungen der CI formulieren, die Datei, Zeile, Regel-ID und konkrete Korrekturmaßnahme enthalten
spec_gate in GitHub-Branch-Schutz integrieren, damit grüne Unit-Tests die semantische Prüfung nicht umgehen können
Negative Fixtures für JSON Schema erstellen und erklären, warum ihr vorhersehbarer Fehlschlag den Vertrag schützt
Überblick: Dieses Kapitel verwandelt die Spezifikation aus statischem Text in einen ausführbaren Schiedsrichter des Repositorys. Das Spezifikations-Gateway (Spec CI) ist ein GitHub-Actions-Workflow, der bei jedem push und pull_request drei Ebenen prüft: Abdeckung der Anforderungen durch den Plan (coverage), Übereinstimmung des Plans mit dem Domänenmodell (scope) und Korrektheit der Datenbeispiele (schema). Schlüsselprinzip: Streit über die Spezifikationsqualität reduziert sich auf eine konkrete Zeile, Regel und Maßnahme. Das Team erhält einen reproduzierbaren Sperrmechanismus, und der Reviewer prüft die Bedeutung der Änderung statt CI-Logs zu untersuchen. Das Kapitel beginnt mit einem lokalen Runnable-Beispiel auf Incident-Payload und skaliert dann auf einen Produktions-Workflow mit Branch-Schutz.
Schlüsselkonzepte: Spec CI (Spezifikations-Gateway): Continuous-Integration-Workflow, der requirements.md, plan.md, validation.md und API-Verträge als ausführbare Artefakte prüft. Blockiert Merge bei drei Verletzungsklassen: unerfüllte Anforderungen, Geltungsbereichsüberschreitung (out-of-scope), JSON-Schema-Fehler. Hauptbegriff des ersten Durchgangs; weitere Begriffe werden bei ihrem Auftreten in Skripten eingeführt.
Gate (Gateway): Obligatorische CI-Prüfung, ohne deren Bestehen Merge unmöglich ist. Im Gegensatz zu gewöhnlichen Tests prüft spec_gate die semantische Integrität, nicht nur die Code-Korrektheit. Muss in den Branch-Schutz-Einstellungen als obligatorisch markiert werden.
Coverage-check (Abdeckungsprüfung): Aufbau des Tracing-Graphen requirements → plan über stabile REQ-*-Identifikatoren und Feld implements. Jede User-Story muss eine umsetzende Aufgabe haben, jede Aufgabe eine Rückwärtsverknüpfung. Fehler: orphan requirement (Anforderung ohne Aufgabe) und rogue task (Aufgabe ohne Anforderung).
Scope-check (Geltungsbereichsprüfung): Detektor für Geltungsbereichsüberschreitung des Domänenmodells. Prüft, dass Aktionen in plan.md im Incident-Response-Domäne erlaubt sind: acknowledge, escalate, annotate, rollback, notify_on_call. Berücksichtigt Akteur, Endpoint und Auslösebedingung. Blockiert autonome Operationen wie force_resolve_without_operator.
Schema-check (Schema-Prüfung): Validierung von JSON-Fixtures aus validation.md gegen JSON Schema. Zwei Richtungen: valide Beispiele bestehen, negative fallen vorhersehbar. Wenn eine negative Fixture besteht – ist das Schema zu schwach.
Fixture (Fixture): Beispiel-Eingabedaten, aus validation.md extrahiert zur Vertragsprüfung. Valide Fixtures bestätigen korrekte Funktion, negative schützen vor Schema-Regressionen.
Spec gate (finale CI-Aufgabe): Abschließender Job im Workflow, der erfolgreiche Ausführung von coverage, scope und schema erfordert. Genau diese Aufgabe muss im Branch-Schutz als obligatorisch markiert werden, sonst umgehen grüne Unit-Tests die semantische Prüfung.
JSON-Diagnose: Format von CI-Ablehnungen, ausgelegt auf schnelle Korrektur ohne Untersuchung. Vier obligatorische Elemente: verständlicher Grund, Datei- und Zeilenreferenz, Regel-Identifikator, konkrete Maßnahme.
Runnable-Beispiel: Lokaler Lernfall auf Incident-Payload, ausführbar ohne GitHub Actions. Enthält check_coverage.py und validate_schema.py zur Demonstration der Gateway-Prinzipien vor vollständiger CI-Einführung.
Übungsaufgaben: Titel: Lokaler Gateway-Lauf zur Abdeckungsprüfung
Problem: Wechseln Sie in das Verzeichnis book2/examples/spec-ci und führen Sie das Abdeckungsprüfungsskript aus. Dann verletzen Sie absichtlich die Verknüpfung: fügen Sie in requirements.md eine Geschichte REQ-999 ohne umsetzende Aufgabe in plan.md hinzu. Führen Sie das Skript erneut aus und analysieren Sie die Diagnose.
Lösung: 1. cd book2/examples/spec-ci
- python3 scripts/check_coverage.py --requirements requirements.md --plan plan.md → erwartet Code 0, Meldung coverage ok
- Fügen Sie in requirements.md hinzu: '## REQ-999: Als Admin möchte ich automatisches Löschen von Incidents'
- Führen Sie das Skript erneut aus → erwarteter Fehler mit Meldung: 'requirements.md:42: REQ-999 hat keine Verknüpfung in plan.md. Fügen Sie in plan.md eine Aufgabe mit implements: REQ-999 hinzu oder entfernen Sie die Anforderung.'
- Korrigieren Sie durch Hinzufügen einer Aufgabe mit implements: [REQ-999] in plan.md, oder entfernen Sie REQ-999
Schwierigkeitsgrad: Anfänger
Titel: Negative Fixture und Schema-Schutz
Problem: Führen Sie im Verzeichnis book2/examples/spec-ci validate_schema.py aus. Erstellen Sie dann eine neue negative Fixture: valides Format, aber mit severity: 'P0' und ohne backup_verified. Prüfen Sie, dass das Schema sie ablehnt. Wenn sie besteht – ist das Schema zu schwach.
Lösung: 1. python3 scripts/validate_schema.py --schema schemas/incident_payload.schema.json --fixtures fixtures → Code 0, valid-incident.json: valid, invalid-missing-incident-id.json: expected invalid
- Erstellen Sie fixtures/invalid-p0-no-backup.json mit _expected_invalid: true, incident_id: 'INC-003', severity: 'P0', aber ohne backup_verified
- Führen Sie validate_schema.py erneut aus
- Bei Erhalt von 'invalid-p0-no-backup.json: expected invalid, rejected: missing required property backup_verified' → Schema korrekt
- Bei Bestehen der Validierung → Schema modifizieren: 'if severity == P0 then backup_verified required' hinzufügen und wiederholen
Schwierigkeitsgrad: Mittelstufe
Titel: Spec CI in Capstone für high_memory_usage übertragen
Problem: Erstellen Sie im Capstone-Projekt eine Spec CI-Zeile für das Szenario high_memory_usage. Anforderung: REQ-HM-01 „Pod nicht neu starten ohne bestätigtes RSS > 90% über 5 Minuten“. Beweisen Sie die Verknüpfung mit plan.md und erstellen Sie eine negative Fixture ohne incident_id.
Lösung: 1. Sicherstellen, dass requirements.md REQ-HM-01 mit klarem Zustand (RSS > 90%, 5 Minuten) enthält
- In plan.md Aufgabe mit implements: [REQ-HM-01] hinzufügen
- Ausführen: python3 scripts/check_coverage.py --requirements requirements.md --plan plan.md → erwartet coverage ok
- Fixture mit high_memory_usage-Payload, aber ohne incident_id erstellen, mit _expected_invalid: true markieren
- validate_schema.py ausführen → erwartet Ablehnung wegen missing required property incident_id
- In capstone/validation.md notieren:
| Spec CI | check_coverage.py | REQ-HM-01 mit plan.md verknüpft | PASS | | Schema negative | validate_schema.py | missing incident_id blockiert | PASS |
Schwierigkeitsgrad: Mittelstufe
Titel: Geltungsbereichsprüfung: Blockierung einer Rogue-Operation
Problem: Fügen Sie im Lernplan plan.md einen Schritt 'TASK-ROGUE: autonomes Schließen des Incidents über POST /incidents/{id}/force-resolve ohne Operator-Bestätigung, mit implements: [REQ-014]' hinzu. Prüfen Sie, dass der Scope-check diese Operation blockiert, obwohl Coverage grün bleibt.
Lösung: 1. TASK-ROGUE in plan.md mit implements: [REQ-014] und Endpoint POST /incidents/{id}/force-resolve hinzufügen
- check_coverage.py ausführen → grün (formale Verknüpfung besteht)
- check_scope.py ausführen (oder manuelle Analyse nach Incident-Response-Domänenmodell)
- Erwarteter Fehler: 'plan.md:48 uses force_resolve without domain permission'
- Ersetzen durch POST /incidents/{id}/ack oder separates Anforderung und Domänenregel hinzufügen
- Wiederholen bis grüner Status
Schwierigkeitsgrad: Fortgeschritten
Titel: Formatierung einer korrigierbaren Diagnose
Problem: Erhalten Sie eine 'schlechte' Fehlermeldung: 'Coverage failed: missing REQ'. Transformieren Sie sie in eine 'gute' nach vier Elementen: Grund, Datei/Zeile, Regel-Identifikator, Maßnahme. Im JSON-Format notieren.
Lösung: Ursprünglich (schlecht): 'Coverage failed: missing REQ'
Transformiert (gut): { 'status': 'failed', 'check': 'coverage', 'file': 'requirements.md', 'line': 42, 'rule': 'REQ-COV-014', 'reason': 'REQ-014 hat keine umsetzende Aufgabe im Plan', 'action': 'Fügen Sie in plan.md eine Aufgabe mit implements: [REQ-014] hinzu oder entfernen Sie die Anforderung aus requirements.md' }
Prüfung: Meldung ermöglicht Korrektur ohne Öffnen von Dateien und Lesen von Prozesslogs
Schwierigkeitsgrad: Mittelstufe
Fallstudien: Titel: Incident-Pipeline: Wie eine negative Fixture eine falsche P0-Eskalation verhinderte
Szenario: Ein SRE-Team in einem Fintech-Unternehmen automatisierte die Verarbeitung von Grafana-Alerts → PagerDuty. In validation.md waren Webhook-Beispiele mit Feldern incident_id, severity, source enthalten. Das Schema incident_payload.schema.json erforderte backup_verified für severity: 'P0'. Die Spezifikation war an Spec CI mit drei Ebenen angebunden: coverage, scope, schema.
Herausforderung: Ein Entwickler 'optimierte' das Schema, entfernte die Bedingung backup_verified für P0, in der Annahme 'Backup ist immer vorhanden'. Eine Woche später fügte ein anderer Entwickler im plan.md einen Schritt zur automatischen Eskalation bei P0 hinzu, ohne die Anforderungen zu ändern. Coverage blieb grün (implements vorhanden), scope ebenfalls (Eskalation im Domänenbereich). Aber die negative Fixture invalid-p0-no-backup.json bestand plötzlich die Validierung – das Schema war zu schwach geworden.
Lösung: Spec CI auf Schema-Check-Ebene erkannte, dass die negative Fixture (markiert mit _expected_invalid: true) die Validierung bestand. Der spec_gate-Status wurde rot, Merge blockiert. Die Diagnose wies hin: 'validation.md:72 schema mismatch: negative fixture invalid-p0-no-backup.json passed, expected reject by missing backup_verified. Action: restore if-then requirement in incident_payload.schema.json: severity P0 requires backup_verified'. Das Team stellte die Schema-Strenge wieder her und fügte explizite Anforderung REQ-BACKUP-01 in requirements.md hinzu.
Ergebnis: Eine Situation verhindert, in der ein Incident mit severity P0 ohne bestätigtes Backup automatisch den Diensthabenden um 3 Uhr nachts eskalieren würde, obwohl Wiederherstellung unmöglich war. Reaktionszeit auf Schema-Regression: Minuten statt Stunden oder Tage. Das Team fasste die Regel: Jede Schema-Änderung erfordert ein Fixture-Paar – valide und negative.
Erkenntnisse: Negative Fixtures sind Regressionstests für das Schema selbst; ihr Bestehen ist Alarm signal, nicht Erfolg
Schema-Änderung ohne Änderung des Fixture-Satzes – klassisches Anti-Pattern, das Spec CI blockieren muss
Drei Prüfebenen (coverage, scope, schema) sind unabhängig: Grün einer kompensiert nicht Rot einer anderen
Verwandte Konzepte: schema-check
fixture
spec_gate
JSON-Diagnose
Titel: Rogue Task und autonomes Schließen: Warum Coverage nicht ausreicht
Szenario: In einem Incident-Projekt implementierte das Team Spec CI mit Abdeckungsprüfung. Jeder REQ-* hatte implements, jede Aufgabe verwies auf eine Anforderung. Im Review sah das wie perfektes Tracing aus.
Herausforderung: Ein Product Manager bat um 'Beschleunigung' der Incident-Auflösung. Ein Entwickler fügte im plan.md die Aufgabe TASK-AUTO-RESOLVE mit implements: [REQ-014] (allgemeine Anforderung 'Diensthabender erhält Eskalationsbestätigung') und Endpoint POST /incidents/{id}/force-resolve hinzu. Formal besteht Verknüpfung, aber der Inhalt – autonomes Schließen ohne Operator – überschreitet das Incident-Response-Domänenmodell. Coverage-check bestand grün.
Lösung: Scope-check auf Domänenmodell-Ebene ausgelöst: Aktion force_resolve gehört nicht zu erlaubten Operationen (acknowledge, escalate, annotate, rollback, notify_on_call). Prüfung berücksichtigte nicht nur Verb, sondern auch Akteur (autonomer Agent vs. Diensthabender) und Endpoint. Diagnose: 'plan.md:48: IR-SCOPE-007 — Autonomous force resolve is outside the incident-response domain model. Action: Replace with POST /incidents/{id}/ack or add an approved requirement and domain rule'.
Ergebnis: Pull-Request blockiert. Das Team diskutierte und lehnte autonomes Schließen als riskant ab. Stattdessen explizite Anforderung REQ-MANUAL-ACK und Aufgabe mit menschlicher Bestätigung hinzugefügt. Domänenmodell blieb unverändert, Vertrauen in Remediation erhalten.
Erkenntnisse: Abdeckungsgraph über Identifikatoren ist stärker als Wortsuche, aber ohne Inhaltsprüfung unzureichend
Scope-check fängt semantische Drift: wenn formale Struktur erhalten, aber Bedeutung geändert
Domänenmodell ist Vertrag zwischen Team und System; seine Verletzung ist gefährlicher als fehlende Tests
Verwandte Konzepte: scope-check
coverage-check
rogue task
domain model
Lerntipps: Beginnen Sie mit dem lokalen Runnable-Beispiel in book2/examples/spec-ci, nicht mit GitHub Actions. Erst lokales grünes Gateway erreichen, dann in CI übertragen
Pre-commit-Hook nur für geänderte Dateien verwenden, vollständigen Lauf dem CI überlassen – spart Zeit und macht Gateway zum gewohnten Zyklus-Teil
Üben Sie an 'schlechten' Diagnosen: Nehmen Sie Meldungen wie 'Coverage failed' und schreiben Sie in Format mit Datei, Zeile, Regel und Maßnahme um
Negative Fixtures parallel zu positiven erstellen – schützt vor 'weichen' Schema-Regressionen
'Verletzungstagebuch' führen: Notieren, welche Fehler spec_gate erfasste, zur Team-Schulung nutzen
Für visuellen Stil: Graphen requirements → plan → domain → schema auf Papier zeichnen, markieren wo welches Gate auslöst
Für auditiven Stil: Kollegen laut erklären, warum push-Trigger in main genauso wichtig ist wie pull_request (direkte Aktualisierung von Dienstdateien)
Für kinästhetischen Stil: Physikalisch implements-Zeile aus plan.md entfernen, Skript ausführen, Blockierung erfahren, dann wiederherstellen
Zusätzliche Ressourcen: GitHub Spec Kit: https://github.com/github/spec-kit — Referenzimplementierung des SDD-Ansatzes, bei dem Anforderungen, Plan und Aufgaben zu prüfbaren Ebenen werden
Runnable-Beispiele des Kapitels: book2/examples/spec-ci/scripts/check_coverage.py und validate_schema.py — lokaler Smoke-Test ohne externe Abhängigkeiten
JSON Schema Validation: https://json-schema.org/understanding-json-schema/ — Spezifikation zur Erstellung strenger Fixture-Verträge
Teil 9 des ersten Bandes: part-09-feature-validation.md — Verknüpfung von validation.md mit Fakten, Basis für Fixture-Verständnis
Teil 16 des ersten Bandes: part-16-team-code-review.md — Team-Review des Beweispakets, Kontext für Automatisierung
Teil 12 des ersten Bandes: part-12-mvp.md — REQ-Identifikatoren und Payload-Schemata im Lernprojekt AgentClinic
Zusammenfassung: Das Spezifikations-Gateway (Spec CI) verwandelt requirements.md, plan.md, validation.md und API-Verträge aus Nachschlagewerken in ausführbare Artefakte, die Merge blockieren. Drei Prüfebenen – coverage (Graph REQ-* → implements), scope (Übereinstimmung mit Incident-Response-Domänenmodell), schema (JSON-Fixtures mit negativen Beispielen) – sind unabhängig und ergänzen Unit-Tests. Kernvorteil: Streit über Spezifikation reduziert sich auf Diagnose mit Datei, Zeile, Regel und Maßnahme, senkt Reviewer-Belastung. Für Einführung: zuerst lokales Runnable-Beispiel, dann GitHub Actions mit obligatorischem spec_gate im Branch-Schutz, immer bei push und pull_request. In Incident-Automatisierung verhindert solche Strenge falsche Eskalationen, gefährliche Auto-Operationen und Vertrauensverlust in Remediation.