This commit is contained in:
team3
2026-07-10 15:43:11 +02:00
commit 0a41166cca
72 changed files with 7772 additions and 0 deletions

115
LEKTIONEN.md Normal file
View File

@@ -0,0 +1,115 @@
# Bezahlte Lektionen aus creator (Vorgänger)
Extrahiert 2026-07-09 aus dem alten Code. Format: **Regel** — Grund (Beleg alt: Datei:Zeile).
Diese Regeln sind Anforderungen an creator2, kein übernommener Code.
## Infra-Fehler
1. **Infra-Fehler (429/Timeout/Netz) getrennt von Inhaltsfehlern zählen** — sonst frisst ein 429 die inhaltlichen Restarts und der Lauf läuft fail-open weiter (pipeline.py:80).
2. **Erschöpfte Infra-Retries ⇒ Lauf-PAUSE (fortsetzbar), nie Teilergebnis** — Quorum verhungerte sonst still (pipeline.py:304).
3. **Retries + Backoff zentral: 3×, 8/16/32 s** (config.py:180).
4. **Stall-Hedge: genau EIN Zwilling nach Schwelle, erster valider gewinnt** — Stalls verbrannten 160230 s Timeout (pipeline.py:225).
5. **Hedge-Schwelle = max(90 s, timeout/2)** — pauschale 90 s hedgten gesunde lange Calls (pipeline.py:196).
6. **Judge-Timeouts eng (p50 672 s), Retry heilt in Sekunden** (config.py:201).
7. **Prozessgruppen-Kill (killpg + start_new_session)** — CLI-Kinder hielten sonst Pipes offen (agents.py:287).
8. **CLI-Starts staffeln (Token-Bucket)** — OpenCode-Session-DB: "database is locked" (agents.py:154).
9. **RAM-Gate vor CLI-Spawns (~310 MB RSS je Prozess)** (agents.py:195).
10. **Concurrency-Slot VOR dem Spawn erwerben** — Queue-Wartezeit zählt nicht gegen den Timeout (agents.py:76).
11. **Agent-Slots nach Pipeline-Stufe priorisieren** (früh vor spät) — nur nötig bei Streaming; Wellen-Design umgeht es.
12. **.env-Datei gewinnt über geerbtes Env** — --reload-Master pinnte stale Werte stundenlang (config.py:13).
13. **Provider-Routen pro Rolle empirisch wählen** — kalt-Endpoint stallte 20 % der Judges (config.py:244).
14. **Timeouts = Basis + pro-Item·n**, nie fix (config.py:195).
## Judge-Rauschen
15. **Hochgewichtete LLM-Urteile: Verdacht + 2 unabhängige Bestätiger** — Einzel-Judge pendelte 0↔5 Befunde (guide_qa.py:138).
16. **Instabile Klassifikations-Judges: Zweitpass auf die Verdachtsmenge** (qa.py:516).
17. **Mehrheit bei Recall-kritischen Entscheidungen** — Einstimmigkeit verwarf reale Einzelfunde (board_inventory.py:580).
18. **Einstimmigkeit bei irreversiblen Merges** (board_inventory.py:1195).
19. **Detektor-vs-Judge-Dissens: dritter Stichentscheid (2/3), Freispruch persistieren** (repair.py:82).
20. **Panel-Ausfall: Ersatz-Richter vor fail-open** (block_calls.py:358).
21. **Panels: 2 = Konsens-Minimum, 3 nur wo Rauschen teuer** (config.py:162).
22. **Quorum-Rennen mit Grace-Fenster** — Sofort-Kill warf fast fertige Stimmen weg (pipeline.py:174).
23. **Klärungs-Loops hart deckeln, Schlussrunde muss alles entscheiden** (config.py:128).
24. **Billige Konsensregeln (≥2 Nennungen) deterministisch im Code, nicht per LLM** (board_inventory.py:546).
## Fehlmerge-Schutz
25. **Relationen (A≤B) über beide Operanden + Richtung individuieren, Konflikte vetoen** — "SAT≤Clique" vs "3-SAT≤Clique" hat hohen Cosinus (blocks.py:1150).
26. **Deterministische Guards nur so streng wie beweisbar; Bedeutung dem belegten Judge** (blocks.py:1157).
27. **Casefold + NFKC vor jedem Ähnlichkeitsvergleich** — "VERTEX COVER" fiel unter die Schwelle (board_inventory.py:1133).
28. **Acronym↔Expansion explizit als Kandidaten einspeisen** — Cosinus ~0.53, nie Kandidat (blocks.py:1093).
29. **Auto-Merge nur über ordnungsunabhängigen Canonical-Key; leerer Key ⇒ nie** (blocks.py:1106).
30. **Embedding-Backstop vetot strukturlose Fehl-Demotes** (config.py:99).
31. **Negations-Guard: Antonyme messen 0.910.95 Cosinus** — gleiche Negationsmenge als harte Merge-Vorbedingung (blocks.py:681).
32. **Frei generierte Titel gegen Korpus verankern** — Drift zu Lehrbuch-Kanon (board_inventory.py:121).
33. **Quorum schützt nicht vor Ko-Halluzination** — Titel ohne Korpus-Anker separat belegen (board_inventory.py:576).
34. **Kandidatenblöcke in Größe cappen** — sonst Riesenkomponente, instabile Judge-Listen (config.py:56).
35. **Containment-Zuordnung nur bei genau einem signifikanten Ganzwort-Treffer** (blocks.py:1250).
36. **Token/Stem-Match statt Substring** — "bergang" ⊂ "Übergang" (qa.py:243).
37. **Benannte Aussagen (Reduktionen, Sätze) strukturell vor Demotion schützen** (blocks.py:1322).
## PDF/Text
38. **Nie blind einem PDF-Extraktor vertrauen** — pymupdf4llm droppt Formeln still; pdftotext ist treu aber strukturarm. v1 nutzt pdftotext (Treue > Struktur); zweiter Extraktor + Verlust-Guard bei Bedarf (blocks.py:349).
39. **PDF-Spacing-Artefakte entzerren ("H ITTING S ET"), mit Frequenzbeleg** (blocks.py:373).
40. **Logik-Versions-Marker für abgeleitete Artefakte** — mtime-Cache überlebte Algorithmus-Änderungen (blocks.py:385).
41. **Optionale Abhängigkeiten (OCR) prüfen, still degradieren** (blocks.py:308).
42. **Titel-Splits klammerbewusst** (textkit.py:54).
43. **Unicode-Dash-Varianten tolerant normalisieren, ASCII-Hyphen schützen** (textkit.py:115).
44. **Marker-Vergleiche gegen Escaping härten (Backslashes strippen)** (guide_qa.py:36).
45. **Metadaten-Header vor Coverage-Detektion strippen** — Phantom-Lücken (qa.py:104).
46. **Regex-Fänge auf Umbruch-Fortsetzung prüfen** (qa.py:210).
47. **Große Quelltexte in ~12k-Abschnitte splitten** — lost in the middle (blocks.py:437).
## Token-Fresser
48. **Evidenz INLINE in Judge-Prompts, nie Judges selbst suchen lassen** — 82 % der Lauf-Tokens waren Cache-Reads aus Judge-Tool-Loops (config.py:143). WICHTIGSTE EINZELLEKTION.
49. **Strukturierten Output als Antworttext, robust parsen; Tool-Writes nur Fallback** — 40 von 64 Turns in einem Write/Validate-Loop (blocks.py:599).
50. **Tool-lose Calls über die direkte API statt CLI-Prozess** (agents.py:242).
51. **MCP-Server nur für full-Agenten** — ~3×300 MB pro Prozess (agents.py:529).
52. **Zusammengehörige Schritte in EINEM Call bündeln** (guide_board.py:7).
53. **Token-Verbrauch auch bei Fehlern/Timeouts erfassen** (agents.py:487).
54. **Rückkopplungslisten (Lücken/Fixes) über Schnittmenge filtern und hart cappen** — 107 "Lücken" auf 216 Subs (blocks.py:786).
55. **Chunk-/Split-Größen zentral und tunebar** (config.py:151).
## Prompt-Design
56. **Faktenbasis vorgeben, VERBATIM-Zitate verlangen, jeden Claim gaten** (Guide-Writer-Board.md:10).
57. **Maschinen-Marker als exakte Struktur-Invariante, unsichtbar, nie Überschrift** (Guide-Writer-Board.md:14).
58. **Längenbudget als HARTE Obergrenze formulieren, nicht als Ziel** (Guide-Writer-Board.md:27).
59. **Ausgabekanal + Format ausschließlich vorschreiben: "NUR JSON, keine Fences, keine Datei"** (Guide-Outline.md:21).
60. **Fixierte Eingabemengen einfrieren: "Copy VERBATIM, do NOT add/remove/split/merge/rename"** (Subblock-Anreichern.md:12).
61. **Aggregat-Titel: nur Eigenschaften, die auf ALLE Mitglieder zutreffen** (Blocks-Gruppierung.md:14).
62. **Namen nur aus Begriffen der Quelle, nie Lehrbuch-Oberbegriff** (Blocks-Naming.md:8).
63. **Katalognummern ("Satz 7.13") sind keine Titel** (Blocks-Sanierung.md:11).
64. **Quellgebundene Schritte: NUR die gelieferten Auszüge, kein Web, keine PDFs** (Blocks-Source-Inline.md:1).
65. **Bewertungs-Prompts: unbeantwortbare Fragen erkennen, Korrektheit in anderen Worten zählt** (Block-Rating-Critique.md:22).
66. **Reservierte Parser-Zeichen dem Modell verbieten** (Blocks-Gruppierung.md:16).
## Übergreifende Guards
67. **Destruktive Entscheidungen: im Zweifel behalten (fail-open)** (repair.py:8).
68. **Infra-Erschöpfung: fail-closed (Pause)** — die Wahl pro Fehlerklasse bewusst treffen (pipeline.py:330).
69. **Freisprüche persistieren** — sonst pendelt die Note ewig unter 10 (qa.py:437).
70. **Note deterministisch aus gemessenen Quoten, nie vom LLM schätzen lassen** (qa.py:294).
71. **Qualitäts-Gate vor teuren Downstream-Phasen** (config.py:132).
72. **QA nutzt EIGENE Detektoren/Schwellen, nie die der Pipeline** — geteilte blinde Flecken (qa.py:1).
73. **Fix-Schwellen an Sektionsgröße koppeln; Kritisches immer fixen** (config.py:170).
74. **Schema-Parser defensiv gegen Judge-Overreport** — 65-Einträge-Vollinventar (guide_board.py:66).
75. **Detektor-Messlatte und Fix-Auftrag teilen dieselbe Formel** — sonst unfixbare Befunde (guide_qa.py:75).
76. **Zwei Retry-Ebenen: Race-Restart vs. Item-Backoff/Dead-Letter, sichtbar + requeue-bar** (kanban.py:135).
77. **Auto-Loop: Ziel erreicht / echter Stillstand / hartes Limit — transiente Verschlechterung zulassen** (auto_loop.py:31).
78. **Guard-Strenge an Fehlerkosten ausrichten** — reversible Fehl-Merges brauchen keine harten Vetos (board_inventory.py:1427).
79. **Nach parallelen Judges ein Reconcile-Pass gegen Duplikat-Parents** (config.py:90).
80. **Zielgrößen sublinear (√n) statt statischer Bänder** (config.py:94).
81. **Fakten-Checks: exakt zitierte Quellstellen einblenden, kein Keyword-Pack** (blocks.py:549).
82. **Unicode am Import normalisieren (NFC + Kontrollzeichen→Leerzeichen), Matching diakritik-fest (NFKD, Kombinationszeichen droppen)** — pdftotext liefert dekomponierte Umlaute und Steuerbytes für Sonderglyphen (ε→\x0f), LLM-Zitate präkomponierte Zeichen bzw. Müll-Echos; per-Zeichen-NFKC komponiert nie → 59/96 aak-Atome „ohne Anker" trotz wörtlicher Zitate (creator2: korpus.py:_snapshot_schreiben, textkit.py:_locker_mit_map).
83. **Text-Reparatur und Zitat-Anchoring nicht selbst erfinden: ftfy am Import, fuzzysearch als letzte Matching-Stufe (Hypothes.is-Muster exakt→locker→fuzzy)** — Reader „verschönern" Zitate (Listing-Zeilennummern weg, verlorene Glyphen rekonstruiert); Fuzzy NUR mit Mindestlänge, harter Fehlerquote und Eindeutigkeits-Guard gegen Doppelgänger-Passagen (SubSetSum vs. Partition teilen den Satzanfang); Steuerzeichen VOR ftfy zu Leerzeichen (ftfy löscht sie und verklebt Wörter) (creator2: korpus.py:_text_reparieren, textkit.py:_fuzzy_span).
## Meta
- Jede Guard/Schwelle trägt ihren gemessenen Beleg im Kommentar.
- Tunebare Parameter und QA-Messlatte strikt trennen (Messlatte nie im Suchraum).
- Deterministisch vor LLM: Konsens, Kandidaten, Guards im Code; der Judge ist Präzisions-Gate für Zweifelsfälle.
- Provider-Ausfall darf nie den Lauf reißen — Stacks unabhängig.