Anwendungsorientierter Teil 11. Integration mit einer echten API: von der Spezifikation bis zum Deployment
Status: Empfehlung. Die SDD-Phasentrennung Specify/Plan/Tasks/Implement/Validate und das 25-Punkte-Readiness-Modell sind ein empfohlener Rahmen. Sie erfordern im Übungsdurchlauf kein echtes Kubernetes, kein GitOps und keinen externen Executor.
Frontier. Vollständig automatisierte Auto-Remediation ohne manuelle Bestätigung (Human-Review) auf dem kritischen Pfad bleibt eine Frontier: Selbst Teams mit großer SDD-Erfahrung halten den Menschen im Loop. Von den eingebauten Befehlen von Qwen Code ist hier nur /plan; die übrigen Schritte sind benutzerdefinierte Befehle oder direkte qwen -p-Aufrufe über Projektskripte.
Für den Übungsdurchlauf reicht die lokale Pipeline examples/real-api/: Webhooks normalisieren, das Readiness-Gateway passieren und die verbotene Aktion blockieren. GitOps, die Kubernetes-API und vollständige Auto-Remediation gehören zum vollständigen Produktions-Track.
> [runnable] — Ein lauffähiges Analogon der Pipeline „Webhook → Normalisierung → Readiness-Gateway → Probelauf" liegt in [examples/real-api/](examples/real-api/README.md). Die Skripte laufen mit der Standardbibliothek ohne externe Abhängigkeiten; sie ersetzen keine Produktionsinfrastruktur, ermöglichen es aber, das Gateway lokal zu durchlaufen und zu sehen, welche Bedingungen die Aktion blockieren.
Das Szenario high_memory_usage ist der Höhepunkt der Leseabschnitte zu derselben SQLite-Datenbank, die wir in Teil 12 des ersten Bandes aufgebaut haben, und wendet denselben Trick der idempotenten Migration an. Nur diesmal wird es aus Betriebssicht betrachtet. Der in Teil 7, Teil 8 und Teil 9 des ersten Bandes erarbeitete Zyklus Specify → Plan → Tasks → Implement wird hier weder aufgehoben noch ersetzt. Er wird in ein Produktions-Gateway eingewickelt und endet mit einer Team-Review des Beweispakets im Sinne von Teil 16.
Vor dem Lesen
- Anknüpfung an den ersten Band: Teile 7–9 legen den Zyklus Spezifikation–Plan–Validierung fest, Teil 16 — die Team-Review.
- Lokaler Übungsfall:
high_memory_usage, der kanonische Fall des gesamten ersten Durchlaufs.
- Spur für
capstone/: Readiness-Verdikt, zwei blockierende Bedingungen und ein erlaubter Dry-Run. - Hauptbegriffe des ersten Durchlaufs:
readinessund Dry-Run. 25-Punkte-Rubrik,audit_trace, GitOps, Executor — nachschlagbar. - Was zurückzustellen ist: GitOps, Kubernetes-API, vollständiger Executor und Auto-Remediation ohne manuelle Bestätigung.
Ziel
Im Übungsminimum prüft dieses Kapitel die kurze Kette Webhook -> Normalisierung -> Readiness -> Dry-Run für high_memory_usage. Der vollständige Produktions-Track erweitert sie um GitOps-Deployment, Rollback von Änderungen und Readiness-Bewertung vor einer eingeschränkten Auto-Remediation. Jede Aktion muss mit den Artefakten Specify/Plan/Tasks/Implement/Validate verknüpft sein und darf nicht in manuellen Befehlen verloren gehen.
Das praktische Ergebnis des ersten Durchlaufs ist kein Produktions-Orchestrator, sondern der Beweis, dass eine erlaubte Aktion das Readiness besteht und eine verbotene blockiert wird, bevor das System verändert wird.
readiness (Reife/Bereitschaft) ist hier eine formale Bewertung der Pipeline auf einer 25-Punkte-Skala mit Schwellenwert 23/25. Auto-Remediation bedeutet in diesem Kapitel ein eingeschränktes Playbook mit vorab genehmigten Aktionen (pre-approved actions), Rollback-Bedingungen und manueller Bestätigung durch eine Person (Human-Review). Es ist keine Erlaubnis für den Agenten, willkürlich an der Produktion zu ändern.
Von den eingebauten Befehlen von Qwen Code in dieser Pipeline ist nur /plan. Die übrigen Schritte — /sdd:specify, /sdd:tasks, /sdd:validate — richten Sie als benutzerdefinierte Befehle in .qwen/commands/sdd/ ein oder ersetzen Sie sie durch gewöhnliche Prompts über qwen -p und Projektskripte.
Minimales Übungsszenario
Übungsfall
Der Produktionsvorfall high_memory_usage für appointments-api — abgeleitet aus der MVP-Phase und den SQLite-Migrationen aus book/part-12-mvp.md. Die Pipeline: Grafana+PagerDuty-Webhook → normalize_webhook.py → Readiness-Gateway nach dem 25-Punkte-Modell → Probelauf gegen eine Liste vorab genehmigter Aktionen. Das Ziel ist es, den gesamten Weg von der rohen Nutzlast bis zum kontrollierten restart_pod zu durchlaufen und sich zu vergewissern, dass die blockierenden Bedingungen (Audit, Stateful) den Fehler genau dort abfangen, wo sie es sollen.
Vorbereitung
book2/examples/real-api/fixtures/webhook_grafana.json,webhook_pagerduty.json— rohe Nutzlasten mit demselbenincident_key.book2/examples/real-api/fixtures/incident_event.expected.json— Referenz des normalisierten Ereignisses.book2/examples/real-api/fixtures/readiness_pass.json(24/25),readiness_block_audit.json(22/25 + Audit unter 1,0),readiness_block_stateful.json(24/25, aber Stateful ohne Backup).book2/examples/real-api/specs/high_memory_usage/specify.md— vorab genehmigterestart_podundscale_up_replicas_one.book2/examples/real-api/scripts/normalize_webhook.py,check_readiness.py,dry_run.py.
Schritte
cd book2/examples/real-api. Erwartung: Sie befinden sich im Beispielverzeichnis, keine zusätzlichen Abhängigkeiten.python3 scripts/normalize_webhook.py --grafana fixtures/webhook_grafana.json --pagerduty fixtures/webhook_pagerduty.json --expected fixtures/incident_event.expected.json. *Erwartung: Rückgabecode 0, normalisiertesincident_eventstimmt feldweise mit der Referenz überein.*python3 scripts/check_readiness.py --readiness fixtures/readiness_pass.json. *Erwartung: Rückgabecode 0,PASS incident=HM-2026-05-17-01 score=24/25.*
python3 scripts/check_readiness.py --readiness fixtures/readiness_block_audit.json. *Erwartung: Rückgabecode 1, Grund —audit_trace_coverage=0,7 < 1,0, zuzüglich Abwertung nach Punktesumme (22/25).*python3 scripts/check_readiness.py --readiness fixtures/readiness_block_stateful.json. *Erwartung: Rückgabecode 1, Grund —stateful workload ohne bestätigtes Backup, obwohl die Summe 24/25 beträgt.*
Schlecht: dry_run.py vor dem Readiness-Gateway ausführen — die Aktion ist formal durch die Spezifikation erlaubt, aber audit_trace_coverage oder backup_verified könnten fehlen. Gut: Zuerst das Readiness-Gateway, Probelauf nur bei Rückgabecode 0 vom Gateway — die Reihenfolge stellt sicher, dass der Konsequenzradius bekannt ist, bevor die Aktionsliste geprüft wird.
python3 scripts/dry_run.py --spec specs/high_memory_usage/specify.md --action restart_pod. *Erwartung: Rückgabecode 0,PASS: action=restart_pod erlaubt (2 actions in spec).*python3 scripts/dry_run.py --spec specs/high_memory_usage/specify.md --action delete_namespace. *Erwartung: Rückgabecode 1,BLOCK: action="delete_namespace" nicht in den pre-approved gefunden.*
- Für das Übungsminimum hören Sie hier auf: Die runnable-Kette hat Normalisierung, PASS für den erlaubten Pfad und BLOCK für audit/stateful/delete-namespace gezeigt.
Falls Qwen Code installiert ist und Sie eine Erklärung für die Review benötigen, führen Sie einen separaten optionalen Schritt aus:
qwen -p "Lies @fixtures/readiness_block_audit.json und @specs/high_memory_usage/specify.md. Was muss ergänzt werden, damit Readiness 23/25 und audit_trace_coverage=1,0 erreicht? Dateien nicht ändern." --approval-mode plan
Diese Anfrage gehört nicht zum Runnable-Minimum. Ihre Ausgabe kann der Review beigefügt werden, aber die Readiness-Freigabe muss sich auf check_readiness.py und dry_run.py stützen.
Kontrollfakt
Schritte 3, 6 — PASS. Schritte 4, 5, 7 — BLOCK mit konkretem Grund in stderr. Wenn Schritt 5 bei stateful=true, backup_verified=false durchgeht, ist das Readiness-Gateway defekt: Der harte Block für Stateful lässt sich nicht umgehen.
Wie dies in capstone/ landet
Übertragen Sie in capstone/readiness.md das Readiness-Ergebnis, die zwei blockierenden Bedingungen und das Resultat von dry_run.py für die erlaubte Aktion. In capstone/validation.md führen Sie die Befehle auf, die tatsächlich ausgeführt wurden. GitOps, Kubernetes-API und der vollständige Executor gehören nicht zum Übungsminimum, sofern sie nicht implementiert wurden.
Lesen Sie diesen Abschnitt so: Eine positive Fixture zeigt den zulässigen Pfad, zwei blockers halten die konkreten Fehlerursachen fest, dry_run ist der Grenzfall zwischen erlaubter und blockierter Aktion. Fehlt auch nur eine Zeile, ist das Readiness-Paket unvollständig.
readiness:
pass_fixture: "readiness_pass.json -> 24/25"
blockers:
- "audit_trace_coverage=0.7 blocks auto mode"
- "stateful=true without backup_verified blocks action"
dry_run: "restart_pod PASS; delete_namespace BLOCK"
Überprüfbare Spur
Die Skripte schreiben nach stdout/stderr und erzeugen kein out/. Halten Sie den Lauf in einem lesbaren Artefakt fest: einer kurzen capstone/readiness.md oder einem CI-Bericht, falls in Ihrem Projekt vorhanden. Der Mindestinhalt sind dieselben vier YAML-Zeilen aus dem obigen Block (pass_fixture, zwei blockers, dry_run); der vollständige 25-Punkte-Bericht ist nur im vollständigen Track nötig.
Erzeugen Sie keinen Commit-Marker um des Commits willen. Für das Lehrbuch zählt eine reproduzierbare Spur, die ohne Chat-Verlauf lesbar ist.
Schlüsselideen
Der Startpunkt der Trace ist audit_trace (das Live-Log von Qwen Code), in dem eingehender Webhook und Spec-Diffs als eine kausale Spur erfasst werden. Für den Vorfall HM-2026-05-17-01 verknüpft der erste Eintrag incident_event.json, den benutzerdefinierten Befehl /sdd:specify und die erzeugte Datei specs/high_memory_usage/specify.md. Fehlt eines dieser Elemente, hat die Pipeline bereits ihre Beweisbarkeit verloren. Das minimale Log-Fragment: webhook_received -> incident_event_normalized -> /sdd:specify -> spec_diff_created; jeder weitere Diff verweist auf dieselbe incident_id. /sdd:specify ist eine Projekterweiterung; richten Sie sie als benutzerdefinierten Befehl in .qwen/commands/sdd/specify.md ein oder ersetzen Sie sie durch direktes qwen -p.
Normalisieren Sie Grafana- und PagerDuty-Alarme zu einem einheitlichen incident-event. Andernfalls diktieren verschiedene Quellen unterschiedliche Versionen desselben Vorfalls. Grafana liefert Metriken und das Beobachtungsfenster, z. B. memory_percent=93 über 10m. PagerDuty ergänzt Priorität, Service-Bindung und Eskalationsstatus. Der Normalisierer führt sie zu den Feldern service, namespace, pod, severity, window_minutes, metric_context, source_refs zusammen. Danach beschreibt der Specify-Schritt nur noch WHY und WHAT: Warum ist ein Eingriff nötig und welches Ergebnis gilt als Erfolg. Es wählt weder Bibliothek, SDK noch konkreten API-Endpunkt.
Was das praktisch bedeutet. Vergleichen wir zwei Specify-Varianten für denselben Vorfall:
Schlecht:
> Specify für high_memory_usage: Pod per kubectl delete pod ... neu starten
Problem: Specify wählt sofort den Implementierungsbefehl und blockiert den Plan.
Gut:
> Specify für high_memory_usage: memory_percent < 80 % für 5 Minuten nach der Aktion halten. Pre-approved actions: restart_pod, scale_up_replicas_one. Audit-Trace ist verpflichtend.
Die SDD-Phasentrennung schützt die Pipeline vor verfrühter Implementierung. Jede Phase ist für ihren Bereich zuständig:
- Specify hält User Story, Erfolgskriterien, funktionale und nicht-funktionale Constraints fest;
- Plan wählt die Strategie;
- Tasks zerlegt sie in ausführbare Schritte;
- Implement wendet Änderungen über einen kontrollierten Mechanismus an.
Diese Struktur entspricht dem praktischen Phasenrahmen Specify → Plan → Tasks → Implement aus GitHub Spec Kit (siehe auch GitHub Spec Kit Quickstart). In der Produktion ist dies wichtig, weil das Modell nicht das Recht erhält, einen Vorfall „sofort zu heilen", bevor Ursache, Eingriffsgrenzen und Ergebniskontrolle nachgewiesen sind.
Erweitern Sie den Kern des Kapitels nicht zum gesamten Produktions-Orchestrator. Im ersten Durchlauf wird hier nur die Kette Webhook -> Normalisierung -> Readiness -> Dry-Run geprüft. Die übrigen Mechanismen aus früheren Kapiteln dienen als Kontrollpunkte:
- Der Verifier aus den Teilen 4 und 8 ist nötig, wenn der Dry-Run ein strittiges Gegenbeispiel aufruft.
- Die Schichtbudgets aus Teil 9 sind nötig, wenn
frontier-reviewerbeginnt, nicht nur High-Risk-Branches zu bedienen. - Anti-Goodhart aus Teil 10 ist nötig, wenn Memory auf Kosten von 5xx, Latenz oder manuellem Audit fällt.
Sind diese Mechanismen noch nicht zusammengestellt, versuchen Sie nicht, sie innerhalb von Kapitel 11 zu simulieren. Vermerken Sie sie als Blocker oder Verweise auf die entsprechenden Kapitel und schließen Sie den Mindestlauf mit dem Readiness-Verdikt und dem Dry-Run-Ergebnis ab.
Für high_memory_usage beginnen Sie den Plan mit minimaler Wirkung. Der Basis-/plan wählt den Neustart des konkreten Pods mit Priorität auf den Konsequenzradius. Dann prüft er die Notwendigkeit eines Scale-up. Und erst danach lässt er eine Erweiterung der Aktion bei erhaltenem Rollback-Pfad zu.
Der Tasks-Schritt gliedert dies in Operationen: Stateless-Charakter des Workloads bestätigen, einen Probelauf (Dry-Run) ohne reale Änderungen ausführen, nur den Ziel-Pod löschen, RSS, CPU, 5xx beobachten; bei fehlender Verbesserung innerhalb des Fensters — Rollback aktivieren und human_review anlegen.
Die Validierung schließt den Auto-Remediation-Kreislauf erst nach Prüfung realer Metriken, des Sicherheits-Gateways und der GitOps-Fixierung (dies ist Teil des Frontier-Szenarios, siehe Kapitelkopf). In validation.md prüfen Sie vier Bedingungen:
- Memory bleibt in zwei aufeinanderfolgenden Fenstern unter dem Schwellenwert;
- 5xx steigt nicht;
- Latenz degradiert nicht;
- Rollback ist beschrieben und ausführbar.
Nach erfolgreicher Prüfung landen sechs Basis-Artefakte in GitOps: Spezifikation, Plan, Tasks, Diffs, Entscheidungslog und 25-Punkte-Bericht. Eine Verfassungsaktualisierung wird bei Bedarf hinzugefügt. Ohne diese kann ein Vorfall technisch gemildert, aber nicht als kontrolliert geschlossen gelten.
Vollständiger Track: 25-Punkte-Readiness-Modell
Im ersten Durchlauf genügt es, zwei Fakten zu verstehen: readiness_pass.json besteht, und die audit/stateful-Fixtures werden blockiert. Die vollständige Rubrik unten ist nötig, wenn Sie dieses Gateway in einen realen Produktionsprozess überführen und erklären müssen, warum der Schwellenwert gerade so gewählt ist.
Das Modell bewertet fünf Kategorien auf einer Skala von 0–5 und liefert eine Gesamtsumme. Punkte werden nach Artefakten vergeben, nicht nach Eindruck. Lässt sich ein Kriterium nicht durch Datei, Log oder Schema belegen, wird die niedrigere Bewertung vergeben. Nachfolgend die Rubriken je Kategorie.
Der Schwellenwert 23/25 ist ein Kompromiss aus „streng, aber nicht lähmend" für das Übungsmodell AgentClinic-Produktion: bis zu zwei „behebbare" Beanstandungen mit „4" in unterschiedlichen Kategorien (4+4+5+5+5 = 23) oder eine „4" bei den übrigen „5" (24/25). Eine „3" oder niedriger in nur einer Kategorie senkt die Summe sofort auf 22 oder weniger und entzieht die Auto-Freigabe. Unter 23: 20–22/25 versetzt die Pipeline in den halbmanuellen Modus mit Bestätigung durch eine Person nach jedem Implement-Schritt. Höher — Schwellenwert 24/25 — drückt Auto bei jeder kleinen Beanstandung in den halbmanuellen Modus, und das Team beginnt, das Modell zu ignorieren. Kalibrieren Sie nach dem Risikoprofil: Zahlungsverkehr und Gesundheitswesen — Auto ≥24/25; interne Werkzeuge erlauben 21–22/25, aber nur als halbmanuell oder Canary, nicht als produktionsreife Auto-Remediation.
Spec — Vollständigkeit von WHY/WHAT/Constraints
| Punkte | Spec |
|---|---|
| 5 | WHY/WHAT/Constraints sind explizit, Akzeptanzkriterien sind vorhanden, kein Out-of-Scope im Plan, Given/When/Then ist vorhanden |
| 4 | WHY/WHAT explizit, Constraints vorhanden, aber ein Punkt im Plan hat kein implements: |
| 3 | WHY ist vorhanden, WHAT ist unscharf, Constraints sind teilweise |
| 2 | Einer der drei Blöcke (WHY/WHAT/Constraints) fehlt |
| 1 | Nur Symptombeschreibung, weder WHY noch WHAT noch Constraints |
| 0 | Es gibt keine Spezifikation |
Implementation — Idempotenz und kontrollierte Änderungen
| Punkte | Implementation |
|---|---|
| 5 | Alle Tasks sind idempotent, Probelauf (Dry-Run) ist vorhanden, Konsequenzradius ist explizit auf Pod/Deployment-Ebene angegeben, Änderungen laufen über GitOps |
| 4 | Idempotenz und Probelauf sind vorhanden, aber ein Task ändert Zustand ohne vorherige Prüfung |
| 3 | Probelauf nur für Teile der Schritte, Konsequenzradius ist textlich beschrieben, ohne explizites Feld |
| 2 | Kein Probelauf, Änderungen werden direkt am Cluster vorbei an GitOps angewendet |
| 1 | Tasks sind nicht idempotent, ein erneuter Lauf bricht den Zustand |
| 0 | Aktionen werden manuell ausgeführt, ohne Fixierung in Tasks |
Verification — Given/When/Then, Schemata, Stresstest, Monitoring
| Punkte | Verification |
|---|---|
| 5 | Given/When/Then deckt Happy- und Negative-Path ab, JSON-Schema validiert Ein- und Ausgaben, Stresstest-Spezifikation und Post-Metriken in zwei Fenstern sind vorhanden |
| 4 | Alle Elemente sind vorhanden, aber die Stresstest-Spezifikation deckt nur eine Klasse von Verletzungen ab |
| 3 | Given/When/Then und Schema sind vorhanden, aber Monitoring wird in nur einem Fenster geprüft |
| 2 | Nur Given/When/Then, ohne Schema und ohne Post-Metriken |
| 1 | Validierung reduziert sich auf Exit-Code-Prüfung oder einen einzelnen Screenshot |
| 0 | validation.md fehlt oder wird nicht ausgeführt |
Process — Tracing „Webhook → CLI → Diff → Replay"
| Punkte | Process |
|---|---|
| 5 | Jeder Schritt (Webhook, Normalisierung, CLI-Befehl, Diff, Commit, Validate) ist über incident_id verknüpft, das Log ist reproduzierbar, ein Replay liefert denselben Diff |
| 4 | Tracing ist vollständig, aber Replay erfordert manuelles Einsetzen einer Variable |
| 3 | Webhook und CLI sind verknüpft, aber der Diff ist nicht an incident_id gebunden |
| 2 | Log ist vorhanden, aber die Schrittreihenfolge lässt sich nur anhand der Zeit rekonstruieren |
| 1 | Aktionen sind im Chat festgehalten, nicht in Dateien |
| 0 | Kein Tracing, Vorfallquelle unbekannt |
Security — Schutzmaßnahmen, Notabschaltung, Rollback, Eskalation
| Punkte | Security |
|---|---|
| 5 | Guardrails verbieten die Erweiterung des Konsequenzradius, Notabschaltung (Emergency Stop) ist vorhanden, Rollback-Bedingung ist vor der Ausführung festgehalten, Eskalation zur manuellen Bestätigung bei Unsicherheit |
| 4 | Alle Elemente sind vorhanden, aber die Eskalation ist nur textlich beschrieben, ohne formalen Trigger |
| 3 | Rollback und Guardrails sind vorhanden, Notabschaltung fehlt |
| 2 | Nur Rollback, ohne Guardrails und ohne Eskalation |
| 1 | „Manueller Rollback" ist beansprucht, aber kein ausführbarer Pfad ist beschrieben |
| 0 | Sicherheits-Gateway ist nicht definiert, Aktionen laufen uneingeschränkt |
Wie gezählt wird und was Merges blockiert
Die Punktesumme ergibt das Gesamtergebnis von 0 bis 25. Der Pass-Schwellenwert für die Auto-Freigabe ist 23/25: Unter dieser Grenze erhält die Pipeline nicht den Status produktionsreif, selbst wenn drei Kategorien das Maximum erreichen. Eine Null in Security ist bei jeder Summe verboten. 0 in dieser Spalte bedeutet fehlenden Schutzkreis und blockiert selbst den halbmanuellen Modus, bis ein Minimum an Rollback, Guardrails und Eskalation vorhanden ist.
Blockierende Bedingungen sind unabhängig von der Summe. Jeder dieser Fälle blockiert das Merge einzeln:
- fehlgeschlagene Validation (Verification ≤ 2);
- fehlender Rollback (Security ≤ 2);
- unbestimmter Konsequenzradius (Implementation ≤ 2 ohne explizites Feld).
Bei einem Ergebnis von 20–22 wird die Pipeline nur im halbmanuellen Modus zugelassen und nur, wenn keine der oben genannten blockierenden Bedingungen vorliegen: Stopp nach jedem Implement-Schritt, explizite manuelle Bestätigung, zwingende Aktualisierung der Spezifikation und Neubewertung, bevor in den Auto-Kreis zurückgekehrt wird.
Checkliste vor dem Produktions-Cutover
Wird beim Überführen des Gateways in einen realen Prozess verwendet — jeder Punkt ist an die Rubrik gebunden, in der ein versteckter Punkteabfall möglich ist:
- [ ] Spec enthält WHY/WHAT/Constraints und ist an
incident_idgebunden; jeder Task hat einimplements:auf eine REQ-Kennung. - [ ] Probelauf wird vor realen Änderungen geloggt; Konsequenzradius ist auf Pod- oder Deployment-Ebene fixiert, nicht in Worten.
- [ ] JSON-Schema validiert
incident_eventund den abschließendenvalidation_report; Given/When/Then deckt Happy- und Negative-Path ab. - [ ] Rollback-Bedingung ist vor der Ausführung festgehalten und auf der Staging-Umgebung geprüft; Notabschaltung ist dem Operator ohne Cluster-Zugang zugänglich.
- [ ] Die Spur
webhook → CLI → diff → commit → validateist überincident_idreproduzierbar; manuelle Bestätigung wird bei wiederholtem Fehlschlag oder Erweiterung des Konsequenzradius automatisch ausgelöst.
Beispiel einer ausgefüllten Rubrik für high_memory_usage
| Kategorie | Punkte | Begründung |
|---|---|---|
| Spec | 5 | WHY (OOMKill verhindern), WHAT (RSS unter 80 % über 10 Minuten), Constraints (Stateful nicht antasten, Rollback nach 6 Minuten) explizit, Given/When/Then zusammengestellt |
| Implementation | 4 | Tasks sind idempotent, Probelauf ist vorhanden, aber der Scale-up-Branch hat keinen eigenen Probelauf-Schritt |
| Verification | 5 | Given/When/Then, JSON-Schema auf incident_event und validation_report, Stresstest-Spezifikation auf verstecktes Leck, Post-Metriken in zwei Fenstern |
| Process | 5 | incident_id=HM-2026-05-17-01 verknüpft Webhook, /sdd:specify, Diff, Commit und Replay |
| Security | 4 | Guardrails auf Stateful-Workloads, Rollback und Notabschaltung sind vorhanden, Eskalation textlich beschrieben ohne formalen Trigger |
| Gesamt | 23/25 | Produktionsreif nach Schwellenwert, aber der Scale-up-Branch bleibt bis zu einem eigenen Probelauf halbmanuell |
Vollständiger Track: Schwellenwertkalibrierung
Die Tabelle „Niedrig / Standard / Hoch" für den Readiness-Schwellenwert, die Übung zur Überschreibung von THRESHOLD und die Signale zur Überprüfung finden sich in Anhang D, Abschnitt D.5. Im ersten Durchlauf ist das Minimum des Kapitels bereits nachgewiesen, wenn readiness_pass.json besteht, die audit/stateful-Fixtures blockiert werden und delete_namespace nicht in der Liste der vorab genehmigten Aktionen erscheint.
Beispiele und Anwendung
Ein praktisches Eingangslog für Qwen Code kann so beginnen: POST /hooks/grafana meldet memory_percent=93, pod=api-7b4, namespace=appointments-api, window=10m. Dann bestätigt POST /hooks/pagerduty severity=critical und verknüpft das Ereignis mit dem Service appointments-api. Der Normalisierer erzeugt ein incident_event mit incident_id=HM-2026-05-17-01, entfernt sensible Felder, hängt Quellverweise an und ruft den benutzerdefinierten Befehl /sdd:specify --event incident_event.json --preset high_memory_usage oder den gleichwertigen qwen -p-Prompt auf — beide Varianten gehören zum empfohlenen Rahmen aus dem Kapitelkopf und werden durch Projektbefehle rund um Qwen Code realisiert.
Der erste Diff in specify.md hält drei Blöcke fest: WHAT (RSS unter 80 % über 10 Minuten senken), WHY (OOMKill und Latenzanstieg verhindern), Constraints (Stateful-Workloads nicht antasten, HPA nicht ändern, Rollback nach 6 Minuten ohne Verbesserung haben). Bei /plan vergleicht das System zwei Strategien: (A) Neustart des Ziel-Pods und Beobachtung; (B) Neustart plus temporäres Scale-up auf vier Replikate. Der Verifier führt Given/When/Then aus: Given Pod ist stateless und Memory liegt 10 Minuten lang über 90 %; When wird nur der Ziel-Pod neu gestartet; Then muss Memory unter 80 % fallen und 5xx den zulässigen Schwellenwert nicht überschreiten. Zeigt die Stresstest-Spezifikation, dass Scale-up eine Änderung der Rollout-Politik erfordert oder ein Speicherleck durch Replikatwachstum verschleiert, bleibt Variante B ein Reserve-Branch mit manueller Bestätigung, keine automatische Aktion.
Im Implement-Schritt wird zunächst der Probelauf ausgeführt. Dann läuft der Commit über GitOps und wird nur bei grünem Validator-Status mit ArgoCD synchronisiert. Der Executor schließt den PagerDuty-Vorfall nicht sofort nach dem Neustart. Er wartet zwei Monitoring-Fenster ab, gleicht validation.md ab, prüft das Sicherheits-Gateway und fügt im Kommentar Verweise auf Spec, Tasks, Commit und Validierungsergebnis hinzu. Sinkt Memory nach 6 Minuten nicht oder steigt 5xx, wird der Rollback-Pfad aktiviert, ein human_review angelegt und die Readiness-Bewertung unter Berücksichtigung des fehlgeschlagenen Verification-Kriteriums neu berechnet.
Zusammenfassung
Die Readiness der Produktionspipeline wird durch das 25-Punkte-Modell fixiert: fünf Kategorien (Spec, Implementation, Verification, Process, Security) mit gleichem Gewicht von 5 Punkten spiegeln die Phasen des SDD-Zyklus wider. Gleiches Gewicht ist ein Prinzip: Keine Kategorie kompensiert eine Lücke in einer anderen, daher erlaubt der Schwellenwert 23 höchstens zwei partielle Lücken in der Summe. Produktionsreif bedeutet nicht unter 23/25 ohne kritische Verstöße gegen Validation und Sicherheits-Gateway. Ein Abfall unter den Schwellenwert versetzt die Auto-Remediation in den halbmanuellen Modus, bis Spezifikation, Politik oder Ausführungspfad korrigiert sind. Vollständig automatisierte Remediation bleibt ein Frontier-Szenario aus dem Kapitelkopf: Lassen Sie sie erst nach Ansammlung von Replay-Beweisen und einem Operator-Probelauf zu. Ein solcher Kreis verwandelt jeden künftigen Vorfall in eine überprüfbare Systemverbesserung.
Fehler als Teil des Vertrags
Eine Produktions-API darf nicht nur PASS oder BLOCK zurückgeben, sondern auch einen Fehlertyp, nach dem der Orchestrator die Wiederherstellung wählt. Alle Fehler in failed zu mischen ist gefährlich: Ein fehlendes Feld im Webhook, ein LLM-Timeout, die Nichtverfügbarkeit der Kubernetes-API und ein Safety-Verbot erfordern unterschiedliche Aktionen.
Minimale Taxonomie für dieses Kapitel:
| Code | Wo er auftritt | Aktion |
|---|---|---|
VALIDATION_ERROR | incident_event besteht das Schema nicht | anhalten, behebbaren Grund zurückgeben |
LLM_CALL_FAILED | Modell erstellt keine Spezifikation oder keinen Plan | Retry mit Limit, dann Degraded Mode ohne Auto-Aktionen |
TOOL_EXECUTION_FAILED | check_readiness.py, dry_run.py oder eine externe API liefert Fehler | falls retryable — wiederholen; sonst eskalieren |
AGENT_WORKFLOW_FAILED | Die Kette webhook → specify → readiness → dry_run hat einen obligatorischen Schritt verloren | Auto-Modus blockieren und correlation_id protokollieren |
Für high_memory_usage bedeutet Degraded Mode: Ereignis normalisieren, readiness.md schreiben, dem Operator den empfohlenen nächsten Schritt zeigen, aber restart_pod nicht automatisch ausführen. Das ist ehrliche Degradation: Das System bewahrt Beweise und erweitert den Konsequenzradius nicht, wenn Modell oder Werkzeug nicht verfügbar sind.
Artefakte und Reifekriterien
| Artefakt | Reif, wenn |
|---|---|
Normalisiertes incident_event | stimmt feldweise mit examples/real-api/fixtures/incident_event.expected.json überein; Specify fixiert WHY/WHAT/Constraints und wählt keinen Remediation-Befehl |
| Lokaler Lauf des Readiness-Gateways | readiness_pass.json besteht; audit/stateful-Fixtures werden mit konkretem Grund blockiert |
dry_run.py auf erlaubter und verbotener Aktion | restart_pod PASS, delete_namespace BLOCK |
| Error Taxonomy | jeder BLOCK gibt einen stabilen Code, Retryability und correlation_id an |
Eintrag in capstone/readiness.md | Score, blockierende Bedingungen, ein tatsächlich ausgeführter Befehl |
Der vollständige Track ergänzt specs/high_memory_usage/specify.md, plan.md, tasks.md und validation.md, einen GitOps-Diff oder Commit, der mit incident_id verknüpft ist, das Entscheidungslog webhook → CLI → diff → commit → validate und eine ausgefüllte 25-Punkte-Readiness-Tabelle mit Belegen. Betrachten Sie ihn als fertig, wenn Plan und Tasks Konsequenzradius, Probelauf, Rollback-Bedingung und Trigger für manuelle Bestätigung aufweisen; die Validation zwei Metrik-Fenster, 5xx, Latenz und Sicherheits-Gateway prüft; benutzerdefinierte Befehle entweder als Projektbefehle eingerichtet oder durch qwen -p-Prompts bzw. Projektskripte ersetzt sind; das Readiness-Ergebnis nicht unter 23/25 ohne blockierende Bedingungen zu Rollback, Verification oder Konsequenzradius liegt.
Praxis
cd book2/examples/real-api && python3 scripts/normalize_webhook.py --grafana fixtures/webhook_grafana.json --pagerduty fixtures/webhook_pagerduty.json --expected fixtures/incident_event.expected.json— *Erwartung: Code 0, normalisiertesincident_eventstimmt feldweise mit der Referenz überein.*- Führen Sie die vier Prüfungen einzeln aus (jede gibt einen eigenen Code zurück, daher passt
&&dazwischen nicht):
python3 scripts/check_readiness.py --readiness fixtures/readiness_pass.json
python3 scripts/check_readiness.py --readiness fixtures/readiness_block_audit.json
python3 scripts/dry_run.py --spec specs/high_memory_usage/specify.md --action restart_pod
python3 scripts/dry_run.py --spec specs/high_memory_usage/specify.md --action delete_namespace
*Erwartung: readiness_pass → Code 0, PASS incident=HM-… score=24/25; readiness_block_audit → Code 1, BLOCK … score=22/25 mit Gründen „score 22/25 unter Schwellenwert 23" und „audit_trace_coverage=0,7 < 1,0 — vollständige Abdeckung erforderlich"; restart_pod PASS, delete_namespace BLOCK.*
- Bewerten Sie Ihren Fall nach dem 25-Punkte-Modell und füllen Sie die folgende Tabelle aus. Für jede Kategorie geben Sie Punkte, Beleg-Artefakt und Grund für eine Abwertung an, falls die Punktzahl kleiner als 5 ist. Berechnen Sie die Summe, prüfen Sie blockierende Bedingungen und formulieren Sie, was geändert werden muss, damit die Pipeline den Schwellenwert 23/25 erreicht. *Erwartung: In jeder Tabellenzeile sind alle drei Felder ausgefüllt; „Beleg-Artefakt" verweist auf eine konkrete Datei oder einen Lauf, nicht auf eine allgemeine Formulierung; die Summenzelle enthält eine Zahl der Form
N/25und eine Liste blockierender Bedingungen oder das explizite „keine Blocker".*
| Kategorie | Punkte (0–5) | Beleg-Artefakt | Grund der Abwertung |
|---|---|---|---|
| Spec | |||
| Implementation | |||
| Verification | |||
| Process | |||
| Security | |||
| Gesamt | Blockierende Bedingungen: | Was vor dem Wechsel zu ändern ist: |
Kontrollfragen
- Warum soll Specify keinen konkreten Remediation-Befehl wählen?
- Welche Bedingungen machen Auto-Remediation unzulässig?
- Was blockiert die Freigabe, wenn Readiness unter 23/25 liegt?
- Ein Webhook zu
high_memory_usagekam außerhalb der Arbeitszeit, die automatische Remediation ist bereit, den Pod neu zu starten. Das Readiness-Modell liefert 22/25 (minus 3 für unvollständiges Audit). Was tun Sie — neu starten, auf den Morgen warten oder den Bereitschaftsdienst rufen?