Anwendungsteil 10. Schutz von Metriken vor Goodhart: Watchdog-Metriken und Notfallmodus
Status: Empfehlung. Der Schutz von KPIs durch eine gekoppelte Watchdog-Metrik (Guard-Metrik) und einen blockierenden Notfallmodus ist eine etablierte Praxis, die im Google SRE Book beschrieben wird. Die konkreten Schwellenwerte (silent_p0, manual_review_floor, audit_trace_coverage) und das Format validation.md v1.1 sind ein empfohlener Rahmen, den die meisten Teams anpassen.
Für den Lerndurchlauf genügt es, examples/goodhart-validator/ auszuführen und zu sehen, wie ein guter MTTR durch den Anstieg von silent_p0 blockiert wird. Das Metriknetzwerk, die Trace-Felder und die Schwellenwertkalibrierung gehören zum vollständigen Produktionspfad. Wenn weiter unten der Begriff „roter Knopf" auftaucht, lesen Sie ihn als kurze Abkürzung für den formalen Notfallmodus.
In Teil 9 des ersten Bandes reichte eine Metrik pro Prüfung aus: „Bewertung ist nach Veröffentlichung sichtbar", „Summe geht nicht ins Negative". Im Produktionsszenario cdn_error_budget_burn reicht diese Logik nicht mehr. Das Dashboard des Agenten- und Vorfallsjournals aus Teil 11 zeigt nach dem Release ein widersprüchliches Bild, und eine einzelne Metrik erweist sich als Köder. Hier werden wir sie zu einem Netzwerk gekoppelter Watchdog-Metriken ausbauen — das sind Paare aus „KPI + Absicherungsindikator", wobei der zweite verhindert, dass der erste auf Kosten versteckter Schäden optimiert wird. Der Katalog typischer Manipulationen, vor denen dieses Netzwerk schützt, ist in Teil 20. SDD-Antipatterns systematisiert.
Vor dem Lesen
- Anknüpfung an den ersten Band: Teil 9 lehrt, die Tatsache zu prüfen, nicht überzeugende Prosa; Teil 20 zeigt, wie ein Prozess beginnt, das falsche Ziel zu schützen.
- Lokaler Lernfall:
cdn_error_budget_burn, weil ein verbesserter MTTR durch den Anstieg vonsilent_p0blockiert werden kann. - Spur für
capstone/: eine Zielmetrik, eine Guard-Metrik und ein blockiertes Beispiel fürhigh_memory_usage.
- Hauptbegriffe des ersten Durchgangs: Guard-Metrik und Notfallmodus („roter Knopf"). Die übrigen —
silent_p0,manual_review_floor,audit_trace_coverage,edge_drift, Trace-Felder, Metriknetzwerk — sind Referenzmaterial und sollten nur dann geöffnet werden, wenn sie für eine einzelne Zeile incapstone/goodhart-note.mdbenötigt werden. - Was zurückzustellen ist: Metriknetzwerk, Trace-Felder, Drift-Kalibrierung und den vollwertigen Notfallmodus.
Ziel
Bis zum Ende des Abschnitts erstellen Sie eine validation.md, die Goodhart-Fallen im Voraus abfängt und verhindert, dass die LLM-Vorfalls-Pipeline Berichts-KPIs auf Kosten der Triage-Degradation verbessert.
Der Hauptgewinn besteht darin, dass Sie Metriken in steuerbare Ziele und unantastbare Qualitätsinvarianten trennen. Anschließend legen Sie für diese überprüfbare Schwellenwerte, Beweise in Traces und Blockierungen in CI fest.
„Köder-Metriken" bezeichnen hier KPIs, die als Signal nützlich, aber gefährlich werden, wenn sie getrennt von Qualitätsinvarianten optimiert werden. KPI (key performance indicator) ist eine Kennzahl, die das Team durch ein Release verbessern möchte.
Dieser Ansatz setzt den SDD-Zyklus fort: Spezifikation, Prüfkriterien und Iterationen werden vor der Einführung von Änderungen festgelegt, nicht im Nachhinein an ein schönes Ergebnis angepasst (GitHub Spec Kit Quickstart).
Der Effekt „wenn eine Messung zum Ziel wird, hört sie auf, eine gute Messung zu sein" ist klassisch als Goodharts Gesetz bekannt (Wikipedia: Goodhart's law). Die SLO-Definition von Google SRE stützt sich direkt auf diese Vorsicht (SRE Book: Service Level Objectives).
Minimales Lernszenario
Lernfall
Der Produktionsvorfall cdn_error_budget_burn, projiziert auf das Lernjournal der Agenten aus book/part-11-second-feature-phase.md. Das Release verbesserte den MTTR von 660s auf 290s und sieht formal wie ein Erfolg aus. Aber silent_p0 stieg von 0,02 auf 0,18, manual_review_rate fiel von 0,18 auf 0,12. Das Ziel ist zu sehen, dass das CI-Gate diese Verschiebung erkennt und das Merging blockiert, trotz „grünem" MTTR.
Vorbereitung
book2/examples/goodhart-validator/specs/validation.yaml— Invarianten und Prüfung des roten Knopfes.book2/examples/goodhart-validator/fixtures/baseline_metrics.json— Baseline (MTTR 660s, silent_p0 0,02).book2/examples/goodhart-validator/fixtures/new_metrics_good.json— Verbesserung ohne Blinde Flecken.book2/examples/goodhart-validator/fixtures/new_metrics_bad.json— „MTTR-Blindheit" (290s, silent_p0 0,18).book2/examples/goodhart-validator/fixtures/new_metrics_drift.json— Drift an den Korrelationskanten.book2/examples/goodhart-validator/scripts/run_validation.py,compare_drift.py,ci_gate.py.
Schritte
cd book2/examples/goodhart-validator. Erwartung: Sie befinden sich im Beispielverzeichnis, es gibt keine zusätzlichen Abhängigkeiten.- „Guter" Durchlauf:
python3 scripts/run_validation.py --validation specs/validation.yaml --metrics fixtures/new_metrics_good.json. *Erwartung: Rückgabecode 0, StatusPASS, alle drei InvariantenOK.* - „MTTR-Blindheit"-Durchlauf:
python3 scripts/run_validation.py --validation specs/validation.yaml --metrics fixtures/new_metrics_bad.json. *Erwartung: Rückgabecode 1,red_button_mttr_blindnesswird ausgelöst,manual_review_floorundsilent_p0_capsind als FAIL markiert.*
Schlecht: nur den MTTR zu betrachten — das Release ist schneller, scheint „besser".
Gut: Validierung mit Invarianten ausführen — „schneller" wird bei silent_p0=0,18 automatisch blockiert.
- Drift-Durchlauf gegen die Drift-Fixture:
python3 scripts/compare_drift.py --baseline fixtures/baseline_metrics.json --new fixtures/new_metrics_drift.json. *Erwartung:edge_drift > 0,12, Rückgabecode 1.* - Kontrolle: derselbe
compare_drift.pygegen die guten Metriken. *Erwartung:edge_drift <= 0,12, Rückgabecode 0.* - Vollständiges CI-Gate:
python3 scripts/ci_gate.py --validation specs/validation.yaml --baseline fixtures/baseline_metrics.json --new fixtures/new_metrics_bad.json. *Erwartung: Rückgabecode 1, inreasonssind konkrete verletzte Invarianten aufgeführt, nicht ein allgemeinesFAIL.* - Halten Sie den Durchlauf als kurze Anti-Goodhart-Notiz fest: die Zielmetrik hat sich verbessert, aber
silent_p0_capundmanual_review_floorhaben das Release blockiert. Erwartung: beim nächsten Pull-Request mit MTTR-Beschleunigung vergleicht der Validator nicht „grün gegen alte Baseline", sondern gegen die good/bad/drift-Fixturen.
Wenn Qwen Code installiert ist und Sie eine Erklärung für das Review benötigen, führen Sie einen separaten optionalen Schritt aus:
qwen -p "Lies @fixtures/new_metrics_bad.json und @specs/validation.yaml. Welche Invariante darf auch bei MTTR=290s nicht umgangen werden? Ändere keine Dateien." --approval-mode plan
Eine solche Ausgabe ist als Erklärung nützlich, ersetzt aber nicht run_validation.py, compare_drift.py und ci_gate.py.
Kontrolltatsache
Schritt 2 ergibt Rückgabecode 0, Schritte 3 und 4 ergeben Rückgabecode 1 mit konkreter Angabe der verletzten Invarianten. Schritt 6 zeigt dasselbe Verhalten im zusammengesetzten Gate. Wenn das CI-Gate new_metrics_bad.json durchlässt, ist die Validator-Konfiguration abgeschwächt — die Schwelle silent_p0_cap oder manual_review_floor wurde verschoben.
Wie dies in capstone/ landet
Übertragen Sie in capstone/goodhart-note.md eine Zielmetrik, eine Guard-Metrik und ein blockiertes Beispiel. Wenn der wichtigste Prüfungsfall high_memory_usage ist, notieren Sie diesen Durchlauf als Anti-Goodhart-Risiko für denselben Regelkreis: Speicher oder MTTR dürfen nicht auf Kosten von silent_p0, manuellem Audit oder 5xx verbessert werden. Übertragen Sie nicht das gesamte Metriknetzwerk, wenn es nicht neu berechnet wurde; für das Lernminimum reicht es zu zeigen, dass ein verbesserter KPI ohne schützende Invariante nicht durchgeht.
Minimales Snippet:
target_metric: "MTTR <= 5m"
guard_metric: "silent_p0 <= 0.05 and manual_review_rate >= 0.15"
blocked_example: "new_metrics_bad.json"
reason: "MTTR improved, but silent_p0 and manual_review_floor fail"
Überprüfbare Spur
Die Skripte run_validation.py, compare_drift.py und ci_gate.py schreiben Ergebnisse nach stdout und erzeugen kein separates Verzeichnis out/. Für den Lernpfad übertragen Sie das Ergebnis in capstone/goodhart-note.md: Zielmetrik, Guard-Metrik, blockiertes Beispiel und Grund.
Wenn Sie in Ihrem Projekt outputs/goodhart.last-run.txt speichern, sollte es als lesbarer Anhang zum Review vorliegen, nicht als leere Markierung. In SDD gilt ein reproduzierbarer Befehl oder ein lesbares Artefakt als Tatsache, nicht schon das Vorhandensein eines Commits.
Schlüsselideen
Definieren Sie zunächst, welche Kennzahlen Qualitätsinvarianten bleiben und welche zu Optimierungszielen werden und damit manipulierbar sind. Eine Invariante kann nicht durch direkten Druck „verbessert" werden: Sie beschreibt einen minimal zulässigen Systemzustand. Beispiele für Invarianten:
- Audit-Vollständigkeit;
- Anteil manueller Prüfungen;
- Obergrenze für
silent_p0(Anteil „stiller" kritischer Vorfälle, die ohne Eskalation geschlossen wurden).
Ein Optimierungsziel hingegen kann gesenkt oder erhöht werden, aber nur innerhalb eines schützenden Korridors. MTTR ist nützlich als Wiederherstellungsgeschwindigkeit, aber gefährlich als einzige Belohnung für ein Modell oder Team.
In validation.md machen Sie diesen Unterschied explizit. MTTR<=5m kann ein Ziel sein. Dagegen bleiben manual_review_rate>=15%, silent_p0<=5% und audit_trace_coverage==100% Zulassungsbedingungen.
Schlecht:
> MTTR unter 5 Minuten erreichen.
Problem: nacktes Ziel ohne Watchdog-Metriken, direkter Weg zu silent_p0.
Gut:
> MTTR <= 5m AND silent_p0 <= 5% AND manual_review_rate >= 15% AND audit_trace_coverage == 100% — Verletzung einer Bedingung = CI_BLOCK.
Die Goodhart-Falle tritt auf, wenn eine Metrik zum Ersatz für die Realität wird. Das System beginnt, die Art der Messung zu optimieren, nicht die Triage-Qualität. Wenn der MTTR isoliert geprüft wird, lernt das Modell, Vorfälle schneller zu schließen, den Anteil der Eskalationen zu senken und lange Untersuchungen zu vermeiden — gerade diese verschlechtern die durchschnittliche Wiederherstellungszeit.
Im Diagramm sieht das wie ein Sieg aus: MTTR fällt auf 5 Minuten oder darunter. Im operativen Regelkreis kann dies das Gegenteil bedeuten. Komplexe P0 sind nicht verschwunden, sondern unsichtbar geworden, weil sie fälschlich als Fehlalarme, niedrige Dringlichkeit oder „selbstheilende" Ereignisse klassifiziert wurden.
Die „MTTR 5 Minuten"-Falle ist besonders gefährlich für seltene schwere Vorfälle, bei denen die Schließgeschwindigkeit mit der Untersuchungsvollständigkeit konkurriert. In Zahlen sieht das so aus:
- Baseline bei 300 Vorfällen im Replay: MTTR 11:00, Eskalationsanteil 14 %,
silent_p02 %; - neue optimierte Version: MTTR 4:50, Eskalationen 6 %,
silent_p018 %.
Formal hat sich der KPI verbessert. Aber das System übersieht nun häufiger kritische Ereignisse ohne manuelle Prüfung und Eskalation. Blockieren Sie ein solches Release: es verlagert das Risiko aus dem sichtbaren Bericht in zukünftige Wiederholungsvorfälle, Post-Mortem-Regressionen und verlorene Verantwortungsketten.
Antikörper in validation.md sind formale Bedingungen, die verhindern, dass Optimierung den Sinn von Qualität umdefiniert. Das Mindestset sind drei Regeln, und sie müssen gleichzeitig geprüft werden:
| Regel | Was sie schützt | Grenze |
|---|---|---|
manual_review_floor | Anteil der Entscheidungen mit manueller Verifikation | nicht unter 15 % |
| silent_p0_cap | Anteil „stiller" P0, die ohne Eskalation geschlossen wurden | nicht über 5 % | | audit_trace_required | Vollständigkeit der Entscheidungsspur (Prompt, Diff, Quelle) | 100 %, ohne Ausnahmen |
Einzeln betrachtet lassen diese Regeln Schlupflöcher. Hohe Tracebarkeit kompensiert nicht den Anstieg von silent_p0. Manuelle Prüfung ist nutzlos, wenn Prompt, Diff und Entscheidungsquelle nicht rekonstruierbar sind. Konfigurieren Sie den „roten Knopf" so, dass er nicht bei einer einzelnen schlechten Zahl auslöst, sondern bei einer Verletzung des schützenden Regelkreises.
Was als Ziel wählen und was als Schutz
Nicht alle KPIs benötigen den gleichen Schutz. Manuelle Triage-Operation und automatische Remediation haben unterschiedliche Risikostufen, daher unterscheidet sich auch das Mindestset an Invarianten. Die Hauptregel: Je gefährlicher die Aktion, desto mehr Watchdog-Metriken werden dem Ziel-KPI zur Seite gestellt.
| Entscheidungstyp | Was wir verbessern | Was zwingend gepaart sein muss |
|---|---|---|
| Manuelle Triage-Operation | MTTR | Entscheidungsspur vollständig gespeichert |
| Auto-Klassifikation ohne Aktion | Geschwindigkeit und Genauigkeit der Klassifikation | keine stillen P0; Entscheidungsspur gespeichert |
| Auto-Eskalation | Eskalationsverzögerung | keine stillen P0; keine Fehleskalationen |
| Auto-Remediation ohne Zustand | MTTR | keine stillen P0; manuelle Prüfung vorhanden; vollständige Audit-Spur | | Auto-Remediation mit Zustand (DB, Cache) | MTTR | dasselbe + verifiziertes Backup | | Release einer neuen Policy | Genauigkeit im Replay | kein „Drift an Grenzen"; vollständige Audit-Spur |
Die vollständigen englischen Metriknamen (silent_p0, manual_review_floor, audit_trace_coverage, false_escalation_rate, edge_drift, postmortem_gap, backup_verified) mit Schwellenwerten und Formeln sind in Anhang D ausgelagert. Hier ist die Regel wichtig, nicht die Tabelle der Namen: zu jeder Zeile „was wir verbessern" gehört ein oder zwei Wächter aus demselben Risikobereich.
Für gefährliche Aktionen (die letzten drei Zeilen) schalten Sie zusätzlich den „roten Knopf" ein — ein blockierendes Gate, das nicht ohne Referendum aus Kapitel 3 umgangen werden darf. Für manuelle und beobachtende Operationen (die ersten drei Zeilen) genügt eine sanfte Warnung.
Die Tabelle soll nicht zum Dogma werden, sondern helfen zu sehen, was Sie übersehen haben. Wenn in der Zeile „Auto-Remediation mit Zustand" keine Backup-Prüfung steht, ist das ein Signal, validation.md neu zu schreiben, nicht „MTTR zu optimieren".
> [konzeptionelle Schnittstelle] — Struktur von validation.md, die Sie an Ihre Trace-Dateien anpassen.
#### Mindeststruktur validation.md v1.1
version: 1.1
invariants:
- name: manual_review_floor
expression: "manual_review_rate >= 0.15"
- name: silent_p0_cap
expression: "silent_p0 <= 0.05"
- name: audit_trace_required
expression: "audit_trace_coverage == 1.0"
checks:
- name: red_button_mttr_blindness
when: "MTTR <= 5m"
assert: "manual_review_rate >= 0.15 and silent_p0 <= 0.05 and audit_trace_coverage == 1.0"
fail: "CI_BLOCK"
Die vollständige Form mit artifact_inputs, network_consistency und dem exakten Ausdruck für audit_trace_required über COUNT(events_with(...)) finden Sie in [examples/goodhart-validator/specs/validation.yaml](examples/goodhart-validator/specs/validation.yaml).
Die nächste Schutzebene ist der Detektor für versteckte Verzerrungen direkt in der Spezifikation. Betrachten Sie eine Regression als eine Verhaltensänderung der Triage bei unveränderten KPIs. Regression ist hier eine Verschiebung in der Verteilung der Entscheidungen, die in den Aggregaten nicht sichtbar ist.
Grund: Schaden ist nicht immer in den obersten Zahlen sichtbar. MTTR kann gleich bleiben, der Eskalationsanteil kann normal aussehen, aber das Modell verteilt Grenzfälle anders zwischen auto_close, manual_review und defer.
Vergleichen Sie daher in validation.md nicht nur Aggregate, sondern auch Verhaltensmuster:
- Severity-Übergangsmatrix;
- Verteilung der Schließungsgründe;
- Anteil erneut geöffneter Vorfälle;
- Verzögerung bis zum Post-Mortem-Label;
- Veränderung der Beziehung zwischen
manual_review_rateundsilent_p0.
Wenn drift_budget (zulässiger Abweichungskorridor von der Baseline) überschritten wird, blockieren Sie den Build auch bei „grünen" KPIs. Das bedeutet, dass das System bereits den Entscheidungsmodus gewechselt hat.
Um die Hauptfalle zu sehen, genügen drei Metriken und ein Wächter:
flowchart LR
MTTR[MTTR]
silent_p0[silent_p0]
manual_review_rate[manual_review_rate]
audit_trace_coverage[audit_trace_coverage]
silent_p0 -->|zieht MTTR unehrlich nach unten| MTTR
manual_review_rate -->|zieht MTTR ehrlich nach oben| MTTR
audit_trace_coverage -->|begrenzt silent_p0| silent_p0Lesen Sie es so: Man kann MTTR künstlich verbessern, wenn man „stillen" P0 erlaubt, ohne Eskalation geschlossen zu werden. Der Wächter audit_trace_coverage verbietet das Schließen ohne Spur, und manual_review_rate hält den Anteil manueller Prüfungen. Das vollständige Bild mit zusätzlichen Metriken (escalation_rate, postmortem_regression) finden Sie in Anhang D; dort sind auch die formalen Schwellenwerte und Verbindungen.
Binden Sie die Prüfungen an Qwen-Logs, Entscheidungen und Diff-Ketten — sonst sind sie nicht in die Produktion übertragbar, ohne Kontext zu verlieren. Der Mindestbestand der Trace pro Ereignis: trace_id (Kette), prompt_hash (Prompt-Hash), decision (was gewählt wurde), policy_version + diff_id (welche Version und welche Änderung sie einbrachten) und postmortem_label (was die Untersuchung bestätigte). Der vollständige Satz von Feldern mit agent, raw_alert_excerpt, reasoning_delta und review_outcome gehört zum vollständigen Pfad und ist in [examples/templates/validation.md](examples/templates/validation.md) zusammengestellt.
Diese fünf Felder ermöglichen es, nach einer Blockierung technische Fragen zu beantworten: Welche Spezifikationsversion änderte das Verhalten, welcher Prompt verleitete das Modell zur automatischen Schließung, welcher Diff brachte eine neue Heuristik ein. Ohne diese Verknüpfung bleibt validation.md eine Erklärung; mit ihr wird es ein reproduzierbares Audit-Artefakt.
Entwerfen Sie Metriken als Abhängigkeitsnetzwerk, nicht als unabhängige Zähler. Genau das ist network_consistency: Eine Änderung einer Metrik darf nicht im Widerspruch zu verbundenen stehen. Berechnen Sie MTTR, silent_p0, manual_review_rate, escalation_rate, postmortem_regression, rollback_rate und audit_gap gemeinsam neu (siehe obiges Diagramm). Eine lokale Verbesserung einer Größe erzeugt oft Schulden in einer anderen. Das praktische Kriterium ist die Konsistenz der Kanten: Wenn MTTR fällt, aber gleichzeitig die manuelle Prüfung sinkt und der Anteil spät bestätigter P0 steigt, kennzeichnen Sie das System als riskant. Dies verwandelt CI von einer „KPI bestanden/nicht bestanden"-Prüfung in eine Prüfung der Verhaltensstabilität der Triage.
> [konzeptionelle Schnittstelle] — scripts/metrics/network_recompute.py zeigt die Form einer lokalen Neuberechnung des Metriknetzwerks; es gibt keine fertige CLI im Lehrbuch-Repository. Ein lauffähiges Analogon des CI-Gates selbst mit Anti-Goodhart-Prüfungen sind python3 examples/goodhart-validator/scripts/run_validation.py und ci_gate.py (siehe unten „Kontrolltatsache").
#### Aktualisierung des Metriknetzwerks und Validierungs-CI-Gate nach Spec-Änderung
python3 scripts/metrics/network_recompute.py \
--spec specs/incident-spec.md \
--replay data/replay_*.jsonl \
--out .artifacts/metric_network.json
python3 scripts/metrics/ci_gate.py \
--artifact validation.md \
--metric-network .artifacts/metric_network.json \
--traces .artifacts/qwen_trace.ndjson
CONTROL: CI_GATE = PASS if (edge_drift <= 0.12 && silent_p0 <= 0.05 && manual_review_rate >= 0.15 && audit_trace_coverage == 1.0) else CI_BLOCK
Vollständiger Pfad: Schwellenwertkalibrierung
Die Tabelle „Niedrig / Standard / Hoch" für silent_p0, manual_review_rate, edge_drift, audit_trace_coverage, die Übung zur „gefährlichen" gleichzeitigen Schwächung zweier Schutzmaßnahmen und das vollständige Metrik-Abhängigkeitsnetzwerk finden Sie in Anhang D, Abschnitt D.4. Im ersten Durchgang reicht es zu sehen, dass ein schlechtes Release durch die Guard-Metrik blockiert wird.
Beispiele und Anwendung
Beispiel: Ein Team möchte die Bereitschaft einer neuen Triage-Pipeline zu aggressiverer automatischer Schließung nachweisen. Zuerst wird ein Replay-Lauf mit der Zieloptimierung MTTR<=5m gestartet. Dann wird derselbe Vorfall-Satz durch red_button_mttr_blindness geprüft.
Wenn das Ergebnis wie MTTR=4:50, silent_p0=18%, manual_review_rate=12% aussieht, blockieren Sie das Release. Der Grund liegt nicht in der schlechten Geschwindigkeit, sondern in der Verletzung der schützenden Invarianten. Dies ist ein wichtiger Unterschied: Das Ziel wurde erreicht, aber der Qualitätsvertrag wurde gebrochen.
> [konzeptionelle Schnittstelle] — scripts/metrics/simulate.py und validate_red_button.py zeigen die Form der Notfallmodus-Prüfung; es gibt keine fertige CLI im Lehrbuch-Repository. Ein lauffähiges Analogon zur Prüfung derselben Invarianten auf den Lern-Fixturen ist python3 examples/goodhart-validator/scripts/run_validation.py (siehe examples/goodhart-validator/README.md).
#### Beispiel für einen Rotknopf-Lauf im Replay
python3 scripts/metrics/simulate.py \
--scenario data/replay_300.jsonl \
--goal "MTTR<=5m" \
--spec specs/incident-spec.md
python3 scripts/metrics/validate_red_button.py \
--artifact validation.md \
--mode red_button \
--assert "silent_p0<=5% && manual_review_rate>=15% && audit_trace_coverage==1.0"
CONTROL: red_button = BLOCKED (MTTR=4:50, silent_p0=18%, manual_review_rate=12%)
Das zweite Beispiel ist die fehlerhafte automatische Schließung von 40 P0 als „Fehlalarme". Vor dem Post-Mortem sieht die Metrik sauber aus: Vorfälle schnell geschlossen, weniger Eskalationen, Warteschlange wächst nicht.
Nach Abgleich mit den Labels zeigt sich ein anderes Bild. Fünf Ereignisse waren tatsächliche kritische Ausfälle. Genau diese sollten silent_p0, escalation_regret und postmortem_regression erhöhen.
Halten Sie einen solchen Fall in validation.md als prädiktiven Triage-Ausfall fest. Warten Sie nicht auf Benutzerschäden in der Produktion. Verwenden Sie Replay und Post-Mortem-Wahrheit als frühes Blockierungssignal.
In der Praxis speichern Sie validation.md neben der Spezifikation und aktualisieren es nur über denselben Review-Prozess wie die Triage-Regeln. CI baut bei jeder Änderung das Metriknetzwerk neu auf, führt den Replay aus, prüft die Trace-Vollständigkeit und vergleicht das Verhalten mit der Baseline. Eine Schwellenwertänderung — etwa das zulässige silent_p0 von 5 % auf 7 % anzuheben — führen Sie als Änderung des Risikovertrags über die Mutable-Regel aus Teil 3 durch, nicht als technische YAML-Korrektur. Diese Barriere schützt das System vor der schleichenden Aufweichung von Invarianten unter dem Druck bequemer Berichte.
Zusammenfassung
Köder-Metriken sind nicht deshalb gefährlich, weil sie falsch sind. Sie sind nützlich, bis sie zum einzigen Optimierungsziel werden.
Eine zuverlässige validation.md löst fünf Aufgaben:
- trennt Ziele von Invarianten;
- blockiert MTTR-Verbesserungen bei steigendem
silent_p0; - verlangt eine minimale manuelle Verifikation;
- prüft die Drift des Triage-Verhaltens;
- erhält die Beweiskette aus Qwen-Logs, Entscheidungen und Diffs.
> [ausführbar] — Der minimale Smoke-Test für dieses Kapitel liegt in [examples/goodhart-validator/](examples/goodhart-validator/README.md).
cd book2/examples/goodhart-validator
python3 scripts/run_validation.py \
--validation specs/validation.yaml \
--metrics fixtures/new_metrics_good.json
python3 scripts/ci_gate.py \
--validation specs/validation.yaml \
--baseline fixtures/baseline_metrics.json \
--new fixtures/new_metrics_good.json
Das Beispiel mit erwartetem Fehlschlag für das Rotknopf-Szenario verwendet fixtures/new_metrics_bad.json: run_validation.py und ci_gate.py sollten mit Code 1 enden, weil manual_review_floor und silent_p0_cap verletzt sind.
Im nächsten Kapitel wird dieser schützende Regelkreis an reale Monitoring- und Deployment-APIs angeschlossen.
Artefakte und Fertigkeitskriterien
| Artefakt | Fertig, wenn |
|---|---|
Lokaler Lauf book2/examples/goodhart-validator | Optimierungsziel von unantastbarer Invariante getrennt |
| Drei Fixturen: good / bad / drift | new_metrics_good.json besteht, new_metrics_bad.json wird mit konkretem Grund blockiert, new_metrics_drift.json wird von compare_drift.py blockiert | | Ein Blockierungsbeispiel wegen Watchdog-Metrik | MTTR hat sich verbessert, aber das Release wurde wegen silent_p0 oder manual_review_floor blockiert | | Eintrag in capstone/goodhart-note.md | drei Zeilen: Zielmetrik, gepaarte Guard-Metrik, blockierende Bedingung |
Der vollständige Pfad ergänzt validation.md mit Zielmetrik und Qualitätsinvarianten, .artifacts/metric_network.json oder ein lauffähiges Analogon des Metriknetzwerks, ein Replay-Set und einen CI-Gate-Bericht mit edge_drift, silent_p0 und audit_trace_coverage. Betrachten Sie ihn als fertig, wenn der Notfallmodus MTTR<5m bei steigendem silent_p0 blockiert, die Trace-Felder Prompt, Diff, Entscheidung und Post-Mortem-Label verknüpfen, und eine Schwellenwertänderung als Änderung des Risikovertrags umgesetzt ist, nicht als YAML-Kosmetik.
Praxis
cd book2/examples/goodhart-validator && python3 scripts/run_validation.py --validation specs/validation.yaml --metrics fixtures/new_metrics_good.json --json— *Erwartung: Code 0, im JSON"status": "PASS", alle drei Invariantenmanual_review_floor,silent_p0_cap,audit_trace_requiredhaben"ok": true.*python3 scripts/run_validation.py --validation specs/validation.yaml --metrics fixtures/new_metrics_bad.json --json— *Erwartung: Code 1, im JSON"status": "CI_BLOCK", die Prüfungred_button_mttr_blindnesswird ausgelöst mit"fail": "CI_BLOCK"undviolated_invariants: [manual_review_floor, silent_p0_cap]. Ebenso gibtpython3 scripts/compare_drift.py --baseline fixtures/baseline_metrics.json --new fixtures/new_metrics_drift.json --threshold 0.12Code 1 zurück und gibtedge_drift=0.18 threshold=0.12 -> FAILaus.*- Übertragen Sie in
capstone/goodhart-note.mddrei Zeilen: Zielmetrik (MTTR), Guard-Metrik (silent_p0oderaudit_trace_coverage), Rotknopf-Regel. *Erwartung: der nächste Merge-Versuch mit verbessertem MTTR, aber fallendemaudit_trace_coveragewird automatisch blockiert.*
Kontrollfragen
- Warum ist MTTR als einziges Optimierungsziel gefährlich?
- Was unterscheidet eine Qualitätsinvariante von einem KPI?
- Welche Trace-Felder werden benötigt, um eine Goodhart-Regression zu untersuchen?
- Nach einem Release fiel MTTR um 30 %, aber
silent_p0stieg von 4 % auf 12 %. Was werden Sie tun — das Release annehmen, zurückrollen oder zusätzliche Diagnostik verlangen? Was genau prüfen Sie?