Thema: Angewandter Teil 5. Mutationstesten von Spezifikationen
Schwierigkeitsgrad: Mittelstufe
Geschätzte Studienzeit: 6–8 Stunden (Theorie: 2–3 Stunden, Praxis: 4–5 Stunden)
Voraussetzungen: Vertrautheit mit JSON Schema und der Struktur von Given/When/Then-Spezifikationen
Abschluss von Teil 9 des ersten Bandes (Überprüfungsfakten und Validierung)
Abschluss von Teil 20 des ersten Bandes (SDD-Antipatterns)
Grundlegende Fähigkeiten im Umgang mit der Kommandozeile und Python 3
Verständnis der Grundlagen graphenbasierter Strukturen (gerichtete Graphen, DFS)
Erfahrung mit Versionskontrollsystemen (Git)
Lernziele: Einen deterministischen Mutantengenerator mit festem Seed starten und bei erneutem Durchlauf denselben Satz von mutation_id reproduzieren
Einen Validierungskontur einrichten, der Mutanten auf dem erwarteten Given/When/Then-Schritt mit exaktem Diagnosecode ablehnt
Die vektorielle Immunitätsmetrik berechnen und interpretieren (strict_reject_rate, depth_of_diagnostics, recovery_time_p95_ms) und Schwellenwerte für CI-Gates anwenden
Jeden Mutanten mit einer konkreten JSON-Schema-Regel und einem Spezifikationsschritt verknüpfen und Nachverfolgbarkeit in SDD gewährleisten
Einen minimalen, reviewfähigen Trail in capstone/validation.md für die Integration des Mutationstestens in den Merge-Prozess erstellen
Überblick: Das Mutationstesten von Spezifikationen ist eine Ingenieurpraxis am Frontier der Standardisierung, die den Validator vom passiven Syntax-Wächter in ein Werkzeug anatomischer Diagnostik verwandelt. Kern des Ansatzes: Eine korrekte Spezifikation (base_spec.json) wird kontrolliert "verdorben", entartete Szenarien eines Incident-Prozesses werden erzeugt, und der Validator muss jeden Defekt auf einem streng definierten Schritt mit vorhersehbarem Diagnosecode abfangen. Das Schlüsselprinzip lautet: "Ein Mutant — ein erwarteter Fehlschlag". Ergebnis ist eine vektorielle Immunitätsmetrik aus drei Komponenten: strict_reject_rate (Anteil strenger Ablehnungen am erwarteten Schritt), depth_of_diagnostics (nützliche Diagnosetiefe vor dem Stopp) und recovery_time_p95_ms (Zeit bis zum stabilen Verdikt). Die Praxis ist eng mit dem "Specification-First"-Ansatz verknüpft und verwandelt absurde Fälle in einen Regressionssatz gegen zukünftige toxische Anforderungen. Das Lehrmaterial stützt sich auf das Runnable-Beispiel in examples/stress-mutator/ mit dem Incident appointment_latency_spike und vier Mutationsoperatoren: Nullify, FutureTime, EscalationCycle, PriorityContradiction.
Schlüsselkonzepte: Mutationstesten von Spezifikationen: Technik, bei der ein Referenzartefakt (base_spec.json) durch Mutationsoperatoren kontrolliert verzerrt wird und der Testkontur verpflichtet ist, jeden Defekt abzufangen. Unterscheidet sich von der manuellen Erstellung einzelner Defekte (Kapitel 2) durch Massenhaftigkeit und Reproduzierbarkeit, von der Verifikation von Gegenbeispielen (Kapitel 4) durch Bindung an einen Katalog von Operatoren, von der Datei-Arbitrage (Kapitel 8) durch Generierung statt Prüfung fertiger Artefakte.
Immunitätsmetrik (immunity score): Vektorielle Metrik der Validator-Widerstandsfähigkeit aus drei Komponenten: strict_reject_rate (Anteil der Fälle, die streng am erwarteten Schritt abgelehnt werden), depth_of_diagnostics (nützliche Diagnosetiefe vor der Ablehnung, gemessen als Anzahl bedeutsamer Schritte in stack_route) und recovery_time_p95_ms (Zeit bis zur Rückkehr eines stabilen Verdikts). Wird als Vektor statt Skalar eingeführt, um Situationen zu vermeiden, in denen wachsende Strenge mit Diagnoseblindheit oder Leistungsdegradation einhergeht.
Prinzip "Ein Mutant — ein erwarteter Fehlschlag": Hauptregel der Mutationsfabrik. Jeder Mutant enthält genau eine Änderung und hat einen festen expected_failure mit Diagnosecode und Stoppunkt halt_before. Verbietet zusammengesetzte Mutationen, die Ursachenlokalisierung unmöglich machen. Schlecht: Ein Mutant setzt gleichzeitig service_id auf Null, dreht den Eskalationsgraphen um und invertiert Prioritäten. Gut: Der Mutator Nullify setzt nur severity auf Null, expected_failure.code = EMPTY_REQUIRED_FIELD, halt_before = When:evaluate_sla_window.
Mutationsfabrik: Deterministischer Mutator über einem korrekten base_spec.json. Parst die Spezifikation in einen AST mit Given/When/Then-Knoten, SLA-Matrix, Eskalationsregeln und JSON-Schema-Fragmenten. Wendet Operatoren mit festem Seed für Reproduzierbarkeit an. Kritisch für das Duell von Verifikator und Implementor: Ein streitiger Fall kann reproduziert, beiden Rollen übergeben und auf Vertragsverletzung geprüft werden.
Mutationsoperatoren: Nullify (Feld auf Null setzen — leerer String, null, leeres Array), FutureTime (Zeitstempel in die Zukunft verschieben relativ zum vereinbarten now), EscalationCycle (Rückwärtskante im Eskalationsgraphen hinzufügen), PriorityContradiction (gegenseitig widersprüchliche Prioritätsregeln einführen). Zukünftige Erweiterungen: RecursiveDependency (indirekte Rekursion zwischen berechneten Feldern).
Validator-Vakzinierung: Bildhafte Bezeichnung für gewöhnliches Mutationstesten von Spezifikationen. Der Validator erhält kontrolliert verdorbenen Input und muss ihn am erwarteten Schritt ablehnen. Verwandelt absurde Fälle in eine "Impfung" gegen Regressionen.
Klassen entarteter Szenarien: Leere Felder (jegliche Leere, ohne die keine sichere Aktion wählbar ist: leere Strings, leere Eigentümer-Arrays, fehlende severity, service_id, runbook_ref), zeitliche Anomalien (formal korrekte ISO-Zeitstempel mit verletzter Kausalität), umkehrbare Eskalationszyklen (unendliche Eigentümer-Neudefinition), rekursive Abhängigkeiten (indirekte Berechnungsketten mit potenziellem unendlichem Aufrollen).
Determinismus und Seed: Ein fester Generator-Seed (z. B. 20260517) garantiert bitweise Identität von manifest.json bei wiederholten Durchläufen. Zwei aufeinanderfolgende Durchläufe mit identischer mutation_id-Reihenfolge sind minimale Qualitätskontrolle. Ohne Determinismus sind keine Regressionsbasis und kein Rollenduell möglich.
Graphenprüfungen außerhalb von JSON Schema: JSON Schema prüft Datenform gut, aber drückt kein topologisches Verhalten von Routen aus. Für EscalationCycle baut der Validator einen gerichteten Graphen auf und startet DFS mit white/gray/black-Zuständen. Erkennung eines gray-Knotens liefert den minimalen Zyklus. Für PriorityContradiction — analoge Kontrolle umkehrbarer Übergänge mit Unterscheidung der Codes CYCLE_ESCALATION und PRIORITY_REVERSAL.
Zeitanker und max-reaction-lag-Politik: Drei obligatorische Anker: event_detected_at, event_received_at, vereinbartes now aus kontrollierter Zeitquelle. Drei Ablehnungscodes: INVALID_TIME_ANCHOR (response_timestamp in der Zukunft — Problem der Eingangsbelastung), NEGATIVE_RESPONSE_LAG (negative Verzögerung — Problem der Normalisierung), STALE_INCIDENT_WINDOW (Ereignis älter als das Fenster — Problem der SLA-Regel). Unterschiedliche Codes sind kritisch für das SDD-Journal.
Rekursive Abhängigkeiten und max_resolution_depth: Unterscheiden sich von Zyklen durch Fehlen einer kurzen Schleife. Typische Kette: owner ← priority ← blast_radius ← owner_group ← owner. Aufrollungslimit (z. B. 8) mit Versuchstrail. Überschreitung → RECURSION_LIMIT mit Feldkette statt Maskierung als Timeout. Schützt LLM-Ausführer vor unendlichem Verfeinern.
CI-Mutationsgate: Blockierung des Merges bei Verletzung einer der drei Schwellen: strict_reject_rate < 0,98, depth_of_diagnostics < 3, recovery_time_p95_ms > 1200. Blockiert auch das Übergehen alter mutation_id, Verschlechterung der Diagnosetiefe, Zeitlimit-Überschreitung. Beispiel: python3 scripts/ci_gate.py --strict-reject-min 0.98 --diag-depth-min 3 --recover-ms-p95 1200 --fail-on-regression.
Reviewfähiger Trail und SDD-Beweise: Minimaler Fragment in capstone/validation.md: Seed, Operatorenliste, drei Immunitätsmetriken, Verdikt. Vollständiger Trail: mutation_id, Spezifikations-Diff, Original- und mutierte Fragmente, Ablehnungsjournal, Diagnosecode, stack_route, Verweis auf JSON-Schema-Regel. Katalog out/mutations — lokal, nicht committet; Quelle der Wahrheit — reproduzierbarer Befehl.
Übungsaufgaben: Titel: Überprüfung der Deterministik des Mutantengenerators
Problem: Ihnen liegt ein korrektes base_spec.json und das Skript mutate_specs.py mit seed=20260517 vor. Sie müssen beweisen, dass der Generator deterministisch ist: Zwei aufeinanderfolgende Durchläufe müssen identisches manifest.json ergeben. Ein Student führte das Skript einmal aus und sah 4 Mutanten-Dateien. Der Reviewer kann die Reproduzierbarkeit nicht prüfen. Korrigieren Sie das Verfahren und erklären Sie, warum ein einziger Durchlauf nicht ausreicht.
Lösung: Schritt 1: Ersten Durchlauf starten: python3 scripts/mutate_specs.py --base base/base_spec.json --seed 20260517 --operators Nullify,FutureTime,EscalationCycle,PriorityContradiction --out out/mutations_run1. manifest.json speichern. Schritt 2: out/mutations_run1 löschen und denselben Befehl mit out/mutations_run2 erneut starten. Schritt 3: Vergleich durch diff out/mutations_run1/manifest.json out/mutations_run2/manifest.json. Erwartung: 0 Unterschiedszeilen. Schritt 4: Vergleich mit Referenz: diff out/mutations_run1/manifest.json manifest.example.json. Erwartung: 0 Unterschiedszeilen. Schritt 5: Stabilität der mutation_id-Reihenfolge prüfen: jq '.mutations | map(.mutation_id)' out/mutations_run1/manifest.json muss mit run2 übereinstimmen. Erklärung: Ein Durchlauf unterscheidet nicht zwischen deterministischem Generator und zufälligem Rauschen. Nur der wiederholte Durchlauf schafft eine Regressionsbasis. Ohne dies sind Verifikator/Implementor-Duell und CI-Prüfung unmöglich.
Schwierigkeit: Anfänger
Titel: Lokalisierung eines Mutanten-Lecks durch Diagnosetiefe
Problem: Der Mutant Nullify setzt severity auf Null. Der Validator stoppte am Schritt Then:notify_primary_owner mit Code MISSING_OWNER statt des erwarteten EMPTY_REQUIRED_FIELD bei When:evaluate_sla_window. strict_reject_rate = 1,0 (alle abgelehnt), aber depth_of_diagnostics = 1,2 (unter Schwelle 3). Analysieren Sie, warum dies eine Regression ist, und beschreiben Sie minimale Änderungen am Validator und expected_failures.json zur Wiederherstellung der Schwelle.
Lösung: Schritt 1: Problem diagnostizieren. Leere severity lief zu tief: Der Validator prüfte die Feldpflichtigkeit nicht am Eingang (Given:incident_received) und versuchte, den Eigentümer anhand ungültiger Daten zu berechnen. Dies birgt das Risiko falscher Benachrichtigung über einen nicht klassifizierten Incident. Schritt 2: Guard im Normalisierer hinzufügen: Prüfung von severity.minLength und severity ∈ enum vor der Phase evaluate_sla_window. Schritt 3: fake_validator.py aktualisieren: Bei leerer severity EMPTY_REQUIRED_FIELD zurückgeben mit halt_before = When:evaluate_sla_window, stack_route = ['schema.normalize', 'Given:incident_received', 'field.severity.check', 'halt']. Schritt 4: expected_failures.json prüfen: Für mutation_id m_20260517_nullify_855e4297f7 wird code=EMPTY_REQUIRED_FIELD, halt_before=When:evaluate_sla_window, depth=4 erwartet. Schritt 5: immunity_score.py neu starten. Erwartung: strict_reject_rate bleibt 1,0, depth_of_diagnostics stellt sich auf ≥3 wieder her, recovery_time_p95_ms wird separat geprüft. Lehre: Hoher strict_reject_rate verbirgt blinde Diagnostik. Die vektorielle Immunitätsmetrik fängt solche Regressionen ab.
Schwierigkeit: Mittelstufe
Titel: Einrichtung des CI-Gates mit Berücksichtigung der Operator-Prioritäten
Problem: Post-Mortem-Historie zeigt, dass 60 % der Production-Incidents mit fehlerhaften Zeitfenstern zusammenhängen, 25 % — mit Eskalationszyklen, 10 % — mit leeren Feldern, 5 % — mit Prioritätskonflikten. Ihr Token-Budget liegt bei 100 Mutanten pro Durchlauf. Die standardmäßige gleichmäßige Verteilung (25 pro Klasse) spiegelt die historische Verwundbarkeit nicht wider. Bauen Sie die Operator-Auswahlpolitik um, begründen Sie die Wahl und zeigen Sie, wie dies expected_failures.json und Immunitätsschwellen beeinflusst.
Lösung: Schritt 1: Gleichmäßige Verteilung durch historiegewichtete ersetzen: FutureTime 40 Mutanten, EscalationCycle 25, Nullify 20, PriorityContradiction 10, Reserve 5 für neue Muster. Schritt 2: In mutate_specs.py --operator-weights FutureTime=0.40,EscalationCycle=0.25,Nullify=0.20,PriorityContradiction=0.10 setzen. Schritt 3: expected_failures.json aktualisieren: Detaillierung zeitlicher Codes erhöhen (INVALID_TIME_ANCHOR, NEGATIVE_RESPONSE_LAG, STALE_INCIDENT_WINDOW) mit unterschiedlichen halt_before für jeden Untertyp. Schritt 4: Schwellen überdenken: Bei steigender Mutantenanzahl kann strict_reject_rate auf 0,99 angehoben werden, depth_of_diagnostics bei ≥3 belassen (aber ≥4 für zeitliche Anomalien fordern), recovery_time_p95_ms durch Optimierung der Graphenprüfungen auf 1000 senken. Schritt 5: In ci_gate.py --weighted-fail-on-regression hinzufügen, der nicht nur globale Metriken, sondern auch per-operator strict_reject_rate vergleicht. Schritt 6: Begründung in validation.md dokumentieren: "Priorität FutureTime erhöht gemäß Post-Mortems Q1–Q3 2024, siehe Verweis auf Incidents #INC-2047, #INC-2089". Lehre: Gezieltes Fuzzing-Testen prüft historisch brüchige Stellen statt Budget auf gleichmäßiges Chaos zu verschwenden.
Schwierigkeit: Fortgeschritten
Titel: Tracing rekursiver Abhängigkeit und Konfiguration von max_resolution_depth
Problem: Der Mutant RecursiveDependency erzeugt eine Kette: owner wird aus priority berechnet, priority aus blast_radius, blast_radius fragt owner_group, owner_group erfordert owner. Der Validator stürzt nach 30 Sekunden mit Timeout ab. stack_route fehlt. Der Entwickler schlägt vor, "einfach den Timeout auf 60 Sekunden zu erhöhen". Widerlegen Sie diese Lösung, implementieren Sie max_resolution_depth mit reproduzierbarem Trail und zeigen Sie den Eintrag in validation.md.
Lösung: Schritt 1: Timeout-Erhöhung ablehnen: Dies maskiert das Problem, macht CI unvorhersehbar, liefert keine Diagnostik zur Vertragskorrektur. Schritt 2: In fake_validator.py einen Abhängigkeitsresolver mit Auflösungsstack-Tracking hinzufügen: resolution_stack = [], bei Feldeintritt — push, bei Austritt — pop, bei wiederholtem push desselben Feldes — Zykluserkennung. Schritt 3: max_resolution_depth = 8 setzen. Bei Überschreitung RECURSION_LIMIT mit vollständiger Kette zurückgeben: ['owner', 'priority', 'blast_radius', 'owner_group', 'owner']. Schritt 4: Versuchstrail in das Journal hinzufügen: resolution_attempts mit Zeitstempel jedes Schritts. Dies ermöglicht die Unterscheidung von Rekursion und einfach komplexer Abhängigkeit. Schritt 5: In immunity_score.py prüfen, dass für RecursiveDependency-Mutanten depth_of_diagnostics den Auflösungstrail enthält (gezählt als len(resolution_attempts) bis zur Erkennung). Schritt 6: Eintrag in validation.md: ``yaml stress_run: seed: 20260517 operators: [Nullify, FutureTime, EscalationCycle, PriorityContradiction, RecursiveDependency] recursive_guard: max_resolution_depth: 8 verdict: PASS strict_reject_rate: "1.0 >= 0.98" depth_of_diagnostics: "5 >= 3" recovery_time_p95_ms: "400 <= 1200" `` Lehre: Unendliches Aufrollen muss beobachtbar und kontrollierbar sein, nicht durch Timeout ersetzt werden.
Schwierigkeit: Fortgeschritten
Fallstudien: Titel: Einführung des Mutationstestens in eine Plattform zur automatischen Incident-Verwaltung
Szenario: Ein SRE-Plattformteam (150 Ingenieure, 40 Mikroservices) verwaltete Incidents über eine automatisierte Pipeline mit JSON-Schema-Validator am Eingang. Nach einer Reihe von Production-Incidents, bei denen leere severity-Felder bis zur Benachrichtigungsphase durchsickerten und falsche Eskalationen zum VP on-call auslösten, entschied sich das Team, Mutationstesten von Spezifikationen einzuführen. Basisszenario — appointment_latency_spike (SLA 10 Minuten, Eskalation appointments_oncall → sre_lead).
Herausforderung: Drei Schlüsselprobleme: (1) Der Validator prüfte JSON-Syntax, fing aber keine semantischen Defekte — leerer String severity passierte minLength=0 wegen eines Schema-Fehlers; (2) Reproduzierbarkeit fehlte: Manuelle Testfälle wurden ad-hoc erstellt und gingen bei Spezifikationsaktualisierungen verloren; (3) CI ließ Regressionen durch, weil die einzige Metrik "alle Tests grün" Verschlechterung der Diagnostik verbarg — der Validator begann, GENERIC_VALIDATION_FAILED statt exakter Codes zurückzugeben, und die Debug-Zeit stieg von 15 Minuten auf 4 Stunden.
Lösung: Das Team führte eine Mutationsfabrik auf Basis von stress-mutator aus dem Lehrgang ein. Schritt 1: Fester Seed=20240715 und 4 Operatoren (Nullify, FutureTime, EscalationCycle, PriorityContradiction) mit Priorität FutureTime=0,45 laut Incident-Historie. Schritt 2: Verknüpfung jedes Mutanten mit Given/When/Then-Schritt und JSON-Schema-Regel — z. B. Nullify(severity) → Given:incident_received, $.properties.severity.minLength. Schritt 3: Vektorielle Immunitätsmetrik mit Schwellen: strict_reject_rate ≥ 0,98, depth_of_diagnostics ≥ 3, recovery_time_p95_ms ≤ 1200. Schritt 4: CI-Gate, das Merge bei jeder Verletzung oder beim Übergehen alter mutation_id blockiert. Schritt 5: SDD-Beweise: mutation_id, Diff, stack_route, Verweis auf Regel. Schritt 6: Für Graphenprüfungen DFS mit white/gray/black-Zuständen hinzugefügt, für zeitliche — drei Anker und drei Ablehnungscodes.
Ergebnis: Innerhalb von 3 Monaten: strict_reject_rate stieg von 0,71 auf 0,99, depth_of_diagnostics — von 1,8 auf 4,2, recovery_time_p95_ms — von 3400 auf 890 ms. Die Anzahl falscher Eskalationen durch leere Felder sank um 94 %. Die Untersuchungszeit für Validierungs-bezogene Incidents fiel von einem Median von 4 Stunden auf 25 Minuten. Eine Schlüsselregression wurde in der PR-Phase gefangen: Ein Entwickler änderte die Prüfreihenfolge, was halt_before für FutureTime-Mutanten von When:evaluate_sla_window auf Then:notify_owner verschob; das CI-Gate blockierte den Merge, und das Team rollte die Änderung vor Analyse zurück.
Gelernte Lehren: Vektorielle Immunitätsmetrik ist kritisch: Anstieg von strict_reject_rate auf 0,99 bei Fall von depth_of_diagnostics auf 1,2 wäre ohne dreikomponentige Kontrolle falscher Erfolg gewesen
Determinismus (fester Seed) ermöglicht, Mutationen in Regressionssatz zu verwandeln: Alte mutation_id werden zur "Vakzine" gegen zukünftige Änderungen
SDD-Beweise mit stack_route und Verweisen auf JSON Schema verkürzen Onboarding-Zeit neuer Ingenieure von einer Woche auf einen Tag
Priorisierung von Operatoren nach Post-Mortem-Historie ist effektiver als gleichmäßige Verteilung: 45 % Budget auf FutureTime erzielte 78 % Abdeckung historischer Defekte
Verwandte Konzepte: Immunitätsmetrik (strict_reject_rate, depth_of_diagnostics, recovery_time_p95_ms)
Prinzip "Ein Mutant — ein erwarteter Fehlschlag"
Determinismus und Seed
CI-Mutationsgate
Graphenprüfungen außerhalb von JSON Schema
SDD-Beweise und reviewfähiger Trail
Titel: Scheitern durch Ignorieren von recovery_time bei großem Release
Szenario: Eine E-Commerce-Plattform bereitete sich auf den Black-Friday-Verkauf vor. Das Validatorteam fügte 50 neue Mutationsoperatoren für die Prüfung von Spezifikationen des Zahlungskonturs hinzu. strict_reject_rate = 0,97, depth_of_diagnostics = 3,5 — innerhalb der Schwellen. Das CI-Gate ließ den Release durch.
Herausforderung: recovery_time_p95_ms stieg unbemerkt von 800 ms auf 4500 ms wegen komplexer Graphenprüfungen auf Zyklen in Zahlungsrouten. In der Spitzenlast wurde der Validator zum Engpass: 12 % der Anfragen liefen bei Validierung in Timeouts, was kaskadiert Retries und Überlastung von Downstream-Services auslöste. Das Team prüfte recovery_time bei Release nicht und betrachtete es als "Hilfsmetrik".
Lösung: Release-Rollback innerhalb von 45 Minuten. Analyse zeigte, dass DFS auf einem Graphen aus 200 Eskalationsknoten für jede Anfrage statt gecachter topologischer Sortierung ausgeführt wurde. Optimierung: Vorab-Graphenanalyse beim Laden der Spezifikation, inkrementelle Prüfung bei Mutationen. Einführung harter Schwelle recovery_time_p95_ms ≤ 1200 mit Merge-Blockierung. Hinzufügen eines Alerts bei Überschreitung von 800 ms über 3 Durchläufe hinweg.
Ergebnis: Nach Optimierung sank recovery_time_p95_ms auf 600 ms. Am Black Friday verarbeitete der Validator 340 % Spitzenlast ohne Timeouts. Schlüsseländerung des Prozesses: recovery_time wurde zur gleichberechtigten Komponente des Immunitätsvektors statt "Bonusmetrik".
Gelernte Lehren: Dreikomponentiger Immunitätsvektor schützt vor Optimierung einer Metrik auf Kosten anderer
recovery_time ist kritisch für Production-Last: Ein "richtiger" Validator, der CI ausbremst, provoziert Umgehungspraktiken und Production-Ausfall
Inkrementelle Graphenprüfungen sind effektiver als vollständiges DFS pro Anfrage bei unveränderter Topologie
Verwandte Konzepte: Immunitätsmetrik und recovery_time_p95_ms
CI-Mutationsgate
Graphenprüfungen außerhalb von JSON Schema
Inkrementelle Validierung
Studientipps: Arbeiten Sie das Material sequentiell ab: Zuerst das Runnable-Beispiel (Schritte 1–7), dann die Theorie der Schlüsselideen, dann die Kontrollfragen. Der Versuch, Theorie ohne Skriptausführung zu lesen, erzeugt Illusion des Verstehens
Führen Sie zwingend den wiederholten Durchlauf mit demselben Seed durch und vergleichen Sie manifest.json via diff. Dies ist minimale Qualitätskontrolle, die nicht übersprungen werden darf. Fixieren Sie das Ergebnis per Screenshot oder Terminalkopie
Erstellen Sie eine Zuordnungstabelle: Mutationsoperator → Klasse entarteten Szenarios → Given/When/Then-Schritt → JSON-Schema-Regel → Diagnosecode → erwartetes halt_before. Diese Tabelle ist Grundlage für die Konfiguration Ihres eigenen Projekts
Experimentieren Sie mit Schwellenverletzungen: Ändern Sie fake_validator.py vorübergehend, um einen Mutanten durchzulassen oder halt_before zu verschieben, und beobachten Sie, welche Vektorkomponente dies fängt. Praktisches Verständnis von Regression ist wichtiger als theoretisches Wissen
Für visuellen Lernstil: Zeichnen Sie das Blockdiagramm aus der Mermaid-Diagramm des Kurses auf Papier und markieren Sie, wo sich Ihr Projekt vom Lehrbeispiel appointment_latency_spike unterscheidet
Für auditiven Stil: Erklären Sie das Prinzip "Ein Mutant — ein erwarteter Fehlschlag" einem Kollegen oder in einer Sprachnachrichten-Aufnahme. Wenn Sie es nicht in 60 Sekunden klar formulieren können — kehren Sie zum Material zurück
Für kinästhetischen Stil: Modifizieren Sie base_spec.json durch Hinzufügen eines neuen Feldes (z. B. runbook_ref), erstellen Sie einen Nullify-Operator dafür, aktualisieren Sie expected_failures.json und führen Sie die vollständige Pipeline durch. Manuelles Erstellen eines neuen Operators beschleunigt das Erlernen
Nutzen Sie den optionalen Schritt mit Qwen Code als Review-Training, nicht als Ersatz für Runnable-Prüfung. Vergleichen Sie seine Ausgabe mit Ihren Fakten aus immunity_score.py — Abweichungen signalisieren Verständnis- oder Toolproblem
Führen Sie ein "Mutationsjournal" in separater Datei: Für jeden Durchlauf fixieren Sie Seed, Operatoren, drei Metriken, unerwartetes Verhalten. Dieses Journal wird Grundlage von capstone/validation.md und hilft, Lernfortschritt zu verfolgen
Beim Übergang zum Production-Track (Schwellenkalibrierung, CI-Gate) konsultieren Sie Anhang D.1, aber erst nach sicherem Durchlaufen des Minimalsszenarios. Vorzeitiges Eintauchen in Kalibrierungsfeinheiten lenkt vom Verständnis der Grundprinzipien ab
Gruppenlernen: Organisieren Sie ein "Duell" — ein Teilnehmer ändert base_spec.json oder fake_validator.py, der andere muss finden, welcher mutation_id kaputt ging. Dies modelliert reale Verifikator/Implementor-Interaktion
Zusätzliche Ressourcen: Quellcode des Lehrbeispiels stress-mutator: book2/examples/stress-mutator/ — Runnable-Beispiel mit base_spec.json, Mutations-, Validierungs- und Immunitätsberechnungsskripten. Primärquelle für alle praktischen Schritte
Github spec kit: https://github.com/github/spec-kit — "Specification-First"-Ansatz, auf den sich das gesamte Kapitel stützt. Vertrag geht Planung und Code-Implementierung voraus
Teil 9 des ersten Bandes (Überprüfungsfakten): ../book/part-09-feature-validation.md — Disziplin der Given/When/Then-Fakten, ohne die Mutationen sinnlos sind. Mutant prüft genau den Fehlschlagsfakt am erwarteten Schritt
Teil 20 des ersten Bandes (SDD-Antipatterns): ../book/part-20-sdd-antipatterns.md — Katalog klassischer Prozessfehler, an die Mutationsoperatoren gebunden sind
Teil 11 (Lehrfeature /agents): ../book/part-11-second-feature-phase.md — Ursprung des Lehrfalls appointment_latency_spike
Teil 12 (MVP und leerer Review-Text): ../book/part-12-mvp.md — einfachstes Beispiel der Faktendisziplin: Leerer Review-Text muss abgelehnt werden. Hier wird dieselbe Logik auf Operatorsätze verallgemeinert
Teil 10 (Goodhart-Validator und ci_gate.py): examples/goodhart-validator/scripts/ci_gate.py — ideenverwandtes Beispiel eines CI-Gates mit Schwellenwerten
Anhang D.1 (Schwellenkalibrierung): appendix-d-threshold-calibration.md#d1-мутационное-тестирование-глава-5 — vollständiger Production-Track: Tabelle "Niedrig/Standard/Hoch", Übung zur Schwellenverschiebung, Signale zur Neubewertung
JSON Schema-Dokumentation: https://json-schema.org/ — Nachschlagewerk für formale Einschränkungen, die durch Graphen- und Zeitprüfungen außerhalb des Schemas ergänzt werden
Zyklensuchalgorithmus in gerichtetem Graphen (DFS white/gray/black): Klassische Implementierung nach Tarjan oder CLRS (Cormen, Leiserson, Rivest, Stein) — Grundlage für EscalationCycle und RecursiveDependency
Zusammenfassung: Das Mutationstesten von Spezifikationen verwandelt den Validator vom passiven Syntax-Wächter in ein aktives Werkzeug anatomischer Diagnostik. Schlüsselprinzipien: Deterministische Mutationsfabrik mit festem Seed, strenge Regel "Ein Mutant — ein erwarteter Fehlschlag", vektorielle Immunitätsmetrik aus drei Komponenten (strict_reject_rate, depth_of_diagnostics, recovery_time_p95_ms), Verknüpfung jedes Mutanten mit Given/When/Then-Schritt und JSON-Schema-Regel, CI-Gate mit Regressionsblockierung, SDD-Beweise mit mutation_id und stack_route-Trail. Lehrminimum — Ausführung von examples/stress-mutator/ mit reproduzierbarem manifest.json, Durchlaufen aller Mutanten durch erwartete Fehlschläge und grüner Immunitätsmetrik. Der reviewfähige Trail wird in capstone/validation.md als Seed, Operatoren, drei Metriken und Verdikt fixiert. Die Praxis zielt auf Erstellung eines Generators entarteter Spezifikationen für reale Projekte der automatischen Incident-Verwaltung, wo absurde Fälle zu Regressionsabwehr gegen toxische Anforderungen und versteckte Ausfallkaskaden werden.