--- title: "Kanshō – Selbstlernende Detect-Pipeline (Konzept und Anforderung)" status: "Konzept / Arbeitsauftrag — §6 finalisiert 2026-09-11" date: "2026-09-11" document_role: "Cursor Implementation Brief / Concept Record" canonical_functional: "docs/architecture/functional/guardrails.md §22.4" canonical_technical: "docs/architecture/technical/privacy_gateway.md §9.7" --- # Selbstlernende Detect-Pipeline Dieses Dokument ist das Home für das **Zielbild 2026-09-11**. Es ersetzt weder `guardrails.md` noch `privacy_gateway.md`. Statuswörter ernst nehmen. §6 wurde am 2026-09-11 mit dem Nutzer im Planmodus geschlossen; die Umsetzung folgt diesen Entscheidungen. Herkunft: explizite Nutzeranforderung und gemeinsame Bewertung in der Konzeptsession 2026-09-11. ## 1. Ziel Ein **selbstlernender Schutz** pro Profil, der über Zeit immer weniger persönliche Klarformen an ein externes LLM gibt und dabei verlässlicher wird. GLiNER findet neue Spannen. Kanshō entscheidet und merkt (Sinne, Cues, Registry). OpenRouter ist Lehrer und Lückenfüller, nicht Alltag und nicht Identitätsquelle. GLiNER-Gewichte werden zur Laufzeit nicht nachtrainiert; ein gemeinsames Jinkendo-NER-Projekt ist ein späterer, getrennter Dienst (stateless, keine gemeinsame Identität). Leitbeispiel: Lange Zeit bedeutet „Sushi“ die Partnerin. Am Tag 21 ist „Sushi“ Essen. Ein Lexem-Lock auf Identität und ein Lehrer, der nur noch Platzhalter sieht, machen das Essen unsichtbar. Das darf nicht passieren. ## 2. Entscheidungsstand ### Entschieden - Identität bleibt lokal. Klasse-A-Mapping, Klarnamen und Registry gehen nicht an Provider. - Keine Wortlisten-UI. Sinne entstehen aus Bestätigungen (Identität / nicht schützenswert). - OpenRouter darf Identitäten nicht stillschweigend anlegen oder löschen. Der Mensch entscheidet über neue Identität und über Abweichungen. - Cue-Treffer gelten nur für **dieses Vorkommen**, nicht für die Schreibweise insgesamt. - Nur Identity-Hits ohne Non-Identity dürfen einen **neuen** Cue nicht festnageln (Sushi-Tag-21). - Schülerpfad-Reihenfolge: lokal cue-aufgelöste Vorkommen → unklare Homonyme als enger Ausschnitt an das Passage-LLM → GLiNER auf den Rest → Generate mit gebauten Mappings. - GLiNER sieht die Originalzeile mit übersprungenen, bereits aufgelösten Offsets, nicht den schon ersetzten Platzhaltertext. - Zwei Lernstufen. Umschalten ist eine Admin-Entscheidung, kein Autopilot. - **Stufe 1 (vollständig):** Kontrollaufruf auf den **unveränderten Nutzersatz** (keine Ersetzungen), parallel der Schülerpfad, Vergleich, bei Uneinigkeit oder neuer Identität Popup, dann lernen. - **Stufe 2:** Lehrer sieht keine **cue-sicheren** Vorkommen mehr. Dieselbe Vergleichslogik. Am Anfang fehleranfälliger; deshalb nach Stufe 1, nicht als Start. - Lehrer-Slice ist der Nutzersatz, nicht der gerenderte Detect-Prompt (kein Mitnehmen von Biografie/Kontext, den GLiNER nicht sieht). - Übereinstimmung plus bereits bestätigtes Label: Cue verstärken, kein Popup. - GLiNER nicht als alleiniges Detect in die Detect-URL schreiben. Detect-OpenRouter bleibt konfigurierbar. - Kein Gateway-Bypass, kein Feature-Flag zum Abschalten der Maskierung. - Bestehenden GLiNER-Client, Local-NER-Settings, Cues und Review-UI wiederverwenden, nicht wegwerfen; **umverdrahten**. - **Startbetrieb:** Lernmodus Stufe 1. Schüler (Cues → Verwandtschaft → Homonym-Mini-LLM bei beiden Sinnen → GLiNER) und Lehrer (unveränderter Nutzersatz) parallel. Diff zum Nutzer. Geprüftes Ergebnis maskiert Generate. - **Admin:** Zielpfad (`student`) + Lernen automatisch Stufe 1 (`learning_full`) + Lernen automatisch Stufe 2 (`learning_reduced`) + Lernen manuell (`learning_manual`) + Bypass (`bypass`, alter OpenRouter-Voll-Detect). Bypass entfällt mittelfristig. Default nach Umbau: `learning_full`. Aliase: `learning` → `learning_full`, `semantic` → `bypass`. - **Stufe 2** ist im ersten Schnitt vollständig (Lehrer ohne cue-sichere Oberflächenformen). - **Lehrer weg:** alle Schüler-/GLiNER-Funde zur Bestätigung (gleicher Weg wie manuell). - **GLiNER weg:** im Lernmodus manuelle Review nach lokaler Vorauswahl. Außerhalb Lernmodus: Nutzer bestätigt Klartext-Egress an das öffentliche LLM. - **Verwandtschaft** bleibt eigener lokaler Schüler-Schritt vor GLiNER. - **Vergleich:** gleiche Nennung = gleicher Wortlaut an derselben Stelle oder eine Spanne vollständig in der anderen. Typen `person→PERSON` usw.; ähnliche schützenswerte Typen gleich; FOOD gegen PERSON immer Diff. Nur bei abweichendem Schutz fragen; gleicher Schutz, anderer Zuschnitt → längere Spanne. Nutzer entscheidet Speise/Person; Cue nicht still ändern; Lehrer-Miss ohne Meldung → kein Popup, Cue bleibt. **Additiv 2026-10-12:** Bestätigter Cue bei Typkonflikt: zählen, nicht erneut fragen, Cue bleibt. Unbestätigter Typkonflikt bleibt Popup. - **Diagnose:** Zähler ohne Klartext (Einigkeit, nur Schüler, nur Lehrer, Typkonflikt, neue Identität, Cue verstärkt). Keine Langeweile-Kennzahl; Stufe nur per Schalter. - **Mini-LLM** nur wenn beide Sinne schon existieren, auch in Stufe 1. - **Geltungsbereich:** alle persönlichen Detect-Aufrufe (Security-Gateway), einschließlich Journalentwurf. ### Bevorzugte Richtung - Nach ausreichend langweiliger Abweichung in Stufe 1: Stufe 2, später Betrieb ohne Kontrollaufruf (Schülerpfad allein). - Diagnostik zeigt Diff-Art (nur Schüler / nur Lehrer / Typkonflikt), ohne Klartextlabels in Compact-Exports. - Fragment-Ausschnitte so eng, dass fremde noch unmaskierte Identitäten nicht mitgehen. - Eigenes Jinkendo-Local-Detect als späteres LAN-Projekt (Text rein, Spannen raus, kein Speicher). Nicht in diesem Slice. ### Verworfen - GLiNER oder OpenRouter als alleiniges Detect. - Lexemweites „einmal Person, immer Person“. - Lehrer auf bereits komplett vormaskiertem Text in Stufe 1. - Online-Fine-Tune von GLiNER auf Journaltext. - Gemeinsame Namensliste über Jinkendo-Produkte. - Detect-Treffer ohne Nutzer als aktive Identität speichern. ### Offen Keine offenen Punkte aus der Planmodus-Runde 2026-09-11. Frühere §6-Fragen sind unter Entschieden festgehalten. ## 3. Ziel-Workflow ``` Nutzersatz │ ├─ Schüler (immer, sobald dieser Pfad gilt) │ 1. Cue-aufgelöste Vorkommen lokal binden │ (Identität maskieren / Nicht-Identität sperren) │ 2. Unklare Homonyme: enger Ausschnitt → Passage-LLM │ 3. Rest → GLiNER (Skip bereits gebundener Spannen) │ 4. Mappings für Generate │ └─ Lehrer (nur Lernmodus) Stufe 1: unveränderter Nutzersatz → OpenRouter-Detect Stufe 2: Nutzersatz ohne cue-sichere Oberflächenformen Vergleich Schüler ↔ Lehrer Uneinigkeit / neue Identität → Nutzer → Cue/Sinn Einigkeit + bekanntes Label → Cue verstärken ``` Generate folgt auf geprüfte bzw. schülerseitig gebaute Mappings, ohne zweiten Voll-Detect. ## 4. Ist-Stand (Code, 2026-09-11) Nicht mit dem Zielbild verwechseln. Älterer Stand vor der Umsetzung nach §6: - `_learning_pause` hing OpenRouter-Detect an den **gerenderten** Prompt, dann Verwandtschaft, GLiNER, Cues, Passage, Popup. - `decision_for_mention` nagelte bei nur Identity-Hits jeden neuen Cue fest (Tag-21). - Admin: `semantic` | `learning`. **Additiv nach Umsetzung §6:** Schülerpfad in `detect_pipeline.py`, Lehrer auf dem Nutzersatz, Admin-Modi `student` | `learning_full` | `learning_reduced` | `learning_manual` | `bypass`. Tabellen `label_senses`, `label_sense_cues`, `pending_mask_reviews` bleiben die Lernspeicher. ## 5. Anforderungen an die Umsetzung (nach Finalisierung) 1. Policy: `decision_for_mention` so ändern, dass ein neuer Cue bei nur einem Sinn **sichtbar bleibt** (nicht automatisch binden). Cue-Hit bleibt bindend. 2. Schülerpfad als eigene, testbare Funktion; `_learning_pause` und später `semantic` hängen daran, sobald §6 das festlegt. 3. Lehrer Stufe 1: Detect-Schema auf dem Nutzersatz, Offsets vergleichbar machen (GLiNER `person|place|…` ↔ Detect `PERSON|…`). 4. Diff nur auf User-Spans; Lehrer-Miss eines bereits nutzerbestätigten Cues nicht automatisch verlernen. 5. Popup über vorhandenes `MaskReviewPanel`, Inhalt = Diff und neue Identitätskandidaten, nicht jedes schon gelöste Cue-Vorkommen. 6. Admin: zwei Lernstufen wählbar (konkretes Schaltermodell laut §6). 7. Tests: Tag-21-Sushi (Identity-Hits, Cue `Frau` vs. neuer Cue „essen“); Diff-Fälle; kein Klartext in Compact-Diagnose; Local-URL-Policy für GLiNER bleibt. 8. Docs additiv in `guardrails.md` §22.4, `privacy_gateway.md` §9.7, `admin_diagnostics.md`. Bestehende Absätze nicht kürzen. Dieses Work-Order-Dokument als Konzept-Home belassen, bis der Code dem Zielbild entspricht. 9. Kein Commit/Push, unless explicitly requested. Nicht in diesem Slice: Fine-Tune, neues NER-Repo, Wortlisten-Editor, Shared-Identity. Journal-Generate-Pause ist durch §6.9 **doch** im Schnitt (alle persönlichen Detect-Aufrufe). ## 6. Offene Punkte — geschlossen 2026-09-11 1. **Start ist Stufe 1 Lernen**, nicht Schüler-allein und nicht der alte `semantic`-Alltag. Schüler und Lehrer-Klartext (Nutzersatz) parallel, Diff zum Nutzer, dann Generate. 2. **Admin:** Zielpfad + Lernen (automatisch 1 / automatisch 2 / manuell) + Bypass. Bypass mittelfristig weg. Default: `learning_full`. 3. **Stufe 2 vollständig** im ersten Schnitt. 4. **Lehrer weg** → manuelle Review aller GLiNER-/Schülerfunde. **GLiNER weg** → im Lernmodus manuell nach Vorauswahl; sonst Bestätigung vor öffentlichem Klartext-Egress. 5. **Verwandtschaft bleibt** eigener lokaler Schritt vor GLiNER. 6. **Vergleich:** enthaltene Spanne / gleicher Wortlaut; Mapping inkl. FOOD≠PERSON; nur abweichender Schutz fragt; Cue nicht still ändern; Lehrer-Miss ohne Meldung kein Popup. Bestätigter Cue bei Typkonflikt zählt, fragt aber nicht erneut. 7. **Diagnose:** Zähler ohne Klartext, keine Langeweile-Kennzahl. 8. **Mini-LLM** nur bei schon beiden Sinnen, auch in Stufe 1. 9. **Alle persönlichen Detect-Aufrufe**, einschließlich Journalentwurf. ## 7. Context Bundle für die Umsetzungs-Session 1. Diese Datei. 2. `docs/architecture/functional/documentation_index.md` 3. `docs/architecture/functional/guardrails.md` (§22.4, Invarianten) 4. `docs/architecture/technical/privacy_gateway.md` (§9.7) 5. `docs/architecture/technical/admin_diagnostics.md` 6. Code: `backend/detect_learning.py`, `backend/dialogue_turn.py`, `backend/gliner_client.py`, `frontend/src/pages/AdminProvidersPage.jsx`, `frontend/src/components/MaskReviewPanel.jsx`, `backend/tests/test_detect_learning.py` Nicht den ganzen `docs/`-Ordner laden. Dialog-/MVP-Fachstand nicht stillschweigend festlegen. ## 8. Prompt für die neue Session Den folgenden Block unverändert in eine **neue** Cursor-Session mit frischem Kontextfenster einfügen. ``` Arbeite im Repo C:\Dev\Kansho. Sprache: Deutsch. Zuerst in den Planmodus wechseln (SwitchMode → plan). Noch keinen Code schreiben, keine Policy umbauen, nicht committen. Auftrag: Selbstlernende Detect-Pipeline gemäß docs/work_orders/detect_self_learning_pipeline.md Das Dokument ist Konzept-Home. Es ersetzt guardrails.md / privacy_gateway.md nicht. Der Code hängt GLiNER und Cues noch hinter OpenRouter-Detect; decision_for_mention nagelt bei nur Identity-Hits jeden neuen Cue fest. Beides soll weg, aber erst nach Finalisierung der offenen Punkte. Sofort laden (nur dieses Bundle): - docs/work_orders/detect_self_learning_pipeline.md (vollständig, besonders §2, §3, §6) - docs/architecture/functional/documentation_index.md - docs/architecture/functional/guardrails.md (§22.4 und Invarianten) - docs/architecture/technical/privacy_gateway.md (§9.7) - Ist-Code: backend/dialogue_turn.py (_learning_pause), backend/detect_learning.py (decision_for_mention, apply_gliner_if_enabled, auto_resolve_ambiguous) Danach mit mir im Planmodus §6 der Work-Order Punkt für Punkt schließen. Nicht raten. Nicht „Bevorzugte Richtung“ als Entschieden behandeln. Erst wenn §6 schriftlich entschieden ist, einen knappen Umsetzungsplan vorschlagen (erster Schnitt vs. später). Umsetzung erst nach meiner Freigabe, dann Agent-Modus. Invarianten, die nicht zur Disposition stehen: - Identität lokal; kein stilles Identity aus OpenRouter/GLiNER - keine Wortliste; Sinne/Cues aus Bestätigungen - Cue gilt pro Vorkommen, nicht lexemweit (Sushi-Tag-21) - Stufe-1-Lehrer sieht den unveränderten Nutzersatz - GLiNER nicht als alleiniges Detect in die Detect-URL - Gateway nicht abschaltbar - bestehenden GLiNER-Client/Cues/Review-UI umverdrahten, nicht löschen - Docs additiv; kanonische Kapitel nicht kürzen Zielbild in einem Satz: Schülerpfad lokal zuerst, Lehrer nur im Lernmodus, zwei Stufen, Mensch bei Diff und neuer Identität. ```