ADR-0006: Quali-Eval-Teilung (eval↔judge) + Pack = Daten¶
- Status: akzeptiert · 2026-06-28
- Bereich: Quali-Eval
Kontext¶
Die qualitative Evaluation muss zwei grundverschiedene Use-Cases prüfen können — emotionale Stütze (ndassist, K.-o. = Sicherheit) und faktische Zuverlässigkeit (buero, K.-o. = keine Halluzination) — ohne für jeden Use-Case Code zu ändern (Spec, „reine Daten (YAML), kein Code"; pack.py-Docstring: „A pack is data, not code"). Zugleich erzeugt ein Lauf zwei klar trennbare Artefakte: das deterministische Generieren von Antworten und das anschließende Bewerten. qualrun.py beschreibt sich selbst als „The deterministic half of the eval"; results.py trennt explizit „Generation fills EvalResponse; judging fills the rest" (Verdict, ModelReport). Kräfte: Reproduzierbarkeit (deterministisches Sampling), Wiederaufnahme nach Abbruch (Generieren ist der teure, schützenswerte Teil), und ein Datenkontrakt, der zwischen Generieren und Bewerten stabil bleibt.
Entscheidung¶
Die Quali-Eval wird in zwei Phasen über einen stabilen Datenkontrakt getrennt: (1) run_eval (qualrun.py) treibt die Matrix Modell × prompt_variant × Pack-Prompt × repeat, schreibt jede Antwort sofort inkrementell nach responses.jsonl als EvalResponse (results.py) und ist via --resume wiederaufnehmbar; (2) das Bewerten konsumiert diese EvalResponse-Records und füllt Verdict/ModelReport. Der Use-Case selbst ist reine Daten: ein Pack (YAML, geladen via load_pack) bündelt scale, gewichtete dimensions, ko_rule, prompt_variants, sampling (Default temperature 0.0, seed 42) und categories[]. Strenge Validierung beim Laden (pack.py: doppelte Prompt-IDs, unbekannte ko_rule.dimension, dangling red_flag_prompts, doppelte Variant-IDs) lehnt einen kaputten Pack ab, bevor ein einziger Request rausgeht.
Erwogene Alternativen¶
- Generieren und Bewerten in einem untrennbaren Schritt — verworfen, weil dann ein Abbruch oder ein Judge-Fehler die teure Generierung verwirft;
qualrun.pyschützt explizit den teuren Teil („the expensive part — generation — is what must survive a crash"), indem Antworten inkrementell persistiert und beim Resume übersprungen werden. - Use-Case als Code statt als YAML-Daten — verworfen, weil dann jeder neue Use-Case eine Code-Änderung bräuchte;
pack.pymacht das Austauschen der YAML zum einzigen nötigen Schritt („swapping the YAML moves the harness … with no code change"). - Validierung erst zur Laufzeit / während des Laufs — verworfen, weil ein dangling Dimension-Verweis oder eine doppelte Prompt-ID dann erst nach teurer Generierung aufflöge;
pack.pyvalidiert strikt vorab, „before a single request is sent".
Auswirkungen¶
- Positiv: Ein zweites Pack (
buero) validiert die Mechanik (Discovery, GUI-Listung, Cross-Judge-Aggregat nach Pack) ganz ohne Code-Änderung — schärfster Kontrast zundassist(Spec, „Ziel & Kontext"). - Positiv: Läufe sind reproduzierbar (deterministisches
sampling, temp 0.0 + seed 42) und überleben Abbrüche (inkrementellesresponses.jsonl+--resume, tolerant gegen eine halb geschriebene letzte Zeile,load_responses_jsonl). - Positiv: Der Datenkontrakt (
EvalResponse/Verdict/ModelReport) entkoppelt Generieren von Bewerten sauber (results.py). - Trade-off / Restgrenze: Der Pack ist nur Daten — ein realer Eval-Lauf gegen ein echtes Modell ist bewusst kein Akzeptanzkriterium, sondern optionaler Folgeschritt (Spec, „Out of Scope").
- Trade-off / Restgrenze: Im Finalize-Pass werden Host-Ressourcen (RAM/Pressure/Throttle) nachträglich per Zeitfenster gemergt; vor dem Baseline-Tick erzeugte Bundles haben
sys_used_baseline_mb/sys_used_delta_mb= None (results.py,qualrun.py-Finalize).
Belege & Links¶
- Spec:
docs/superpowers/specs/2026-06-27-buero-pack-design.md· Code:touchstone/pack.py,touchstone/qualrun.py,touchstone/results.py· Tests:tests/test_pack.py(Spec-Akzeptanzkriterium 2:test_shipped_buero_pack_parses) - Verwandt: ADR-XXXX (K.-o.-
red_flag_scope, vgl.docs/superpowers/specs/2026-06-27-ko-red-flag-scope-design.md)