update
This commit is contained in:
98
AUFTRAG-inventar-fix.md
Normal file
98
AUFTRAG-inventar-fix.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# Auftrag: Inventar-Pipeline reparieren — zu viele, fehlende und schlecht benannte Bausteine
|
||||
|
||||
## Kontext
|
||||
|
||||
Das Thema `aak` (Uni-Quelle `uni/aak`: Skript + Serien + Klausuren + Hausaufgaben) erzeugte **108 Bausteine**. Soll-Abgleich mit dem Skript ergibt: sinnvoll wären **~60–70** (davon ~40–45 Skript-Kern). Der letzte QA-Lauf (`storage/qa/aak/20260705-201016.json`) zeigt 36 % Dubletten-Verdacht bei Note 10.0 und Lücken-Quote 0.0 — obwohl Kernkonzepte fehlen.
|
||||
|
||||
Zahlenfluss des Laufs (aus `storage/topics/aak/arbeit/inventar-*.json`):
|
||||
~1150 Roh-Nennungen (24 Chunks × 2 Research-Pässe) → 203 Kandidaten → Filter degradiert 69, Recheck holt 17 zurück → 134 → Dedup prüft 183 Paare, merged nur 17 (9 %) → 117 → Gruppierung: 5 Umbrellas, 17 Umbrella-Merges per Type-Gate verworfen → Supplement +4 → **108**.
|
||||
|
||||
Die Pipeline-Stages stehen in `inventory_stages` (`backend/board_inventory.py:1614`). Alle Zeilennummern unten beziehen sich auf den Branch `refactor` inkl. der offenen (uncommitteten) Diffs — siehe „Leitplanken".
|
||||
|
||||
## Befund: sechs Root Causes
|
||||
|
||||
### R1 — Extraktion erlaubt Beweisschritt-Granularität (Hauptursache „zu viele")
|
||||
- `templates/Prompt/Blocks-Research.md` erklärt „named theorems with their own statement" und jede „standalone REDUCTION" zum eigenen Baustein. `templates/Prompt/Blocks-Source-Uni.md` nennt „formulas and theorems" als Zielkategorie, ohne Granularitätsgrenze.
|
||||
- Folge im aak-Lauf: 14 Beweisschritt-/Beweis-Objekt-Bausteine (z. B. `Type-I`, `Schedule D*`, `Gewichtsfunktion d2`, `Zick-Zack-Tour`, `Optimaler Rundweg OPT((Kn,d2)) = n`, `3-SAT ≤ K-COLOR: G=(V,E) Konstruktion`) und 8 Bausteine für EIN Konzept („untere Schranken via ETH": `Lower Bound via k/n/|E|/|T|` + 4 weitere).
|
||||
- Verstärker: `_is_named_statement` (`backend/blocks.py:1355`) schützt alles mit Reduktions-Syntax vor Demotion — auch Konstruktionsdetails wie `…: G=(V,E) Konstruktion`.
|
||||
|
||||
### R2 — Quellen-Nummern als Titel, Reparaturstufe greift nicht (Hauptursache „Benennung")
|
||||
- Research-Pässe übernehmen Skript-Nummerierungen als Titel („Satz 7.13", „Bemerkung 7.22", „Definition 6.19"). 6 finale Bausteine tragen reine Satz-/Bemerkungs-Nummern.
|
||||
- `_REFERENCE_RE` (`backend/blocks.py:1022`) matcht nur nackte Referenzen („Bemerkung 7.22"), NICHT „Satz 7.13 (Christofides)" oder „Satz 7.6: Kriterium für Eulerschen Kreis" — die laufen als „gute" Titel durch.
|
||||
- Rename ist Best-Effort: In `clarify` wird nur umbenannt, wenn ein Judge freiwillig `rename` liefert (`backend/board_inventory.py:663`). Beispiel Cluster `08c52a84`: Judge j1 schlug für „Bemerkung 7.22" den korrekten Konzeptnamen vor („Untere Schranke für FPTAS …"), die Aggregation verwarf ihn.
|
||||
- Singletons überspringen Naming komplett: `_choose_title` läuft nur bei `len(rows) > 1` (`backend/board_inventory.py:725` und `:802`).
|
||||
|
||||
### R3 — Titel-Split zerschneidet Namen (abgeschnittene Titel)
|
||||
- `_title = entry.split(" — ")[0]` (`backend/textkit.py:35`) + aggressives `_norm_dash` (`backend/textkit.py:77`): ein en-Dash MIT einseitigem Space **innerhalb** eines Titels wird zum Separator → Split mitten im Titel.
|
||||
- Es gibt keine Klammer-Balance-Prüfung und keinen Repair. Ergebnis: `Aε-Algorithmus (Güte 1+ε, Laufzeit O(n3` und `N P via nicht-deterministische Turingmaschine (Definition 6.` liefen wortwörtlich bis `done`.
|
||||
- (Die 60-Zeichen-Kürzung in `backend/board_artefacts.py:81` betrifft nur Ordnernamen, nicht Titel — kein Fix nötig.)
|
||||
|
||||
### R4 — Dedup-Dämme brechen (36 % Verdacht überleben)
|
||||
- Merge braucht Einstimmigkeit zweier Judges (`if ja1 and ja2`, `backend/board_inventory.py:1200`); „uneinig" → kein Merge, kein Tiebreak.
|
||||
- Parameter-Familien werden als Paare je einzeln mit „nein" beschieden (`Lower Bound via k`↔`n`↔`|E|`↔`|T|`, alle QA-Jaccard 1.0).
|
||||
- Kandidaten-Generierung verpasst Komposita: `_canonical_key` (`backend/blocks.py:1118`) trennt „Cliquenproblem" nicht in „Clique"+Stopwort → „Clique" vs. „Cliquenproblem (k-Clique)" wird ggf. nie Judge-Kandidat.
|
||||
- Type-Gate der Gruppierung verwarf 17 Umbrella-Merges (`grund: "type-gate"` in `inventar-gruppierung.json`) — exakt die späteren QA-Dubletten (Approximations-Grundbegriffe, Type-I/II+Schedule-Objekte, NP-Definitionen).
|
||||
- Filter-Recheck holte 17 korrekte Degradierungen zurück (`ueberstimmt`/`floor_veto` in `inventar-filter-535eb84c.json`) — darunter die komplette Lower-Bound-Familie.
|
||||
|
||||
### R5 — Echte Lücken trotz Quote 0.0 (Ursache „fehlende")
|
||||
- Fehlend im aak-Inventar: **SAT/Satz von Cook-Levin** (zentralster Satz), **MGA (Güte 2)**, **Sahni-PTAS Ak**, **Satz von Lawler**, **Satz 6.16 (P=NP-Kriterium)**, Lastfunktion (Def 7.26, per Supplement teilweise nachgeholt).
|
||||
- QA-Lücken sind token-basiert (`backend/qa.py:163`): 108 übergranulare Bausteine decken jede Sektion irgendwie ab → Konzeptlücken unsichtbar, Supplement (`_proc_gap_check`) ergänzt zu wenig.
|
||||
- Verlust-Vektor upstream: `clarify` verlangt für Einzel-Reader-Funde Einstimmigkeit aller Judges (`accept = v >= len(outs)`, `backend/board_inventory.py:657`) — ein einziges „nein" verwirft einen real existierenden Fund als `failed-quorum`.
|
||||
|
||||
### R6 — QA-Note ist blind für das Problem
|
||||
- `NOTE_GEWICHTE` (`backend/qa.py:40`) enthält keine Dubletten. 36 % Verdacht + Verschlechterung zum Vorlauf (+0.06) ergeben trotzdem Note 10.0.
|
||||
|
||||
## Maßnahmen (priorisiert; M1–M3 = Ursachen, M4–M5 = Dämme, M6 = Messung)
|
||||
|
||||
### M1 — Titel-Hygiene, deterministisch
|
||||
1. `_norm_dash`/Titel-Split klammer-bewusst machen: Dash innerhalb offener Klammer ist KEIN Separator. Nach dem Split: unbalancierte Klammern → Titel reparieren (bevorzugt: Split rückgängig / nächsten Separator nehmen).
|
||||
2. `_REFERENCE_RE` erweitern: auch `Satz 7.13 (Christofides)`, `Satz 7.6: Kriterium …`, `… (Definition 6.19)` erkennen. Deterministischer Strip: Referenz-Präfix/Suffix entfernen, Konzeptrest behalten („Satz 7.6: Kriterium für Eulerschen Kreis" → „Kriterium für Eulerschen Kreis"). Reine Nummern ohne Konzeptrest („Bemerkung 7.22") → Rename-PFLICHT (Judge muss Konzeptnamen liefern, sonst bleibt die Karte vor `done` hängen bzw. wird saniert), statt Best-Effort.
|
||||
3. Naming/Sanierung auch für Singletons erzwingen, wenn Titel `_is_reference`, klammer-unbalanciert oder >80 Zeichen ist (`board_inventory.py:725`, `:802`, `_sanierung_noetig` `:492`).
|
||||
|
||||
### M2 — Granularitätsgrenze in den Prompts
|
||||
1. `Blocks-Research.md` + `Blocks-Source-Uni.md` (und Geschwister `Blocks-Source-*.md`): Negativ-Liste ergänzen — KEINE eigenen Bausteine sind: einzelne Beweisschritte, Hilfskonstruktionen/Beweis-Objekte (Hilfs-Schedules, Gewichtsfunktionen, konstruierte Touren), berechnete Einzel-Instanzen, Parameter-Instanzen desselben Arguments (dieselbe Technik „via k / via n / via |E|" = EIN Baustein). Solche Inhalte gehören als Aspekt in den Eltern-Baustein.
|
||||
2. Titel-Regel in beide Naming-Prompts (`Blocks-Naming.md`, `Blocks-Klaerung.md`, `Blocks-Sanierung.md`): Titel ist der KONZEPTNAME; Quellen-Nummerierungen („Satz 7.13") sind als Titel verboten, dürfen aber in der Beschreibung stehen.
|
||||
3. Sätze bleiben erlaubt als Baustein, wenn sie ein eigenständig prüfbares Ergebnis sind (Cook-Levin, Christofides) — benannt nach dem Ergebnis, nicht der Nummer.
|
||||
|
||||
### M3 — Fragment-Filter nachschärfen
|
||||
1. `_is_named_statement` (`blocks.py:1355`) verengen: Reduktions-Syntax mit Konstruktions-Suffix (Doppelpunkt/Zusatz NACH der Relation, z. B. `…≤ K-COLOR: G=(V,E) Konstruktion`) ist NICHT geschützt, sondern fragment-verdächtig.
|
||||
2. Recheck-Overturn erschweren: `ueberstimmt` nur bei einstimmigem Recheck-Panel statt Mehrheit (`board_inventory.py:1031`). Beleg: 15 von 17 zurückgeholten Karten waren spätere QA-Dubletten.
|
||||
3. Parameter-Varianten als Verdacht markieren: Titel-Paare, die sich nur durch ein Parameter-Token unterscheiden (`via k`/`via n`/`via |E|`), in `_filter_suspect` bzw. als eigene Familien-Heuristik aufnehmen → Filter-/Dedup-Kandidat.
|
||||
|
||||
### M4 — Dedup-Recall erhöhen (ohne Fehlmerge-Risiko aufzugeben)
|
||||
1. Die drei offenen Diffs (Richtungs-Guard `_direction_conflict`, Judge-Kanal-Guard, Dedup-Prompt-Zeile) BEHALTEN — sie sind Teil der Lösung.
|
||||
2. Tiebreak statt Veto: bei 1-1-Judge-Split (`uneinig`, `board_inventory.py:1200`) einen dritten Judge entscheiden lassen.
|
||||
3. Familien-Kollaps: Cluster von ≥3 Titeln, die sich nur im Parameter-Token unterscheiden, als EIN Merge-Fall (ein Judge-Call für die Familie) statt n² Einzelpaare.
|
||||
4. `_canonical_key` (`blocks.py:1118`): Kompositum-Suffix „…problem" auch verklebt abtrennen („Cliquenproblem" → Stamm + Stopwort), damit solche Paare Kandidaten werden. Generisch halten (Suffix-Regel, keine Wortliste pro Domäne).
|
||||
5. Type-Gate der Gruppierung (`_GROUP_STANDALONE`-Pfad) lockern: Umbrella-Merge nicht allein wegen gemischter Content-Typen (Definition+Satz+Algorithmus) verwerfen, wenn das Judge-Panel die Gruppe bestätigt hat. Die 17 verworfenen Fälle aus `inventar-gruppierung.json` sind der Prüfmaßstab.
|
||||
6. NICHT anfassen: die Varianten-Regel „k-X ≠ X / Max-X ≠ X" im Dedup-Prompt und das 2-Judge-Panel für klare Fälle. Bisher 0 Fehlmerges — das muss so bleiben.
|
||||
|
||||
### M5 — Lücken schließen
|
||||
1. `clarify`-Quorum für Einzel-Reader-Funde von Einstimmigkeit auf Mehrheit senken (`board_inventory.py:657`) ODER abgelehnte Funde als Fragment aufbewahren statt `rejected`, damit `gap_check`/Supplement sie wiederfinden kann.
|
||||
2. Gap-Check konzeptbasiert ergänzen: benannte Ergebnisse des Korpus (Sätze/Definitionen mit eigener Aussage, Abschnittsüberschriften) gegen das Inventar prüfen, nicht nur Token-Abdeckung. Ein benanntes Kernresultat ohne zugeordneten Baustein = Lücke → Supplement-Kandidat.
|
||||
3. Prüffälle für aak (müssen nach einem Neulauf existieren): SAT/Cook-Levin, MGA, Sahni-PTAS Ak, Satz von Lawler, P=NP-Kriterium (Satz 6.16).
|
||||
|
||||
### M6 — QA ehrlich machen
|
||||
1. `dubletten_verdacht` in `NOTE_GEWICHTE` aufnehmen (`qa.py:40`), damit die Note das Nutzerproblem abbildet.
|
||||
2. Optional: konzeptbasierte Lücken (aus M5.2) als eigene QA-Quote ausweisen.
|
||||
|
||||
## Leitplanken
|
||||
|
||||
- **Generisch bleiben**: keine aak-/Komplexitätstheorie-Sonderregeln in Pipeline oder Prompts. aak ist nur der Prüffall. Alle Heuristiken müssen für beliebige Themen tragen.
|
||||
- **YAGNI**: kleine, gezielte Diffs; bestehende Muster (Judge-Panels, Schema-Parser, Kanban-Stages) wiederverwenden; nichts Neues bauen, was eine Prompt-Zeile löst.
|
||||
- **Offene Diffs behalten**: `backend/blocks.py`, `backend/board_inventory.py`, `templates/Prompt/Blocks-Dedup.md` enthalten uncommittete Änderungen (Richtungs-Guard). Nicht verwerfen, darauf aufbauen.
|
||||
- **Niemals `git commit` oder `git push`** — der Nutzer committet selbst.
|
||||
- **Fehlmerge-Bilanz**: Recall-Erhöhungen (M4) dürfen keine falschen Merges einführen. Jede Lockerung braucht einen Judge-Beleg-Pfad; deterministische Auto-Merges bleiben streng.
|
||||
- **Keine Echtläufe ohne Freigabe**: `make qa TOPIC=aak` mit LLM-Judges und komplette Neuläufe kosten Tokens — nur nach Rückfrage beim Nutzer starten.
|
||||
|
||||
## Validierung (in dieser Reihenfolge)
|
||||
|
||||
1. `pytest` in `backend/` — bestehende Tests dürfen nicht brechen; für M1 (Titel-Split, Referenz-Regex) und M4.4 (`_canonical_key`) gezielte Unit-Tests ergänzen (Fixtures: die realen Schadensfälle aus diesem Auftrag).
|
||||
2. `make test-e2e` — Fake-E2E (`backend/fake_agents.py`) muss grün bleiben; Störfall-Matrix ggf. um Referenz-Titel und unbalancierte Klammern erweitern.
|
||||
3. QA-Fehler-Injektion (Muster siehe QA-Modul-Tests): injizierte Satz-Nummern-Titel, Parameter-Familien und Konzeptlücken müssen von den geänderten Checks erkannt werden.
|
||||
4. Erst nach Nutzer-Freigabe: Neulauf aak + `make qa TOPIC=aak`. Erfolgskriterien:
|
||||
- Baustein-Anzahl ~60–70 (statt 108),
|
||||
- `dubletten_verdacht` < 0.10 (statt 0.361),
|
||||
- die 5 Prüffall-Konzepte aus M5.3 existieren,
|
||||
- kein Titel matcht die erweiterte Referenz-Erkennung, keine unbalancierten Klammern,
|
||||
- Lücken-/Fremd-Quote nicht schlechter als der Referenzlauf `20260705-201016.json`.
|
||||
Reference in New Issue
Block a user