Files
creator2/LEKTIONEN.md
2026-07-10 15:43:11 +02:00

116 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.