Skip to content

feat(dashboard): Wilson-CI der Fehlerquote sichtbar + Delta gegen letzte n>=20-Version (#196 P4+P5)#225

Merged
TillQuandel merged 2 commits into
masterfrom
feat/196-wilson-ci
Jul 12, 2026
Merged

feat(dashboard): Wilson-CI der Fehlerquote sichtbar + Delta gegen letzte n>=20-Version (#196 P4+P5)#225
TillQuandel merged 2 commits into
masterfrom
feat/196-wilson-ci

Conversation

@TillQuandel

@TillQuandel TillQuandel commented Jul 12, 2026

Copy link
Copy Markdown
Owner

Schließt #196 ab (P1–P3 waren PR #209). Closes #196.

P4 — Wilson-CI sichtbar machen

Persistenz-Lücke geschlossen: run_eval.py schrieb anchors_total/anchors_hallucinated nicht in note_evals (der Pipeline-Pfad eval_quality_v4.save_result() tat es bereits). Insert-Dict in _eval_insert_data() extrahiert + Felder ergänzt; Round-Trip-Test gegen tempfile-DB belegt das echte Spalten-Mapping. Keine neue CI-Spalte — das CI ist aus den Roh-Counts ableitbar (SSoT), Design-Entscheidung dokumentiert.

Serverseitig: neues _pooled_hall_stats() (aus _pooled_hall_pct() extrahiert, Delegation — keine Duplikation) liefert gepoolte Rate + wilson_ci(ah, th) + anchors_total/rows_n/notes_n. CI nur wenn Roh-Counts vorhanden; beim Mean-Fallback (Alt-Zeilen ohne Counts) bleiben alle CI-Felder null → Kachel zeigt kein CI.

Kachel: Fehlerquote zeigt „CI x–y % · N Anker" (DE-Locale via _fmtDE) + Cluster-Caveat im hint/hint-pop-Tooltip (PR-#219-Muster): Anker innerhalb einer Note sind korreliert — das CI unterschätzt die Unsicherheit.

P5 — Delta-Semantik

version_delta() vergleicht die neueste Version jetzt gegen die letzte frühere Version mit n≥20 statt starr gegen die direkte Vorversion (die praktisch immer n=1–2 hat → Delta war dauerhaft „nicht belastbar"). Fallback ohne n≥20-Historie: direkte Vorversion, reliable:false (Verhalten wie bisher). Rückgabe neu mit prev_version/prev_n; alle drei Client-Konsumenten (Delta-Chip, Spark-Row, Übersichts-Banner) zeigen die Vergleichsbasis transparent an. Notwendige Folge-Konsistenz: Der Banner las den Wert aus version_delta, das Label aber aus vers[-2] — nach der Umstellung hätte er Wert (v0.3.31) und Label (v0.3.139) gemischt.

RED-Beweis (TDD)

  • hall_kpi: ImportError: cannot import name '_pooled_hall_stats' (Collection-RED)
  • run_eval: AttributeError: module 'run_eval' has no attribute '_eval_insert_data'
  • P5: assert 5.0 == 12.0 (verglich noch gegen Vorversion) + 2× KeyError: 'prev_version'
  • Gesamt-RED: 5 failed, 18 passed → nach Implementierung 42 passed (3 Testdateien)

Suite

pytest generative lib/decision_engine/tests shared/tests -q: 5776 passed, 3 skipped, 4 deselected (master-Stand: 5766). ruff format --check . + ruff check . sauber.

Playwright-Sichtverifikation (hell+dunkel)

Server aus Worktree auf Port 8061 (genau 1 Listener-PID verifiziert), echte DB read-only. Reale Werte v0.3.140: Fehlerquote 7,5 %, CI 5,9–9,6 %, 810 Anker (52 Zeilen/40 Notes); Delta gegen v0.3.31 (n=21), reliable:true — vorher wäre gegen v0.3.139 (n=2, immer ausgegraut) verglichen worden. Screenshots: C:/tmp/196-verify/196-{kpis,ci-tooltip,delta-tooltip}-{light,dark}.png.

Reviews

  • Task-Review (Opus): Spec ✅, Approved; 3 Minor-Kosmetik-Punkte (Null-Guard-Inkonsistenz im hint-pop, fehlender Regressionsschutz für die main()-Verdrahtung, prev_version unescaped als Fortführung des Bestandsmusters) — fürs Whole-Branch-Review vorgemerkt.
  • Cross-Model (Mistral magistral-medium): 1 Fund verworfen als Fake-Fund (_distinct_notes „nicht definiert" — existiert in eval_dashboard.py:668, vorgeschlagener Fix duplizierte die Bestandsfunktion); 1 Fund bestätigt-minor (theoretisches „n=undefined" im Banner nur bei fehlgeformtem kpi_trend mit ungleich langen Listen — vor-bestehendes Restrisiko, Backlog).

Scope

run_eval.py (+ neuer Test), generative/eval_dashboard.py, internal/dashboard/eval_dashboard.html, 2 bestehende Testdateien erweitert (keine Assertions entfernt). anchor_rate bewusst NICHT in run_eval geschrieben — Feld existiert im generativen eval_note()-Result nicht, auch save_result() schreibt es nicht; ein Wert wäre geraten.

Kontrollrunde (2026-07-12, zweite unabhängige Review-Ebene)

  • Opus-Kontroll-Review (Fehlerfindung + Behauptungs-Drift-Prüfung des PR-Bodys, Selbstverifikationspflicht): 0 neue Funde; 10/10 geprüfte PR-Behauptungen belegt (u. a. CI-Arithmetik wilson_ci(61, 810) → 7,5 % / 5,9–9,6 % exakt; alle drei Delta-Konsumenten konsistent auf prev_version; keine Assertions entfernt — Diff der Testdateien rein additiv). 9 Kandidaten aktiv widerlegt, darunter 12 Edge-Case-Proben an version_delta (leere/ungleich lange Listen, None-Werte) ohne Crash. Ergänzender Beleg: der dokumentierte hint-pop-Null-Guard-Minor kann faktisch nie auslösen (hall_anchors_total ist serverseitig an hall_ci_low gekoppelt — beide null oder beide gesetzt).
  • Mistral-Schwerpunkt-Resample (Linse Server↔Client-Feldvertrag / CI-Mathematik / Schleifenlogik): 0 Funde.

Tilltime added 2 commits July 12, 2026 15:16
run_eval.py schrieb hallucination_rate, aber nicht anchors_total/
anchors_hallucinated -- obwohl eval_note() sie liefert und das Dashboard sie
fuer die gepoolte Fehlerquote + Wilson-CI braucht (Review-Fund). Insert-Dict in
_eval_insert_data() extrahiert und um die Anker-Roh-Counts ergaenzt, konsistent
mit dem kanonischen Pfad eval_quality_v4.save_result(). anchor_rate ist im
generativen Result nicht enthalten und wird -- wie save_result -- nicht
geschrieben.
…-Version (#196 P4/P5)

P4: _pooled_hall_stats() liefert zusaetzlich das 95%-Wilson-CI (gepoolt,
ankergewichtet) plus Anker-/Zeilen-/Notes-N; _calc_kpis reicht sie als
hall_ci_low/high/anchors_total/rows_n/notes_n durch (null im Mean-Fallback ohne
Roh-Counts). Fehlerquote-Kachel zeigt "CI x-y % . N Anker" in DE-Locale, mit
Cluster-Caveat im Tooltip (Anker innerhalb einer Note korreliert -> CI
unterschaetzt die Unsicherheit).

P5: version_delta() vergleicht gegen die letzte fruehere Version mit n>=20 statt
starr die direkte Vorversion (Nachbarversionen sind oft Einzel-Note-Wegwerflaeufe
n=1-2 -> immer reliable:false). Fallback auf Vorversion (reliable:false) wenn
keine existiert; Rueckgabe nennt prev_version/prev_n. Alle drei Client-
Konsumenten (Delta-Chip-Tooltip, Spark-Row, Uebersichts-Banner) nutzen
prev_version -- sonst mismatch zwischen Wert (vd.prev) und Versions-Label.
@TillQuandel TillQuandel merged commit 5380acf into master Jul 12, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dashboard-Kennzahlen belastbar machen: Wilson-CI-Anzeige, Kosten/akzeptierte Note, Waisen-Banner, Delta-Semantik

2 participants