TGV · KI-First-Architektur

Wie eine KI-First-Anwendung entsteht

Beschluss 17.09.2026: RAG und fachliche Arbeit: Bauplan ab 18.09., Bestand, Rechtevertrag und Abnahme. Historische Betriebsangaben unten sind datierte Befunde, keine aktuelle Live-Auskunft.

Nicht Bildschirme mit ein bisschen KI, sondern ein Gehirn (Agent), das mit Händen (Skills) arbeitet und dünne Oberflächen (Seiten) bedient. Hier: wie das zusammenspielt — und wie es mit den Seiten wechselwirkt.

1Das Prinzip — Gehirn · Hände · Oberfläche

Die Umkehrung des klassischen Apps: die Seite denkt NICHT, sie hostet ein Fenster auf den Agenten. Intelligenz lebt im Agenten, Fähigkeit in den Skills, die Seite zeigt & nimmt entgegen.

Gehirn

Der Agent

Plant, entscheidet, wählt Werkzeuge, formuliert. Adaptive Persona je User/Mandant. agent_loop

Hände

Die Skills

Tun die Arbeit: extrahieren, klassifizieren, abgleichen, suchen, versenden. ~45 Bausteine. /api/skill/*

Oberfläche

Die Seite

Dünn: zeigt Karten, nimmt Eingaben, rendert kanonisch. Denkt nicht. core_shell + engine.js

2Wie eine Antwort entsteht — der Fluss

Von der Absicht bis zur gerenderten Karte. Jeder Schritt ist scope- und vertraulichkeits-gegatet (RLS + conf), der Ton kommt aus der adaptiven Persona.

IntentDu fragst / Seite ruft

Texteingabe, Klärung, Screen-Kontext

Agentplant

versteht Absicht, wählt Werkzeuge, kennt den Kontext (CORE/RKA/Steuer/Vertrag)

Skills/Toolstun

ruft die passenden Skills/Lese-Tools — scope-gate fail-closed

DatenRLS-scoped

nur Mandant + erlaubte Vertraulichkeit (Owner-Bypass)

AntwortKarten + Empfehlung

render_hints → Envelope, keine nackten IDs

Seiterendert

engine.js zeichnet die Karten in den Screen — du gibst frei

3Die Wechselwirkung mit den Seiten

Seitenbau (wie eine Seite entsteht) und KI-First (Agent+Skills) sind zwei Gesichter DESSELBEN Systems — verbunden durch den einen Katalog und die eine Engine.

Seite → Agent

Jede Klärung / Frage / Composer-Eingabe ruft den Agenten (skillFetch core-chat). Die Seite ist ein dünnes Fenster — R-V4-17: NIE einen screen-eigenen Composer bauen.

Agent → Seite

Der Agent rendert Karten (render_hints) in die Seite, schlägt Aktionen vor, und in Phase 0 den Zweck der Seite selbst (Dialog: KAI schlägt vor, du validierst).

Seite → Skills

Für strukturierte Reads ruft die Seite Skills direkt (restGet / skillFetch, RLS) — kein Agent nötig. Reine Daten-Darstellung.

Katalog verbindet

Jede Funktion (FX · Skill · Agent) lebt einmal im Kanon-Katalog mit Vertrag {scope · i18n · produkt · vertraulichkeit}. Die Seite konsumiert sie per Slug — nie neu programmiert.

↳ Diese Funktions-Landschaft IST das „② Funktionen"-Regal des Kanon-Katalogs im Seitenbau-Konzept. Die zwei Dokumente greifen ineinander.

3bWas ist eine „Karte"? — der render_hint-Vertrag

Präzisierung (JC-Frage 13.07.): Eine „Karte" ist kein freies Template, sondern ein Daten-Vertrag: der Agent liefert Daten + einen Typ (render_hint) — NIE Markup (R-92). Der Renderer bindet jeden Typ an GENAU EINEN kanonischen Baustein. Deshalb ist die Tabellen-Karte (data-table: Suche · Sortierung · Multiselect · Pagination) etwas völlig anderes als die Klärungs-Karte (klaerung-card: R-94-Raster, Quell-Links, Entscheidung) — zwei Bausteine, zwei Verträge, EIN Prinzip. Definiert sind die Verträge in CARD_SCHEMA_REFERENCE.md (AGENT-CHAT#01, #697) + kai_renderer.js (Chat) + engine.js BAUSTEIN/POLICY (Sektionen); die Mensch-Sicht je Baustein steht in der Komponenten-Landkarte.

render_hint (Daten-Typ)Was der Agent damit sagtKanonischer BausteinSSOT
result_cardgenerische Treffer-/Listen-Antwortresult-tablekai_renderer.js · CARD_SCHEMA §1
contract_cardein Vertrag (Fristen, Betrag, Status)ds-card (Kanon-Hülle)CARD_SCHEMA §2
month_summary_cardMonatsstand (Kennzahlen-Block)kpi-blockCARD_SCHEMA §3
account_status_cardKonten GRUPPIERT (Karten-Flut-Fix; IBAN maskiert R-51)account-status-cardCARD_SCHEMA §4 (#695)
next_actions_cardpriorisierte nächste Aktionen (Aggregat)vorschlags-chips + ListeCARD_SCHEMA §5
travel_summary_cardReise-Zusammenfassung (RKA)ds-cardCARD_SCHEMA §6
approval_cardSchreib-Freigabe (Write-Pfad: „noch nichts gespeichert", Bestätigen rechts)approval-card (R-94)CARD_SCHEMA §7
klaerung_cardKlär-Fall als bedienbare Karte (8 Fall-Typen, Quell-Links Beleg+Buchung)klaerung-cardkai_renderer.js (PLAT#03 #727)
prose · list · dataTable · approvaldie 4 Antwort-FORMEN des Sektions-Renderers (Policy pickComponent wählt — nicht der LLM)long-prose · data-table (voll: Suche/Sort/Multiselect)engine.js BAUSTEIN/POLICY
memoir_fiche · souvenir · etappe5 · photo · synopsisgabriels Karten — GLEICHES Prinzip, eigener Wortschatz (Achse TGV-weit, Vokabular je Mandant)ds-card · beleg-preview · audio-linegabriel.html render_hints

Bindung: der Agent wählt den TYP · Policy/Renderer wählen den Baustein · der Harness prüft das Ergebnis (R-92: kein Schema-injiziertes Markup · R-91: keine nackten IDs). Neuer Karten-Typ = neuer Vertrag in CARD_SCHEMA + Baustein im Katalog — nie ein Ad-hoc-Template im Screen.

4Element-Tabelle · Die Agenten

Wer denkt — je Kontext ein Agent, EINE geteilte Engine, adaptive Persona.

AgentRolleKontext / WoStand
CORE-CHATAdaptiver Orchestrator — plant + ruft ~10 Lese-ToolsCORE · RKA · Steuer · Vertragstaged
AGENT-ORCH#01LLM-First Triage — Dokument → Klassifikation/EntitätIntake-Pipeline (Shadow)shadow
Klärung-AgentKlärungs-Logik + Karten (list_pending → Envelope)Klärung-Screenskill live
Persona (adaptiv)Ton/Verhalten je User+Mandant, editierbar (prompt_config)CANON_LAYER im Promptlive
FACH-AGENT je DokumentartÜbernimmt NACH der Triage: füllt die Pflichtfelder seiner Dokumentart, setzt die Vertraulichkeit fachlich, knüpft die Verbindungen (Rechnung ↔ Vertrag ↔ Projekt ↔ Begünstigte). Darf ein stärkeres Modell nutzen als die Triage.Intake-Kaskade, nach ORCH — Zuständigkeit aus der Registry, nicht hartcodiertKanon 04.08. · Bau offen (#303)
GabrielEigenes Produkt (Biografie/Lebenserinnerung)gabriel.htmllive

4b · Die Kaskade nach der Triage — Kanon-Regel (JC 04.08., E-50/#303)

⛔ KANON: Nach der Triage übernimmt ein FACH-AGENT je Dokumentart. Die Triage entscheidet nur, worum es geht — nicht, was es bedeutet. Der Fach-Agent besitzt die Fach-Fragen seiner Dokumentart und ist verantwortlich dafür, dass die Kette vollständig wird: Stammdaten · Vertraulichkeit fachlich · Fristen · Verknüpfungen. Und er darf ein stärkeres Modell nutzen als die Triage: die Modellstärke folgt der ROLLE, nicht nur dem Preis — Kosten werden dort ausgegeben, wo Wert entsteht. Regel: R-178.

Warum das keine Komfort-Frage ist (der Kosten-Beweis, E-48/#301): KAI fragte JC sinngemäß „ist diese Versicherung vertraulich?" — gemessen waren alle 4 Hiscox-Verträge samt 16 rag_chunks pauschal streng_vertraulich, das Dokument selbst null; die Stufe entstand beim Ingest, pauschal. Ein Fach-Agent hätte erkannt: reine Betriebs-Versicherung ⇒ entitäts-intern. Die fehlende Kaskade kostet nicht Komfort, sondern Datenqualität und Nutzbarkeit — sie sperrt KAI aus den eigenen Verträgen aus.

Reuse statt Neubau — der Mechanismus existiert bereits: 08_OPS/chat_engine/gateway.py:17-21 hat die Tier-Tabelle trivial → haiku · standard → sonnet · komplex → opus und wählt heute „pro Anfrage das BILLIGSTE Modell, das die Anforderung erfüllt" (gateway.py:3). Es fehlt kein Getriebe, nur ein Anspruch: eine ROLLE muss einen Tier beanspruchen dürfen. Das Baseline-Protokoll MODELLWAHL01_BASELINE_2026-08-02.md denkt Modellwahl bisher ausschließlich kostenoptimierend, nicht rollenbasiert.

⛔ EIN Ort, an dem steht wer zuständig ist — die Zuständigkeits-Registry doc_type → Fach-Agent → Skills → Pflichtfelder → Modell-Tier.
Ort: 02_SKILLS/_registry.yaml, erweitert um eine routing:-Achse — plus ein generiertes DB-Read-Model für die Laufzeit (Sync-Richtung Code → DB, nie zurück; dasselbe Muster, das für die Taxonomien schon entschieden ist, Taxonomie-Register).
Warum dort — mit Gegenprobe: ① _registry.yaml ist bereits „DIE eine deklarative Wahrheit für Skill → Verdrahtung" und generiert + validiert heute schon 6 zuvor divergierende Listen (_registry.yaml:1-16); es ist der einzige Kandidat mit einem laufenden Guard (08_OPS/validate_skill_registry.py, „Drift = exit 1"). ② Es weiß schon, dass contract-extract den Ghost ersetzt (_registry.yaml note zu contract-extract) — die Wahrheit steht da, nur liest sie niemand. ③ Gemessene Gegenprobe: eine doc_type-Achse hat es heute nicht (0 Treffer auf stream/doc_type) — die Erweiterung ist echt, nicht eingebildet. ④ Die Alternative 08_OPS/agent_orch01/taxonomy.py:60-88 trägt zwar schon STREAM → SKILLS, ist aber hartcodiertes Python (R-168) und ausdrücklich die Vergleichs-Vorlage für den Agenten, nicht die Betriebs-Wahrheit. ⑤ Eine Tabelle skill_routing_rules existiert ausdrücklich nicht (PIPELINE_A2_MAIL_INTAKE.md:166,270) — deshalb Read-Model statt Neuerfindung.
⛔ Die harte Grenze dieser Entscheidung — die Registry ist der richtige Ort, aber sie ist heute NICHT vollständig (gemessen 04.08., AGENT-ORCH#01 · Register #307): die Namen der n8n-Skills stehen nirgends versioniert im Repo — ⚠️ diese meine eigene Formulierung war zu grob und ist am 04.08. nachgemessen korrigiert worden. Richtig ist: _registry.yaml hat sehr wohl ein Muster für „Vertrag da, Bau woanders" — class: n8n + n8n_wf_id + bundled:false/version_tracked:false (_registry.yaml:322-345 auf master, dort 3 Einträge). ⛔ Und die Angabe des Refs ist hier keine Pedanterie, sondern der ganze Unterschied (R-181): das Feld repo_dir: false — das den Verzeichnisbaum-Check genau für diesen Fall entschärft — existiert auf master NICHT (0 Treffer), auf dem ungemergten AGENT-ORCH#01-Branch claude/great-bell-6afe55 aber 18× (n8n_wf_id dort 31×). Dort ist extract-contract-pdf bereits ein echter skills:-Eintrag (class: n8n · repo_dir: false · n8n_wf_id: 5jYCxB9NzqyRMqjI, Notiz „n8n-Workflow AKTIV, aber 0 Executions"). „Gibt es nicht" wäre also falsch gewesen — richtig ist „auf master noch nicht". Die echte Grenze ist eine andere und schärfere: der Ghost tgv-extract-contract-pdf steht dort ausschließlich als Kommentar im Block „Referenziert, aber NICHT implementiert" — ausdrücklich „bewusst NICHT als skills:-Eintrag (sonst bricht der Verzeichnisbaum-Check)" und „von beiden Parsern ignoriert" (_registry.yaml:436-449). ⇒ Es fehlt nicht die Versionierung, sondern der Guard hat dort eine bewusste Parser-Blindstelle: ein Offline-Guard kann belegen, dass ein Routing-Ziel kein skills:-Eintrag ist — nicht, dass es nirgends existiert, denn die Fälle, die er finden müsste, sind genau die, die als Kommentar unsichtbar gemacht wurden. Dieser Befund gilt unabhängig vom Ref — der Kommentar-Block steht auf master und auf dem ORCH-Branch (dort :628-630). ⚠️ Und dort erzeugt der Fix einen Widerspruch mit sich selbst: 260 Zeilen über dem Kommentar, der sagt „bewusst NICHT als skills:-Eintrag", steht der Skill inzwischen als skills:-Eintrag. Beim Merge muss der Kommentar mit weg, sonst behauptet die SSOT beides gleichzeitig. Genau daran ist unsere eigene Annahme zerbrochen (siehe Korrektur in §4c: der „Ghost" hatte einen aktiven n8n-Workflow). Die routing:-Achse ist erst vollständig, wenn ALLE Ziele als skills:-Einträge geführt werden — auch die n8n-Skills, für die das Muster bereits existiert; bis dahin ist jede Ghost-Prüfung eine Teil-Prüfung und muss sich als solche ausweisen (R-160: die dritte Antwort ist n/a, nicht grün). Der Bau-Weg ist damit kleiner als gedacht: nicht „Versionierung für n8n erfinden", sondern das vorhandene class: n8n-Muster auf die fehlenden Ziele anwenden und den Kommentar-Block leerlaufen lassen.

⚠️ Zwei Nebenbefunde IN der SSOT, beide gemeldet, keiner von dieser Lane gefixt: ① Derselbe Kommentar-Block behauptet „ROUTING-FLIP STEHT NOCH AUS … Bis zum Flip routet der Live-Orchestrator weiter auf den Ghost" — das ist seit der ORCH-Messung vom 04.08. überholt (aktive prompt_config id=31 führt bereits [contract-extract, tgv-store-file-to-drive]). Eine SSOT, die ihren eigenen erledigten Stand als offen führt, schickt den nächsten Leser auf die falsche Fährte — dieselbe Klasse wie R-146. ② Derselbe Block nennt den Flip „JC-gated" — nach R-180 und JCs Wortlaut „Ich gate nix." ist auch das eine erfundene Freigabe-Instanz, diesmal nicht im UI, sondern in der Verdrahtungs-Wahrheit selbst.

4c · Die Ernte-Liste — der Fach-Agent ist ein Blueprint von 2026, kein Entwurf

JCs Satz „alles ist da, aber nicht verdrahtet" ist belegt: TGV -App files/TGV_AGENT_SPEC_CONTRACTS_V2.md (13.04.2026) beschreibt exakt die Kaskade — Haupt-Triage delegiert an fünf Spezialisten. Zu ERNTEN, nicht neu zu erfinden (NUXIN-N②); jede Zeile mit ehrlichem Ist-Stand.

Baustein aus dem BlueprintWas er leistetIst-Stand in TGV (gemessen 04.08.)
5 Sub-AgentenFinance (Tranchen, Budget, IBAN-Betrugsschutz) · Legal & Deadline (Kündigungsfenster, Widerspruch, Alert 5 Tage vorher) · Digital-Asset/Subscription (Zombie-Abos, Domain-Ablauf, Auto-Verlängerung) · Real-Estate (umlagefähige Kosten, Hausgeld-Vorjahresvergleich) · Document-Completeness (Checklisten, z. B. Schlussrechnung braucht Abnahmeprotokoll)nicht portiert kein Begriff „Fach-Agent" im Kanon (KONZEPT_AGENTEN_INSZENIERUNG.md:16-24 kennt nur ORCH · TOKEN · Dokumentalist)
context_summaryLebendes Gedächtnis je Vertrag (bis 4000 Zeichen): „Mängelrüge offen", „Tranche 2 bezahlt" — jeder Sub-Agent liest es, bevor er handeltnicht portiert
priority_scoreDringlichkeit aus Fristnähe × finanzieller Wirkung — schützt GF-Zeit, statt alles gleich laut zu meldennicht portiert
kb_contracts_patternsLernschicht: klassifiziert der Mensch ein unbekanntes Dokument, werden Muster/Keywords gespeichert — das System lernt⛔ existiert NUR als Name in einer RLS-Liste (05_SCHEMA/157:66,115) — nie mit CREATE TABLE angelegt
Rollentrennung Extraktion ≠ Bedeutung„Was steht im Dokument?" ≠ „Was bedeutet der Vertrag operativ?" (Betriebs-/Projekt-/Privat-Klassifikation, Split-Beneficiaries, Wealth-Relevanz)halb Extraktion live (contract-extract), die Bedeutungs-Hälfte fehlt — TGV_CONTRACT_PROFI_SKILL_ARCHITECTURE_v0100_20260423.md:16-45
⛔ Die Wurzel des Ghost-Skills — kein Tippfehler, sondern ein Plan, der nie Bau wurde: 08_OPS/agent_orch01/taxonomy.py:61,77 routet VERTRAG auf tgv-extract-contract-pdf — genau den Namen aus dem Blueprint (TGV_CONTRACT_PROFI…:18). Implementiert wurde stattdessen contract-extract (02_SKILLS/tgv-skill-contract-extract/skill.py, Endpoint app.py:1343-1360), und die Skill-SSOT weiß das auch („ersetzt Ghost tgv-extract-contract-pdf, Audit #479"). Nur die Vergleichs-Konstanten zeigen weiter auf den Plan statt auf den Bau. Regel: R-179. Zugehörig offen: der Routing-Flip (VERTRAG_01…/build/LIFT.md Schritt 3) ist nie abgehakt.

⚠️ KORREKTUR 04.08. 01:24 UTC (AGENT-ORCH#01, live gemessen) — der Satz „die Triage schickt Verträge an ein Nichts" stand hier und ist WIDERLEGT. Er bleibt sichtbar durchgestrichen stehen, statt still verschwunden zu sein: die Triage schickt Verträge an ein Nichts. Gemessen: die aktive prompt_config id=31 führt für Vertrag ["contract-extract", "tgv-store-file-to-drive"] — 0 Ghost-Treffer in der gesamten Live-Taxonomie; und tgv-extract-contract-pdf hat sogar einen aktiven n8n-Workflow („Extract Contract PDF v0.5", 0 Executions). „Ghost" hieß also kein Python-Skill — nicht „nichts vorhanden". Der Live-Pfad ist lückenlos.

⇒ Der Ghost saß in Python-Konstanten für Paritäts-Vergleiche, Schatten-Läufe und Offline-Evals. Er hat nie eine Vertragsverarbeitung ins Leere geschickt — er hat die Vergleichsmessungen gegen einen Referenzwert laufen lassen, den es so nicht gibt. Das ist der leisere und gefährlichere Fall: ein toter Referenzwert bricht nichts, er vergiftet still die Evals, die uns sagen sollen, ob wir richtig liegen (verwandt R-172 und R-173). Warum die Narbe stehen bleibt: sie zeigt, wie eine plausible Annahme („Name fehlt ⇒ Verarbeitung läuft ins Leere") an einer Messung zerbrochen ist — genau der Reflex, den R-175 für KAI verlangt, hier auf uns selbst angewandt.
Reihenfolge, bindend: Erst die Kaskade, dann der Verträge-Screen (E-30). Ein Screen vor dem Fach-Agenten zeigt leere Felder und wirkt wie ein Bau-Fehler, obwohl die Datenlücke davor liegt — heute belegt: prf_contracts.project_id 0 belegt, direction 1 von 190 (Felder da seit Mig 193/195, kein Agent schreibt sie), mandant_id default 'jcbinetti' (Mig 193) = kein echter Multi-Mandant-Fill.

⛔ DIE URSACHE IST SEIT 04.08. GEMESSEN — und sie ist eine andere als angenommen: contract-extract wird geplant, aber nie ausgeführt. Null agent_events; alle drei seit dem Flip durchgelaufenen Verträge sind ohne ihn verarbeitet worden (AGENT-ORCH#01, 04.08. 01:24 UTC). Deshalb ist prf_contracts leer — nicht wegen eines Ghost-Namens. Damit wird die Reihenfolge-Auflage stärker, nicht schwächer: der Verträge-Screen zeigt leere Felder, weil der füllende Skill nie läuft. Ein Screen kann das nicht heilen, und ein Bug-Report gegen den Screen würde am falschen Ende ansetzen. ⚠️ Hypothese, nicht gemessen Warum er nicht läuft (Verdacht Reader-Gate BR#03) ist noch nicht belegt — bis dahin ist die Ursache „er läuft nicht" Tatsache, die Erklärung „weil …" nicht.

4d · Der KVP-Agent — wer den Kreis schließt Gate-A-Stoff, Bau ab 07.08.

JC 04.08. (Anlass, sinngemäß): „Der alte Matcher sollte auch lernen. Ziel ist, dass durch die Klärung und die Konversation mit dem User das System lernt und ORCH und die anderen Agenten immer bessere Entscheidungen treffen." — dazu die Frage, ob das verdrahtet ist. Gemessene Antwort: der Kreis ist eine offene Linie.

StufeStandFundstelle
① Erfassen — Korrektur → learning_events⚠️ Sediment87 Zeilen / 36 Korrekturen, aber Backfill/Bulk — 0 aus dem Chat (DATEN#01, live 10.08.) ⇒ „User korrigiert seit Monaten" widerlegt. 05_SCHEMA/050 · Schreibpfad tgv-skill-klaerung/skill.py:156,558,630,683
② Verdichten — → kb_suppliers/pattern_rules❌ Promoter läuft NIEpattern_rules=0 · Promoter (Windows-Task nie eingerichtet, 0 agent_events) liest learning_events gar nicht — Mining ist per SKILL.md:78 auf „Iter 18+" vertagt. Schwellen 05_SCHEMA/057 · View v_pattern_rules (025)
③ Zurücklesen + Anwenden❌ DREIFACH offenreadback.py DRY („schreibt NICHTS") · Live-Engine erkennt 200+, wendet 0 an (stempelt nur skills_done_versions). Scharfschaltung E5R3_…STAGED.sql · Details in der Fortschreibung 4d· unten
Das System erkennt seit Monaten Muster — und wendet nichts an.⚠️ Korrigiert 10.08. (KVP#01 + DATEN#01, live gemessen): Die frühere Fassung sagte „der User korrigiert seit Monaten, niemand liest zurück" — gemessen ist es schärfer: der Korrektur-Strom ist Sediment (0 Chat-Korrekturen), UND die Live-Engine LIEST die Muster (200+), wendet sie aber nie an (stempelt nur). Ein Fach-Agent, der nicht aus Korrekturen lernt, ist nur ein besserer Rater. Kaskade (§4b) und Lern-Loop sind EIN Bauwerk. Prozess-Beschreibung: TGV_LEARN_ABSCHLUSS_SKILLS_GOVERNANCE.md.

Warum AGENT und nicht Skill: Sortieren unter Mehrdeutigkeit ist eine Entscheidung, keine Handreichung (Skill = Hand · Agent = Gehirn). Auftrag in fünf Schritten: ① aufnehmen (einmal) · ② dreifach klassifizieren — Mehrfachzuordnung ist der Normalfall, nicht die Ausnahme (§4e) · ③ weiterreichen an den zuständigen Ort · ④ verdichten mit Korroborations-Gate — eine einzelne Korrektur ist noch keine Regel · ⑤ rückwirken — genau die heute fehlende Stufe ③.

⛔ Grenzen des KVP-Agenten (bindend): Er entscheidet nichts fachlich — das bleibt beim Fach-Agenten (R-178). Er schaltet nichts still scharf: eine gelernte Automatik ist Governance — sichtbar, abschaltbar, mit Herkunft („gelernt aus deiner Korrektur vom …"). Und er darf ein stärkeres Modell nutzen (R-178): Verdichtung ist Analyse, nicht Triage.
Sein Platz in der Kaskade: Triage → Fach-Agent → Ergebnis → User/Klärung → KVP-Agent → Muster → zurück in Triage und Fach-Agent. ⇒ Er macht aus der Linie einen Kreis. Reuse-Stand: der Loop ist rund 70 % gebaut und 0 % geschlossen — live sind Lern-Modell (050), Schreibpfad Klärung, Promoter-Schwellen (057), Muster-View (025), Korroborations-Gate und die KVP-Erfassung (K-54); fertig aber DRY ist readback.py; staged die Scharfschaltung; offen sind KVP-Status-Screen (#254), der Daumen (#302, zu ernten) und kb_contracts_patterns (nie angelegt, nur Name in 05_SCHEMA/157:66,115). ⇒ Der Aufwand liegt in Scharfschaltung, Scope-Achse und Agenten-Rolle — nicht in neuer Infrastruktur.
⛔⛔ DIE HÄRTESTE OFFENE FRAGE: Gelerntes braucht eine Scope-Grenze (JC-Einwand 04.08.). JC: „Achtung, dies gilt möglicherweise für einen bestimmten Scope. Das soll der Agent auch rausfinden mit dem Kontext." Ein Muster ohne Scope ist fachlich falsch (eine C3-Gewohnheit ist keine C4-Gewohnheit) und ein Datenschutz-Bruch (private Muster im Geschäfts-Mandanten).
⚠️ Messfrage ① ist damit beantwortet — aus dem Schema, nicht geschätzt: learning_events trägt weder mandant_id noch entity als eigene Spalte (05_SCHEMA/050: user_id · created_at · context_doc_id · context_txn_id · decision_id · skill_name/-version · field · system_suggestion · user_choice · was_correction · confidence_pre/post · source · notes · raw_payload). entity kommt dort nur als möglicher Wert von field vor — das System lernt also über Entitäten, weiß aber nicht, in welcher es gelernt hat.
Der Scope ist nur indirekt rekonstruierbar — context_doc_id → documents.entity → entities.slug → entities.mandant_id (Mig 209; documents hat selbst keine mandant_id, 05_SCHEMA/196:12 „Mandant wird über entity geführt"). ⛔ Und dieser Bezug ist vergänglich: beide Kontext-Fremdschlüssel stehen auf ON DELETE SET NULL — wird das Dokument gelöscht, verliert das Lern-Ereignis rückwirkend seinen einzigen Scope-Bezug. Ein Muster, das später daraus verdichtet wird, ist dann nicht mehr zuzuordnen.
⇒ Vor jeder Scharfschaltung: ① additive Migration für die Scope-Achse (die Ableitung über den Join reicht nicht, weil sie löschbar ist) · ② Geltungsebene als Feld am Muster (global · Mandant · Entität · Projekt) — der KVP-Agent schlägt vor aus dem Kontext, die Governance bestätigt · ③ ⛔ dasselbe Scope-Objekt wie §8b verwenden — sonst entsteht ein vierter Scope-Begriff und wir haben die Drei-Vokabular-Krankheit ein zweites Mal.
Entwurf liegt (KVP#01, STAGED, nicht gefahren): 01_ITERATIONS/KVP_01_LERN_LOOP/scope_achse.STAGED.sql — additiv auf learning_events + pattern_rules, §8b-Vokabular (mandant_id·entity·project_code) + geltungsebene, denormalisiert gegen die Löschbarkeit; Rettungs-Backfill + VALIDATE separat, JC-Hand. Mig-Nummer von Tower.

4d· — Fortschreibung KVP#01 (10.08.): der Kreis ist DREIFACH offen, und eine Ablage ging verloren gemessen, kein Bau

Die Stufen ①–③ oben stimmen im Gerüst — KVP#01 hat sie live gegengemessen (mit DATEN#01) und drei Dinge geschärft: der Kreis ist an drei Stellen offen, nicht an einer · JCs Feld-Vision war schon gebaut und ging verloren · und die Ablage dafür braucht ein eigenes Zuhause, kein fünftes Vokabular.

⛔⛔ Der Kreis ist DREIFACH offen (korrigiert DATEN#01s „die Engine arbeitet"):
① learning_events → pattern_rules — der Übersetzer läuft nie: der Promoter ist ein Windows-Task, nie eingerichtet (0 agent_events), und er liest learning_events ohnehin nicht (Mining auf „Iter 18+" vertagt, tgv-skill-pattern-promoter/SKILL.md:78).
② pattern_rules → Engine — die Regeltabelle wird nicht gelesen: die Live-Engine TGV_Skill_Pattern_Engine_v0_2 liest kb_suppliers/documents, nie pattern_rules/v_pattern_rules.
③ ⭐ Engine → Dokument (das teuerste) — die Engine stempelt nur skills_done_versions und schreibt entity/category nie zurück. „200+ Entscheidungen" heißt: 200+ mal erkannt und gemeldet, 0 mal angewandt. Das System erkennt seit Monaten Muster und tut nichts damit.
⭐⭐ Und eine Ablage ging verloren (die stärkste Fundstelle): Mig 010 (contract_agent) gab dem alten Vertrags-Agenten den Prompt „entscheide selbst, was für DIESEN Vertragstyp relevant ist" + die jsonb-Ablage prf_contracts.extracted_data — genau JCs selbst-lernendes Feld. Der heutige tgv-skill-contract-extract nennt extracted_data 0× (git log -S = 0; Skill neu in 0afb6525 „VERTRAG#01" #498). ⇒ Kollateralschaden beim Neubau, nicht Absicht — die Fähigkeit lebte im Vorgänger, die Neuschrift begann leer. NUXIN-N② in Reinform: nicht was gelöscht wurde ist die Gefahr, sondern was beim Neubau nicht mitkam.

Zwei Lern-Dimensionen, zwei Zuhause (Tower#35 entschieden 10.08.):

DimensionZuhause (entschieden)Was zu schließen ist
A · provider → {entity, category}kb_suppliers — Live-Substrat, NUXIN „bau auf was läuft" (256 Zeilen, von der Engine gelesen)(a) learning_events-Korrekturen → kb_suppliers-Upsert · (b) ⭐ die Engine muss ANWENDEN statt stempeln — das ist die eigentliche Arbeit
B · Feld/Datum (JCs Vision)pattern_rules wiederbeleben (scope='extraction' im CHECK, Seeds da) — NICHT kb_suppliers, NICHT neue TabelleLeser bauen (= derselbe Aufwand wie neue Tabelle, aber kein 5. Vokabular) + jsonb-Beutel auf documents als Rohstoff-Eingang
Warum getrennt: kb_suppliers hat PK (pattern, entity) — keine doc_type-Achse, kein field/date-Selektor; seine Datumsspalten (renewal_date, last_seen) sind Werte über einen Lieferanten, keine Meta-Regeln welches Feld zählt. Feld-Lernen dort hineinzuzwingen wäre der Wildwuchs-Fehler. Die Scope-Achse (§8b-Objekt) gehört an beide Zuhause: kb_suppliers hat entity schon, das Feld-Zuhause bekommt sie neu.

Vier Lücken für Dimension B (in §4d bisher nicht benannt):

LückeBefund (Fundstelle)
① kein Feldbeutel auf documentsVerträge haben extracted_data (applied); documents nicht — ai_suggestion=TEXT (nicht GIN-abfragbar), media_meta STAGED (Mig 239)
② ORCH-Vertrag fragt kein FeldSAFE_AGENT_PROMPT (agent_loop.py:73) = doc_type·stream·entity·skill_plan — kein Datum (Register #337/N)
③ keine Brücke Feld-in-N-Docs → Spaltelearning_events zählt Korrekturen, nicht die Häufigkeit gesehener Felder
④ RAG speichert, gibt nicht zurückrag.chunks.source_meta existiert (Mig 028), rag.search_chunks gibt es nicht zurück — JCs „im RAG-Chunk" halb gebaut
Der Loop lernt heute aus Korrekturen — nicht aus Extraktionen (was der Agent SIEHT).Die Felder, die contract-extract/vision-extract finden aber verwerfen (vertragsbeginn·kündigungsfrist·Datum), betreten den Loop nie. Das ist der zweite Rohstoff, der Brille C (§4e) füllt.
⛔ Feld-Wildwuchs-Wand (Zwilling zur Scope-Grenze oben): kanonische Feld-Taxonomie + Normalisierer = entSameScope() für Felder. Der Beutel nimmt alles (nichts verloren), aber Beförderung zur Spalte setzt Kanonisierung voraus; unkanonisierte Schlüssel bleiben sichtbar+gezählt, aber in Quarantäne — omission_catalogue-Haltung (annotieren, nie still auffüllen).
Entschieden Tower#35, 10.08. (damit der Nächste nicht neu abwägt): ① Schwelle „Feld wird Spalte" = ≥20 Docs / ≥2 Entitäten / treue ≥ résumé → tunable_params (owner_tier=super_admin, is_interim; JC ändert per Zeile, kein Deploy). ② Kandidat automatisch, Spalten-Promotion = JCs Hand (DDL-Kanon); die Vorlage MUSS die Herkunft zeigen („in 23 Docs über C3+C4 gesehen, Beispiele…"). ③ Kanonisierung-vor-Beförderung (Feld-Taxonomie als Wand). ④ scope-CHECK um 'entity' zurückgenommen (Entität läuft über kb_suppliers; 'extraction' existiert schon). ⑤ v_pattern_rules pattern_rules unionen nur im Zuge von Dimension B — heilt nur den DRY-readback, kein Live-Fix.

4e · Die drei Brillen — einmal aufnehmen, dreifach auswerten

JC-Modell, bindend: Dieselbe Äußerung ist gleichzeitig drei Rohstoffe. Sie wird einmal aufgenommen und dreifach ausgewertet — nie dreimal erfasst. Wer sie nur als Fehler-Ticket behandelt, verliert Brille C; wer sie nur ablegt, verliert Brille B.

BrilleFrageRohstoffErtrag
A · Antwort-QualitätWar die Antwort gut?Antwort + Bewertung (Daumen, #302) + Dialog-Telemetrie: Tool-Wahl, Abbrüche, Nachfrage-Ketten, TokenNeuer Lern-Input — u. a. gegen die Klasse „unbemühte Absage" (E-42.C: KAI kapituliert, statt das passende Werkzeug zu wählen)
B · System-VerbesserungWas sagt es über TGV?JC-Befunde · Klärungs-Kommentare · KVP-Vorschläge (K-54) · UX-AuditorRegister-Zeile · Regel · Komponente · Kanon · Skill-Bedarf. ⚠️ Heute die einzige halbwegs laufende Brille — und sie läuft über Tower-Handarbeit
C · Digitaler ZwillingWas sagt es über User, Projekt, Entität, Vorgang?Zuordnungs-Gewohnheiten · Lieferanten-Muster · Orts-Repertoire · Vertraulichkeits-UrteileDas Lebensgedächtnis — Grundlage dafür, nie zu fragen, bevor die Maschine fertig geprüft hat (E-26)
A verbessert die Antwort · B verbessert das System · C verbessert das Wissen über die Welt des Users.JCs Kette für Brille B im Wortlaut: JC-Wunsch → Regelungen → Komponenten → Kanon → Skills. Genau diesen Weg geht heute jede Zeile dieses Kompendiums — nur eben von Hand.
Ressource für vier Kunden (JC 04.08.): das System (bessere Vorschläge, messbare Trefferquote) · die Agenten (Vorwissen statt Raten) · der User (sieht, dass seine Korrektur wirkt; Vorschläge tragen Herkunft) · KAI (kann über den Bestand sprechen: „das hast du bisher immer C3 zugeordnet"). ⛔ Abrufbarkeit ist Teil des Konzepts, nicht Zugabe — ein Bestand, den nur ein Cron liest, ist ein Datengrab. Erreichbar auf drei Wegen: als Werkzeug (Agenten), über die Wissenssuche (KAI) und als Fläche (KVP-Status-Screen, #254).

4fDIE AGENTEN-LANDKARTE — wer sie sind, was sie tun, wie sie zusammenspielen

JC-Auftrag 04.08. (Register #328): „Wer sie sind, was sie können, was sie machen, welche Skills sie abrufen, wie sie alle miteinander gut zusammenspielen. Die Workflows, Cascading und Routinen dieser Agenten." — Die Bausteine standen verstreut über acht Kompendium-Seiten; was fehlte, war die eine Ansicht. Diese Seite erfindet nichts: jede Zeile zeigt auf ihren SSOT, die Definition bleibt dort. ⛔ Und jede Zeile trägt ihren ehrlichen Zustand — läuft · gebaut, nicht verdrahtet · Konzept. Alles andere wäre R-188.

Core-Graph-Anschluss (JC 25.09.2026, #3120; geschrieben). Diese Landkarte liefert Rollenbegriffe, keine ungeprüfte Live-Topologie. Für den neuen Core-Graphen in KAI und Shell müssen Rollen, tatsächlich verfügbare Skills, Aufrufberechtigungen und beobachtete Ausführungen gegen den aktuellen Bestand abgeglichen werden. Entwicklungs-Lanes sind keine Laufzeit-Agenten; ein Skill-Registry-Eintrag beweist allein noch keinen Agenten-Aufruf. Historische n8n-/Drive-Verweise werden weder still zum Core-Ist erklärt noch aus dem weiterhin bestehenden Dashboard-Modell entfernt. Der Gesamtworkflow eines neuen Dokuments (§7f) ist der zweite fachliche Ausgangspunkt, mit gesondertem Nachweis je tatsächlichem Ausführungsschritt.

Die Besetzung — dreizehn Rollen, je EINE Sorge

AgentWas er kann · was er tutSkills / Werkzeuge, die er ruftStand (ehrlich)
KAI · Chat-AgentHauptdarsteller und Dirigent. Analysiert laufend, was jetzt für den User wichtig ist, wählt die Darstellung aus der Komponenten-Bibliothek und führt das Gespräch über alle Modalitäten — Tippen, Klick, Mail, Upload, TriggerLese-Executoren (query_documents · get_transactions · search_knowledge_scoped) · Antwort-Rendererläuft agent_loop.py
ORCH-AgentBühnenmeister hinter den Kulissen: Intake · Triage · Klassifikation · Re-Triage. Sagt, worum es geht — nicht, was es bedeutetSkill-Router mvOybw4cBU7y8X5Y (v0.7.4) · classify-csv · detect-duplicate · resolve-supplierläuft
FACH-AGENT
(je Dokumentart)
Der Spezialist nach der Triage: füllt die Pflichtfelder seiner Dokumentart, setzt die Vertraulichkeit fachlich, rechnet Fristen, knüpft Verknüpfungen (Rechnung ↔ Vertrag ↔ Projekt). ⛔ Darf ein stärkeres Modell rufen — Modellstärke folgt der Rolle, nicht dem Preiscontract-extract · pdf-invoice-extract · tax-extract · upsert-contract-from-invoiceVertrags-Instanz läuft und schreibt wieder (04.08. belegt) · Registry offen (#303)
TOKEN-AgentProduzent und Budget: bestimmt Modell, Aufwand, Kosten/Nutzen und hält die Inszenierung wirtschaftlichgateway.py Tier-Tabelleläuft, aber rollen-blind — wählt „das billigste Modell, das reicht"; der Rollen-Anspruch aus R-178 fehlt noch
UX-AgentBühnenbildner und Dramaturg: besitzt und vergrößert die Komponenten-Bibliothek, prüft jede Darstellung dagegen — Lücke ⇒ Bibliothek wächst ⇒ alle erbenKomponenten-Landkarte (65 K-IDs) · Konformitäts-Guardläuft AGENT-UX#01
DokumentalistArchivar: Ablage und Verschieben, prüft jede Bewegung. ⛔ Verschieben ist eine Freigabe-Handlung — der Ordner trägt die Reichweite, die Datei erbt sie (K-41). JC E-55: „Der Dokumentalist sortiert danach" — erst einstufen, dann sortierenstore-file-to-drive · (Bewegungs-Skills offen)GESPERRT bis der Gabriel-Schlüsselbauer mandantenfähig ist (#323) — sonst Sisyphos
KVP-AgentNimmt jede Korrektur einmal auf und wertet sie dreifach aus (Antwort-Qualität · System-Verbesserung · digitaler Zwilling), verdichtet mit Korroborations-Gate und wirkt zurück in Triage und Fach-Agentlearning_events (Mig 050) · pattern-promoter · readback.pyKonzept (E-52) — Loop ~70 % gebaut, 0 % geschlossen: Zurücklesen ist DRY
WIZARD-AgentKonfiguriert einen neuen Mandanten im Dialog, bis eine frische TGV-Oberfläche steht — inkl. diktiertem Erst-Interview (Firma, Vorhaben, Entitäten) als Teil des digitalen Zwillings. ⛔ JC: „nicht nur die Initialisierung" — er bekommt viele Aufgabenaudio-transcription · conversational-input · (Konfig-Skills offen)Konzept (E-58); Persona-/Onboarding-Wizard existiert als Vorstufe
SCREEN-BUILDER
-Agent
⭐ Das Ziel hinter allem (E-53): baut Seiten allein nach der Intention des Users. Rollenbild JC: „Der User ist der Gestalter, KAI ist Berater, Web-Designer, Coder."Screen-Factory-Vertrag · K-IDs · SCREEN_COMPOSER (5 Gates)heute Playbook/Skill, nicht Agent — und er erklärt rückwirkend die ganze Kanon-Härte (s. u.)
Telemetrie-/LernSouffleur: macht das Stück besser (User · Mandant · TGV), pseudonymisiertagent_events · Dialog-Telemetrieexistiert
InitiativeProaktiv: Alerts und Vorschläge aus dem Ereignis-Strom—Vision
⭐ HISTORIKERSchaut zurück: „Das gab es schon — damals ging es so aus." Antwortet auf jede Absicht vor dem Plan · schreibt nach dem Lauf zurück · verdichtet (Doppeltes zusammenführen, Veraltetes stilllegen, Narben behalten) · meldet Widersprüche, statt sie zu glätten. ⛔ Sitzt an der Absicht, nicht an der Frage. Hütet Ebene ③ — nie ② mit Fall. §6Konzept-Index · Register · Katalog · screen_factory_contracts.jsonKonzept (E-69)
⭐ VERDRAHTERSchaut vorwärts: „Das wurde beschlossen — hier fehlt es noch." Kein Beschluss bleibt ohne Wirkort. Jede Konzept-Aussage bekommt Eigentümer + next_guard, sonst gilt sie als geschrieben, nicht als beschlossen · meldet, was seit N Tagen beschlossen und unverdrahtet ist · ⛔ baut nicht selbst — er benennt und mahnt. §6iGuards · Register · Roadmap-GatesKonzept (E-69)

Die Kaskade — und warum sie ein Kreis sein muss

Triage → Fach-Agent → Ergebnis → User/Klärung → KVP-Agent → Muster → zurück in Triage und Fach-Agent.Die ersten vier Glieder laufen. Das fünfte ist gebaut, aber DRY. ⇒ Heute ist die Kaskade eine Linie: der User korrigiert, das System schreibt mit, niemand liest zurück. Ein Fach-Agent, der nicht aus den Korrekturen lernt, ist nur ein besserer Rater — Kaskade und Lern-Loop sind EIN Bauwerk, keine zwei Projekte.

Die Regie, Schritt für Schritt (SSOT: KONZEPT_AGENTEN_INSZENIERUNG.md): ① Der User kommuniziert mit KAI — durch Tippen und Handeln. ② KAI dirigiert: was ist wichtig? → holt Daten → wählt die Darstellung → der TOKEN-Agent bestimmt Modell und Aufwand. ②b Nach der Triage übergibt ORCH an den Fach-Agenten der Dokumentart — und der darf einen höheren Modell-Tier beanspruchen. ③ Der UX-Agent wirkt vorab und laufend. ③b Nach jedem Ergebnis und jeder Klärung übernimmt der KVP-Agent und schließt den Kreis. ④ Dokumentalist, Wizard, Telemetrie, Initiative treten ein, wenn ihre Sorge dran ist. ⑤ Alles innerhalb des Scope-Gates — die unverrückbare Bühnengrenze, fail-closed, die kein Agent überschreitet.

Wer wen ruft — die Zuständigkeit gehört in EINE Registry, nicht in den Router-Code (#303). Das Ziel-Format steht fest: doc_type → Fach-Agent → Skills → Pflichtfelder → Modell-Tier. Heute lebt die Zuordnung verteilt (n8n-Router-Map, prompt_config, Python-Fallback) — deshalb konnte ein Routing-Ziel monatelang auf einen Namen zeigen, den es als Python-Skill nie gab (R-179).

Die Routinen — was von selbst läuft, und was nicht

RoutineAuslöserStand
Intake → Triage → KlassifikationMail-Eingang · Upload · Drive · Fotoläuft automatisch (Skill-Router v0.7.4)
Fach-Extraktion (Vertrag)nach der Triage, je Dokumentartläuft — schreibt seit 04.08. wieder
Klärung → User-Entscheidung → learning_eventsKlärungs-Karte im Dialogläuft (Erfassen ✅)
Muster verdichten → zurücklesenKorroborations-GatePromoter da, pattern_rules leer; Zurücklesen DRY
⛔ Wissens-Index (RAG)sollte am Ende der Kette laufenes gibt KEINEN automatischen Ingest — der Index wird von einem handgestarteten Python-Skript gepflegt (#311)
Ablage aufräumenDokumentalistgesperrt bis #323
⛔ Die drei Sätze, die diese Landkarte ehrlich machen — und die JC beim Lesen kennen muss:
① Die Kaskade ist heute eine Linie, kein Kreis — Zurücklesen ist gebaut, aber DRY (#316).
② Historischer Befund vom 04.08.: kein automatischer RAG-Ingest (#311). Stand 17.09. überholt: Ingest und produktive Suche existieren; die vollständige Erschließung ist nicht gesichert. Siehe 7b: belegter Bestand.
③ Der Dokumentalist darf noch nicht laufen — sein eigener Ablage-Kanon verbietet es, solange der Intake bauartbedingt memoir-geprägt ablegt (#323, ABLAGE_KANON §7: „Ein Ordnungs-Agent, der aufräumt, während der Intake weiter falsch anlegt, ist Sisyphos.").
Und der Grund, warum die Kanon-Arbeit dieser Wochen kein Aufräumen war: der Screen-Builder-Agent (E-53).Jede geschlossene Parameter-Lücke, jede Komponenten-Korrektur ist Werkzeug-Härtung für einen Agenten, der ohne uns baut. Ein Screen, der Parameter festhält, die der Komponente gehören, ist für einen Agenten nicht bedienbar — das erklärt rückwirkend JCs Härte bei R-176.
⛔ ZWEI AGENTEN, ZWEI MOMENTE — sie treffen sich nie (JC-Befund 08.08.). JC fasste zusammen: „wir lassen Mistral entscheiden wie die Dokumente zugeordnet werden und der Agent hat auch den lexikalen Weg als Zusatzinformation." Das vermischt zwei Agenten in einem Satz — und es war kein Missverständnis, sondern ein Befund über diese Landkarte: Eingang und Frage standen in verschiedenen Dokumenten, und keines zeigte auf das andere.
① BEIM EINGANG — der ORCH-Agent triagiert. Er sieht den Volltext und setzt doc_type · entity · provider · skill_plan — seit 08.08. auch die Vertraulichkeitsstufe. Modellwahl folgt der Rolle (R-178).
② BEI DER FRAGE — KAI sucht. Er sieht eine Suchanfrage, nie das ganze Dokument. Hierher gehört der lexikalische Weg (Wortsuche) — er entscheidet nichts über Zuordnung, Einstufung oder Ablage.
⇒ Der Fix war die Verzahnung, nicht ein längerer Absatz. Wer die Suchwege sucht: Chatbot First §9e. Wer den Index sucht: Dokumente §3c.

5Element-Tabelle · Die Skills (~45 Hände)

Was das System TUN kann — die wiederverwendbaren Bausteine (R-V4-19: nie neu programmieren). Gruppiert; Quelle: Skills-Registry. → Jeder EINZELNE Skill (Name · Endpoints · Verdrahtung, such-/filterbar): Skills-Register (43, generiert aus _registry.yaml).

GruppeSkills (Auswahl)Reichweite
Intake & OCRpdf-invoice-extract · parse-docling · pdf-ocr-fallback · vision-extract · ocr-to-source · audio-transcription · store-file-to-drivePipeline-Backend
Klassifikationclassify-csv · classify-party-role · resolve-supplier · route-project-document · pattern-engine · tax-extractPipeline / ORCH
Abgleich & Dedupreconcile-payment · detect-duplicate · contract-stub-safety-netBuchungen-Screen + Agent
Verträgecontract-extract (live) · extract-contract-pdf · upsert-contract-from-invoiceVerträge-Screen
Wissen (RAG)rag-ingest · rag-search · memory-search-chat · search_knowledge„Kai fragen" (gated am CORE-CHAT-Flip)
Reisekosten (RKA)create-trip · assign-beleg · calculate · render · versand · bmf-pauschalen · … (~13)RKA-Cockpit (live)
Finanz & Steuerimport-banking-csv · monthly-closing-prep · tax-send-package · vat-currencyBanking · Buchhalter-Versand
Report & Audiocreate-excel-report · create-drive-document · generate-cv · tts · audio-transcriptionteils nur Gabriel/Backend
Lernenrecord-decision · pattern-promoter · initiative-feedLernschleife (gesammelt, nie zurückgelesen — s. Kasten)

~15 von 33 HTTP-Skills sind heute aus einem Screen erreichbar (dominiert vom RKA-Cockpit). Der Rest ist legitimes Pipeline-Backend ODER wartet auf den EINEN CORE-CHAT-Flip, der ~10 Lese-Tools auf einmal sichtbar macht.

Die Lernschleife — ein Tor, drei Wirkungen (PIPELINE#03, 14.09.2026, #1910; Wächter 08_OPS/check_lernschleife_ist_geschlossen.py). Die Schleife hat vier Stufen, und drei davon laufen: ① learning_events wird gefüllt (gemessen 14.09.: 112 Zeilen, 40 Korrekturen — Felder entity 16 · skill_selection 10 · vat_treatment 6 · doc_type 3; Schreiber: tgv-skill-klaerung bis 08.09., KAI-Daumen bis 05.09., classify-party-role, tri02); ② readback.pattern_rules_candidates() (08_OPS/agent_orch01/readback.py) liest sie zurück und baut das Kandidaten-Set — schreibt aber nichts; ③ pattern_rules hat 0 Zeilen; ④ tgv-skill-pattern-promoter kann darum nichts befördern. Welche Stufe liest zurück: nur ②, und nur trocken. Was ihr fehlt: derselbe Riegel wie dem Identifizierer — readback gehört zu agent_orch01 („ändert nichts live", Flip = JC-Wort). Deshalb kein Bau vor Stufe 2: Stufe 2 (ORCH führt, #1910 Rang 3) muss ②→③ mitfreigeben — die Kandidaten von readback nach pattern_rules schreiben (Promoter-Schwellen aus Mig 057, trocken zuerst), und das Gehirn liest v_pattern_rules als Prior neben kb_suppliers. Ein Flip, der nur das Routing öffnet und die Schleife zu lässt, sammelt weiter Korrekturen, die niemand liest. Lern-Box: „Read-Back" = die Korrektur des Menschen beim nächsten gleichartigen Beleg wieder vorlegen; „Promoter" = eine Regel erst nach genug Bestätigungen scharf schalten (Laplace-Vertrauen, Mig 057).

⚠️ FORTSCHREIBUNG KVP#01, 25.09.2026 — live gegen die DB gemessen (Mgmt-API, Uhr 18:1x–18:2xZ), drei Sätze dieses Absatzes sind nicht mehr wahr:
① Das DB-Tor ist seit zehn Tagen offen. documents_routing_engine_check lautet gemessen CHECK (routing_engine = ANY (ARRAY['legacy','v2','orch'])) — Migration 283_riegel_c_routing_engine_orch steht seit 2026-09-15 in tgv_migrations. Der Satz „kennt nur legacy/v2" stand hier und im Wächter und wurde von dort ins Auftragsbrett kopiert. ⛔ „Ein Tor, zwei Symptome" gilt nicht mehr: die DB-Hälfte ist auf, die Modul-Hälfte (08_OPS/agent_orch01/__init__.py:14) ist ein Text-Riegel ohne Schalter — kein Flag, keine Zeile, die JC umlegt, sondern eine Absprache aus dem Juni. Gefahren ist trotzdem niemand: routing_engine='orch' hat 0 Zeilen (650 legacy · 258 v2). Eine mitgeschleppte Sperre lässt eine offene Tür wie eine verschlossene aussehen.
② Der Zuwachs sind Bestätigungen, keine Korrekturen. learning_events = 115 Zeilen (+17 seit der Wächter-Basis 07.09.), davon was_correction=true = 40, unverändert; die 17 neuen sind ausnahmslos field=doc_confirm, source=klaerung, was_correction=false. Die jüngste echte Korrektur ist vom 2026-09-05. ⇒ Nicht „die Schuld wächst um 17 Korrekturen", sondern: der Korrektur-Strom steht seit drei Wochen still — eine zweite, bis heute unbenannte Krankheit, die die erste Formulierung verdeckt hat. Wirkort des Fixes: 08_OPS/check_lernschleife_ist_geschlossen.py (Etikett getrennt, Tor gemessen statt behauptet, Selbsttest (5)/(6) mit Beißprobe).
③ Und die Wurzel liegt eine Stufe tiefer als Station ②: die Tabelle pattern_rules hat im ganzen Schema genau einen Leser — ihren eigenen updated_at-Trigger. v_pattern_rules (351 Zeilen) unioniert gemessen pattern_rules_seed und kb_suppliers und nicht pattern_rules (Reichweite: alle Views/Matviews aller Schemata + alle Funktionen in public). ⛔ Selbst wenn der Riegel fiele und der Promoter schriebe, sähe die Engine nichts. Der Union-Punkt steht als Tower#35-Entscheid ⑤ vom 10.08. oben im Absatz 4d· („nur im Zuge von Dimension B") — er ist damit Voraussetzung der Schleife, nicht ihre Zugabe.
Der KVP-Datenvertrag — was live wirklich trägt (KVP#01, 25.09.2026, gemessen; Vorgabe: KAI_QUALITAET_KVP_MONITORING_V1.md auf codex/kai-qa-testprogramm-20260925). ⛔ Die QA-Dateien unter 07_TESTS/kai_qa_corpus_100/ sind keine Live-Datenquelle. Wer auf ihnen baut, baut ein Schaufenster. Diese Tabelle ist gegen die Live-DB gemessen, nicht aus Migrationen gelesen.
Feldgruppe (Vorgabe)Live-TrägerBefund
Bindung — turn_id, answer_id, conversation_idnur learning_events.raw_payload (jsonb)❌ keine Spalte Mig 226 ist nicht appliziert (keine Zeile in tgv_migrations); chat_messages hat 6 Spalten, turn_id/llm_model/latency_ms fehlen. Schlüssel gezählt, nicht geraten: turn_id/answer_id/conversation_id in 6 von 115 Zeilen, model in 2, Latenz in 0. Bereits so gemessen am 03.08. (screen_factory_contracts.json → chat-historie.next_guard); 53 Tage später unverändert. Laufzeit-Sonde: 08_OPS/chat_engine/thread_store.py:171 has_turn_columns()
Scope — mandant_id, entity_id, project_codechat_sessions.scope_json · agent_events.mandant_id · chat_messages.envelope_json→scope⚠️ ungleich verteilt learning_events trägt keine Scope-Spalte (unverändert seit der 4d-Messung oben). chat_sessions.scope_json trägt mandant_id/entity/project_code/confidentiality_max in 146 von 146 Sitzungen — aber als JSONB, das keine Policy liest. agent_events.mandant_id: 12 280 von 44 654 Zeilen gefüllt (27 %). envelope_json→scope: 571 Antworten, Unterschlüssel mandant_id/entity/project_code/doc_scope/confidentiality_max
Messung — Modell, Latenz, Kosten, Werkzeugstatusskill_call_costs (model/duration_ms/status/mandant_id) · agent_events.tool_*❌ für die Fläche unlesbar skill_call_costs hat genau eine Policy: skill_call_costs_service_all für service_role. ⇒ Kein angemeldeter Nutzer, auch kein super_admin, liest Kosten/Latenz aus dem Browser. Eine KPI-Kachel „Modell/Latenz/Kosten" wäre heute ohne Dienst-Endpunkt leer
KVP — Fehlerklasse, Befund, Retest, Tower-Commit—❌ existiert nicht Reichweite der Suche: alle Schemata außer pg_catalog/information_schema/pg_toast, relkind r/v/m/p, neun Namensmuster (%retest% · %qa% · %befund% · %finding% · %kvp% · %turn% · %feedback% · %quality% · %qualitaet%) ⇒ 0 Treffer. Ein Retest-Register gibt es live nirgends; es liegt als Datei auf dem Codex-Zweig
Datenschutz — Pseudonymisierung für die Produktsicht—❌ kein Feld, keine View Pseudonymisierung existiert heute nur als Satz im Konzept
⛔ Die RLS-Wahrheit, und sie entscheidet über die ganze Fläche (gemessen in pg_policies, 25.09.): learning_events · agent_events · pattern_rules · audit_events tragen je eine einzige Policy für authenticated, und ihr Ausdruck ist is_global_admin(auth.uid()) — eine Ja/Nein-Wand ohne Mandanten-Achse. chat_sessions/chat_messages sind eigentümer-gebunden (user_id = auth.uid() oder global admin). ⇒ Ein mandant_admin (T3) sieht in allen vier Quellen heute NULL Zeilen, und zwar korrekt default-deny; die T3-Sicht der Vorgabe hat keinen Datenpfad, nicht nur zu wenige Daten. Und ein T4-super_admin, der über is_global_admin hineinkommt, sieht alle Mandanten roh — das ist das Gegenteil der geforderten pseudonymisierten Aggregation. Positivkontrolle der Messung: tgv_migrations 232 Zeilen, pg_class meldet relrowsecurity=true für alle zehn geprüften Tabellen, und 0 Basistabellen in public ohne RLS.

⛔⛔ BERICHTIGUNG NOCH AM SELBEN TAG (25.09., KVP#01 nach einem Einwand von CODEX-KAI#03): RLS ALLEIN IST DER FALSCHE MESSORT — es gibt ZWEI Lesepfade, und sie geben verschiedene Antworten. Der Absatz oben misst die RLS und ist darin richtig. Er beantwortet aber nur die Frage „was sieht ein User-JWT direkt an PostgREST?" — und genau über diesen Pfad liest die geplante Fläche voraussichtlich gar nicht. Gemessen am Code: 08_OPS/tgv-skills-service/app.py:6445 sagt im Klartext „Service-role PostgREST call (RLS bypassed — authoritative)"; die Gegenprobe im Schema steht in 05_SCHEMA/246:135 (prf_pnr_service_all … TO service_role USING (true)). ⭐ Auf dem Dienstpfad liegt die Wand in der ANWENDUNGSSCHICHT, nicht in der RLS — ein grüner RLS-Test wäre dort ein falsches Grün.
QuelleRLS-Policy (User-JWT-Pfad)Pfad, über den die Fläche wirklich liestWo die T3-Wand liegt
agent_eventsis_global_admin — T3 sieht nichtsService-Key über POST /api/skill/audit-log (app.py:8128) → _supa_rest (app.py:6445)✅ GEBAUT — nachschlagen statt bauen ep_audit_log ist der fertige Präzedenzfall genau dieser Wand: JWT-Pflicht (403 sonst) · _user_scope(auth.user_id) aus der Mitgliedschaft (app.py:6580, fail-closed, 15 s TTL) · mandant_id=in.(nur Mandanten mit Rolle mandant_admin/super_admin) · Default-Deny 403 ohne Mitgliedschaft · mandant_id IS NULL bleibt super_admin-only
learning_eventsis_global_admin — T3 sieht nichtskeiner — 0 GET-Endpunkte im Dienst (einzige Nennung app.py:4340 ist ein Kommentar); das Frontend schreibt nur über die RPC record_answer_rating❌ auf BEIDEN Pfaden zu kein Endpunkt und keine mandant_id-Spalte ⇒ auch der Anwendungscode-Weg ist heute nicht baubar. ⭐ Das macht Naht ① zum harten Blocker: sie blockiert nicht einen Pfad, sondern beide
⭐ Stand 11.10.2026 (KAI-QA#03, #4029, JC „JA“ in #4023) — für die DAUMEN gibt es jetzt einen Leser: das KAI-Werkzeug daumen-durchsicht (TOWER#71: Fläche = KAI, Chatbot First; bewusst keine HTTP-Route) über 08_OPS/chat_engine/daumen_durchsicht.py, je Modell und je Dialog, Antwort als zwei Tabellen-Blöcke. Die Spalte mandant_id existiert inzwischen, ist auf allen 6 Daumen aber leer ⇒ die Wand hängt am Urheber (super_admin alle, jeder andere nur seine eigenen), nicht am Mandanten. Gegenbeweis live nur GET: super_admin 6/6, qa@/C3/C4 je 0 bei 6 fremden. ⛔ Ein Verwalter sieht die Daumen seiner Leute damit nicht — das wäre JCs Wort (#3550). ⛔ Das Modell fehlt auf 4 von 6 Altdaumen: chat_messages.llm_model ist erst seit kurzem gefüllt (67 von 728 Antworten).
chat_sessions/chat_messageseigentümergebunden user_id = auth.uid()/api/skill/chat-threads, JWT-only + Ownership-CheckEigentümer — bewusst kein Mandanten-Scope. Ein T3 sieht die Gespräche seiner Nutzer nicht, und das ist Absicht, kein Mangel
skill_call_costsnur service_roleService-Key❌ zu bauen RLS kann hier gar nicht wirken — die Wand muss Anwendungscode sein, Muster ep_audit_log
Retest-Register——existiert nicht (s. o.)
⭐ REGELKLASSE: eine Wand-Aussage nennt immer den Pfad, für den sie gilt. „RLS schützt X" ist unvollständig, solange nicht dabeisteht, ob die lesende Fläche über User-JWT oder über den Service-Key kommt. ⛔ Und die Gegenbeweis-Pflicht folgt dem Pfad: liest die Fläche über den Dienst, muss der Gegenbeweis gegen den Endpunkt mit einem echten T3-JWT laufen — ein RLS-Test beweist dort nichts.

⇒ Was der Screen /verwaltung/kai-qualitaet braucht, bevor er gebaut werden darf — vier Nähte, keine neue Plattform:
① Scope-Achse an learning_events (additiv, mandant_id/entity/project_code/geltungsebene, denormalisiert gegen ON DELETE SET NULL) — der Entwurf liegt seit dem 10.08. STAGED unter 01_ITERATIONS/KVP_01_LERN_LOOP/scope_achse.STAGED.sql und ist Voraussetzung, nicht Zugabe. ⛔ Ohne sie ist jede T3-Kachel entweder leer oder mandantenübergreifend.
② Die Wand je Quelle — und zwar auf dem Pfad, über den wirklich gelesen wird (berichtigt 25.09., s. Tabelle oben): liest die Fläche über den Dienst, ist die Wand Anwendungscode nach dem Muster ep_audit_log (app.py:8128-8171) — JWT-Pflicht, _user_scope aus der Mitgliedschaft, mandant_id=in.(eigene), Default-Deny 403. ⛔ Nicht neu erfinden: dieser Endpunkt ist der gebaute Präzedenzfall. Liest sie über User-JWT, braucht es zusätzlich eine zweite Policy aus der Mitgliedschaft (is_mandant_admin(auth.uid(), <mandant_id der Zeile>), Mig 252) statt is_global_admin. Default-Deny bleibt auf beiden Pfaden, und die RLS bleibt die Grundsicherung, auch wo der Dienst sie umgeht. ⛔ Gegenbeweis-Pflicht, dem Pfad folgend: der Fix gilt erst, wenn gemessen ist, dass ein eingeschränkter Nutzer die fremden Zeilen nicht sieht — gegen den Endpunkt, nicht gegen die RLS, wenn der Dienst liest. Heute nicht durchführbar, weil die QA-Sitzung von der Shell nicht angenommen wird (QA-AUTH-01, CODEX-KAI#01 Rang 1).
③ Jede Hilfstabelle erbt die Schutzpflicht der Daten, die sie spiegelt: jedes CREATE TABLE einer künftigen Befund-/Retest-Ablage braucht ENABLE ROW LEVEL SECURITY im selben PROPOSED-Skript — sonst spiegelt eine ungeschützte Tabelle geschützte Daten.
④ Jede gekappte Zahl nennt ihre Decke, nie die Anzahl des Verborgenen. „12 von 35 gemessen" ist erlaubt; „und 4 weitere siehst du nicht" wäre ein Orakel über geschütztes Material. Eine leere Kachel ist grau mit Reichweite, nie grün.
⛔ Nicht gemessen und deshalb ohne Urteil: die Wirkung dieser Policies auf eine echte T3-Sitzung (Zugang fehlt, s. ②) · der Dienst-Endpunkt-Vertrag für skill_call_costs (nur die DB-Seite ist gemessen) · ob ein n8n-Weg an der RLS vorbei liest.

Der Screen-Vertrag vw-kai-qualitaet — und warum er heute NICHT in screen_factory_contracts.json steht. Der Guard 08_OPS/check_screen_factory_contracts.py:129 verlangt für jeden Vertrag eine existierende file, und :148 einen visible_url_local, der auf eine vorhandene Datei unter 06_DASHBOARD/ zeigt. ⇒ Ein Vertrag ohne Screen lässt den Guard rot werden. Die Vorgabe sagt ausdrücklich „zuerst messen, nicht bauen" — beides zusammen heißt: der Vertrag lebt hier, bis der Screen gebaut wird, und wandert dann als Ganzes in die JSON. Kein zweiter Ort, keine zweite Liste.
FeldWert
id · route · screen_typevw-kai-qualitaet · /verwaltung/kai-qualitaet · admin (im Kanon der neun Typen vorhanden — kein neuer Typ)
T3 · MandantenansichtSieht nur den Scope der Mitgliedschaft des Aufrufers (user_mandant_roles, Mig 252 is_mandant_admin), nie Default, nie Hardcode. Inhalt: eigene Feedbacks · abstrahierte Fragenfamilien · Messreichweite · eigene offene Retests. ⛔ Heute ohne Datenpfad (s. RLS-Wahrheit oben) — der Screen wäre leer, nicht falsch, und muss das grau mit Reichweite sagen
T4 · ProduktansichtPseudonymisiert und aggregiert über die berechtigten Mandanten — nie Rohgespräch als Analyse-Abkürzung. ⛔ Heute liefert is_global_admin das Gegenteil: alles roh. Die Pseudonymisierung ist zu bauen, nicht vorhanden
Datenquellen (nur diese)Turn-/Antwort-Metadaten im autorisierten Scope · learning_events (Feedback) · agent_events (Technik) · Retest-Register. ⛔ Nicht 07_TESTS/kai_qa_corpus_100/ — Dateien im Repo sind kein Live-Screen
PillenGrau = nicht gemessen · Rot = Befund offen · Orange = begrenzt/offen eingeordnet · Grün = benannte Fragenfamilie unter benannter Version und Reichweite bestanden. Farbe allein trägt nie ein Urteil — Text, Reichweite und Zeitpunkt stehen daneben
Abnahme (die vier, die beißen)① Gegenbeweis: ein eingeschränkter Nutzer sieht die fremden Zeilen nachweislich nicht — sonst gilt der Scope nicht als gefixt · ② leere Datenlage ist grau mit Reichweite, nie grün · ③ jede KPI führt auf dieselbe Grundmenge · ④ ein Guard wird absichtlich verletzt und muss rot werden, bevor die Fläche als geschützt gilt
not_actionsKeine Prompt-, Modell-, Rollen- oder Regeländerung · keine globale Testausführung aus einer T3-Sitzung · keine stille Ausführung (Vorschlag · Freigabe · Vollzug bleiben getrennt)
⛔ Einordnung: Teil des bestehenden KVP (§4d oben), keine zweite Parallelplattform und keine zweite Liste neben der lebenden Roadmap. Vorgabe: KAI_QUALITAET_KVP_MONITORING_V1.md · KAI_QUALITAETSKREISLAUF_V1.md · KAI_FEEDBACK_TELEMETRIE_KVP_INTEGRATION_V1.md, alle drei auf codex/kai-qa-testprogramm-20260925 und keine auf master.
Der rote Faden: Eine KI-First-Anwendung entsteht, indem man NICHT Screens mit Logik füllt, sondern Fähigkeiten (Skills) + ein Gehirn (Agent) + dünne Oberflächen über EINEN Katalog verbindet. Die Seite ruft den Agenten oder direkt einen Skill; der Agent rendert zurück in die Seite. Beides — Seitenbau und KI-First — sind gebunden an denselben Kanon-Katalog + dieselbe Engine, gesichert vom selben Harness. So bleibt das System kohärent und verbessert sich selbst (Lernschleife).

6GEDÄCHTNIS-FIRST — die drei Achsen und die eine Adresse E-67/E-68 · JC 06./07.08.

Der Abschnitt beantwortet JCs schärfste Frage: „Das Erinnerungsvermögen scheint mir das größte Problem, das wir in drei Monaten hatten." — und er ist kein Anhang, sondern die Klammer über allem darüber.

6a · Die Diagnose — sechs Gedächtnisse, kein Index

Was heute geschrieben wird, landet an sechs verschiedenen Orten: Anforderungs-Register (>350 Zeilen) · JC-Entscheide (E-1…E-68) · Kompendium (39 Seiten) · Roadmap-Board · Commit- und PR-Texte · und das private Gedächtnis des Agenten.

⛔ Der Konstruktionsfehler, offen benannt: Der Agent führt Notizen in ~/.claude/projects/…/memory/ — der Mensch kann sie weder finden noch lesen. Für ein Produkt, dessen Versprechen „dein Gedächtnis" lautet, ist ein Agenten-Gedächtnis ohne Lesezugang kein Merkmal, sondern eine Haftung. Es ist dasselbe Silo, gegen das TGV antritt — nur ein Stockwerk tiefer.

Und die Folgekosten sind gemessen, nicht befürchtet: geht eine Notiz verloren (nicht gemergt · falscher Branch · Token-Grenze · falsche Fassung), zieht der Agent den ganzen Fall neu auf — oder er erfindet, was schon existiert. Beides kostet Lebenszeit, und genau die soll TGV zurückgeben.

6b · Die drei Achsen — JCs eigener Dreiklang

JC hat die Lösung selbst formuliert: „festzuhalten in wiederfindbarer, lesbarer Form, was wir als ABSICHT definiert haben, mit welchem VERTRAG es verankert ist, und mit welchem FERTIGUNGSGRAD wir es als Werkzeug anwenden können."

AchseBeantwortet die FrageExistiert heute alsFehlt
ABSICHTWas wollten wir erreichen — und für wen?JC-Entscheide (E-…)⛔ kein Objekt: keine Nummer, kein Zustand, kein Ergebnis, keine Spur
VERTRAGWas ist zugesagt — und woran misst man den Bruch?Katalog (K-IDs) · Regelwerk (R-…) · Skills-Registry⛔ nur für Oberflächen-Bausteine; Skills und Agenten haben keine Zusagen-Form
FERTIGUNGSGRADWie weit ist es — und kann ich es benutzen?Gates A–F auf dem Roadmap-Board⚠️ nicht je Gegenstand, nur je Screen/Lane
⭐ Alle drei Achsen existieren bereits. Was fehlt, ist ihre Verbindung am selben Gegenstand und EINE Adresse, die der Mensch aufrufen kann. Eine Sache, eine Karte: Absicht, Vertrag, Fertigungsgrad — nebeneinander, nicht in drei Dateien verteilt.

Und daraus folgt die Antwort auf „jeder Mandant will sein Master-Konzept wiederfinden": Das Master-Konzept ist kein Dokument, sondern eine Sicht, erzeugt aus den drei Achsen. Nur so bleibt es pflegbar und je Mandant eigenständig.

6c · Was Gedächtnis-First strukturell erzwingt (nicht durch Disziplin)

Der Kanon dieser Woche lautet: Regeln werden müde, Prüfer nicht. Also sind es Bedingungen, keine Vorsätze.

RegelWarum
Kein privates Agenten-GedächtnisWas der Agent lernt, wird dort geschrieben, wo der Mensch es öffnen kann. Ein Gedächtnis, in das der Eigentümer nicht sehen kann, gehört ihm nicht.
Eine Sache, eine AdresseJede Absicht, jeder Vertrag, jeder Baustein hat eine aufrufbare Stelle — nicht Zeile 217 von 350.
Der Dreiklang ist PflichtEin Gegenstand ohne Absicht, Vertrag oder Fertigungsgrad ist unvollständig — und ein Prüfer sagt das, statt dass es jemandem auffällt.
Rückfluss ist Teil der ArbeitJeder Lauf meldet, was gefehlt hat. Die Lücke ist der Kandidat für den nächsten Baustein — ohne sie wächst die Werkstatt nicht, sie füllt sich nur.
Schreiben am Wirkort, nicht im BerichtEin Beschluss, der nur im Gespräch lebt, zählt nicht. Diese Regel gibt es seit Juli — 6c macht sie prüfbar statt appellativ.

6d · INTENT-FIRST — die Kette (E-67)

Der Satz: In TGV formuliert der Mensch Absichten. Alles andere ist ableitbar — und was abgeleitet wurde, bleibt als Fähigkeit erhalten. Die Regel dazu: Eine Absicht ist ein Beleg — Nummer, Zustand, Ergebnis, Spur.

Absicht → Präzisierung → Plan → Verträge → Ergebnis → Rückfluss. Das Fundament sagt seit langem „LLM liefert Intent, NIE Markup" — bisher galt das nur für die Darstellung. 6d verallgemeinert es auf die ganze Kette.

SchrittRegel
Präzisierung⛔ Nur fragen, was den Bau VERZWEIGT. Ein Wizard, der zwanzig Dinge fragt, von denen achtzehn Standard sind, ist ein Formular mit Gesprächsanstrich. — Der Baustein dafür existiert (klHost/Klär-Karten), zeigt aber auf Dokumente statt auf Absichten.
VerträgeJe Zusage: gibt es das schon? Meistens ja. Was fehlt, wird gebaut und aufgehängt.
Ergebnis⭐ Gegen die ABSICHT prüfen, nicht gegen den Plan. Ein Test am Anfang bestätigt die Absicht, ein Test am Ende die Wirkung.

6e · Was ein VERTRAG ist — und was er nicht ist

Drei Teile: ① Absicht — was erreicht es für einen Menschen, in dessen Worten · ② Zusagen — was ist danach immer wahr, inklusive Verhalten im Fehlerfall · ③ Anschluss — rein, raus, und was es anfassen darf (Scope).

⛔ Ein Vertrag ist keine Dokumentation. Dokumentation beschreibt — ein Vertrag bindet. Ein Vertrag kann gebrochen werden, und der Bruch ist messbar. Doku veraltet still; ein Vertrag scheitert laut.

Beleg vom 05.08.: drei Dateien waren sich einig, der Privat-Bucket heiße tgv-jean-chris — geprüft wurde die Spiegelung, nicht die Wirklichkeit. Ein Vertrag hätte gelautet: der zurückgegebene Bucket existiert und trägt die Daten dieses Mandanten — und das wäre prüfbar gewesen.

Warum Agenten Verträge brauchen: Code sagt WIE, nie WOFÜR. Ein Agent setzt zusammen — ohne Vertrag müsste er das Programm bei jedem Aufruf im Kopf simulieren. ⭐ Und er muss sagen können „das gibt es schon": ohne Verträge ist das eine Textsuche, mit Verträgen ein Nachschlagen über Absichten — NUXIN wird maschinenlesbar.

Das Bild: eine Werkstatt. Werkzeuge hängen an der Wand, am Werkzeug hängt ein Schild. Der Agent ist der Geselle, der Schilder lesen kann. Ohne Schilder baut er, was schon an der Wand hängt.

6f · Die Positionierung — drei Gedächtnisse, das dritte ist der Burggraben

„KI erledigt deine Arbeit" verspricht jeder — das ist kein Alleinstellungsmerkmal, das ist der Markt. TGVs Versprechen lautet anders: jede gelöste Aufgabe macht die nächste billiger.

GedächtnisWas es behältVerbreitung
FaktenDokumente, Wissen, Belegejeder baut das
Entscheidungenwarum etwas so istselten
⭐ Fähigkeitenwas wir dafür gebaut haben — als Vertrag, nicht als Codefast niemand
Deshalb sind Verträge keine Ingenieurshygiene, sondern die Positionierung: ohne sie ist das dritte Gedächtnis nicht speicherbar — man kann Fähigkeiten nicht aufbewahren, wenn man sie nicht beschreiben kann.

Der Nachweis liegt vor: Annas Website (Typ B) entstand in einer Woche, weil dreizehn Dinge vorher woanders gelernt worden waren — aber sie hängen bis heute ohne Schild an der Wand, weshalb sie noch niemand ein zweites Mal benutzt hat.

E-68 · das Angebot: „Plattform anbieten und das notwendige Training dazu, damit Menschen sich ihre Zeit zurückgewinnen — entsprechend deren eigenen Absichten." ⭐ Eine Plattform, die nur unsere Fälle kann, ist eine Software. Eine, die fremde Absichten aufnimmt, ist eine Werkstatt. Messgröße ist zurückgewonnene Lebenszeit — nicht Funktionen, nicht Screens.

6g · Die ACHT Ebenen — welches Gedächtnis, wem es gehört, wo es liegt

EbeneWas darin lebtGehörtLiegt in
① Nutzerwas dieser Mensch will, wie er arbeitet, seine Absichtendem NutzerDB · Scope = Nutzer
② MandantFakten und Entscheidungen: Dokumente, Verträge, Konventionen, sein Master-Konzeptdem MandantenDB · Scope = Mandant
③ Produkt (TGV)Fähigkeiten: Bausteine, Skills, Verträge, Regeln, NarbenTGV (JC)Repo, versioniert
④ Werkzeugdas Arbeitsgedächtnis des Agenten—lokal · ⭐ Zielzustand: INDEX auf ①–③, kein Speicher
⑤ Episodischwas in diesem Austausch geschahGespräch⭐ muss verdichtet werden — oder es ist zu Recht weg
⑥ Weltfremdes Wissen: Gesetze, Pauschalen, Anbieterpreiseniemandemkb_* · die Wahrheit liegt außerhalb
⑦ Betriebwas Läufe wirklich taten — Ereignisse, Kosten, FehlschlägeTGVagent_events · Beweismaterial, kein Wissen — muss beschnitten werden
⛔ ⑧ Live-Serverwas der Mensch tatsächlich sieht—Hetzner · eine Kopie, die alt sein kann
⛔ Ebene ⑧ wurde am 07.08. nachgetragen — durch einen Fehler im Text über auffindbares Gedächtnis. Tower gab JC einen Live-Link auf einen Abschnitt, der nur auf master lag: 404.
„Es steht auf master" heißt nicht „du kannst es sehen." Zwischen beiden liegt der Deploy. Der Live-Server ist ein eigenes Gedächtnis, weil er alt sein kann, ohne dass es jemandem auffällt — und weil er für den Menschen die EINZIGE Quelle ist.

Die Trennlinie ② / ③ bleibt hart: „Hiscox gehört zu C4" ist ②. „Eine Korrektur des Menschen schlägt jede Ableitung" ist ③. ⭐ Genau diese Trennung macht TGV verkaufbar — ③ reist zum nächsten Kunden mit, ② niemals. Und sie macht Löschung möglich: wer ② löscht, verliert keine Fähigkeit.

6h · Fünf Brillen, ohne die kein Gedächtnis planbar ist

BrilleFrageWarum sie fehlt = Sumpf
VerfallWas darf altern, was muss altern, was darf nie altern?Ein Preis muss altern, eine Narbe nie. Ohne Verfallsregel liest es irgendwann niemand mehr
VorrangWer gewinnt bei Widerspruch?Mensch vor Ableitung · Messung vor Behauptung · jung vor alt — außer bei Narben
VergessenWas passiert bei Löschverlangen?Nur weil ③ vom Fall entkoppelt ist, ist Löschen in ② ohne Wissensverlust möglich
VertraulichkeitErbt die Lehre die Stufe ihrer Quelle?⛔ Sonst ist eine Lehre aus einem streng_vertraulich-Dokument ein Leck mit Umweg
HerkunftWer, wann, aus welcher Messung?Ohne sie ist „Vorrang" nicht anwendbar — man kann nicht entscheiden, wer recht hat, wenn man nicht weiß, woher es kommt

6i · Die VIER Zustände — und warum drei nicht reichen

ZustandBedeutetPrüfer
geschriebendie Aussage steht im Kompendium—
verdrahtetsie wirkt an einem WirkortEigentümer benannt
geprüftein Guard hält sienext_guard
⭐ sichtbarder Mensch kann sie aufrufendeployt + Link
⛔ Die ersten drei Zustände leben alle im Repo. Keiner davon heißt, dass JC es sehen kann.
⭐ Bei Screens gibt es dieses Tor längst — Gate E verlangt „live + Voll-Shell-Bild-Beweis". Für Konzepte gibt es kein Tor. Genau deshalb konnte ein Text über auffindbares Gedächtnis unauffindbar bleiben.

Regel: Eine Konzept-Aussage ohne next_guard ist nicht „fertig", sondern „geschrieben" — und eine, die nicht deployt ist, existiert für den Menschen nicht.

6j · Der Lauf und die Schnittstellen

Absicht → Präzisierung → Plan → Verträge → Ergebnis → Rückfluss. ⛔ Ohne Schritt 2 kann eine Absicht den Zustand „geplant" nicht erreichen.

Historiker spricht mitWannWas er gibtWas er bekommt
Orchestrator⛔ vor jedem Plan, verpflichtendFundstellen — oder „nichts, und das war der Suchraum"die Absicht
Fach-Agentenbeim Bauenden Vertrag des Bausteins⭐ die Lücke — die einzige Schnittstelle, die das Gedächtnis wachsen lässt
KVP-Agentnach dem LaufHäufungen: „diese Klasse fünfmal"Ereignisse aus ⑦
Dokumentalistnie⛔ nichts — Ebene ② bleibt drüben⛔ nichts
KAInur bei Präzedenz-FragenFundstelle + Herkunftdie Frage
Menschbei Widerspruchden Widerspruch, nicht die Glättungdie Entscheidung — sie schlägt jede Ableitung
⭐ Die Linie, die alles klärt: Der Historiker sitzt an der ABSICHT, nicht an der FRAGE.
„Was steht in meiner Police?" → Daten, kein Historiker. „Wie ist das Wetter?" → Allgemeinwissen, kein Historiker. „Haben wir so etwas schon gemacht?" oder eine Absicht → Historiker.
Er ist nicht im Weg jeder Frage — er ist im Weg jedes Vorhabens. Deshalb kostet er fast nichts: Fragen sind viele, Absichten sind wenige.

Richtungen: ③→③ ist sein Kerngeschäft (verdichten, Widersprüche, Veraltetes) · ③↔④ füttert und erntet den Arbeitsindex · ②→③ nur entkoppelt vom Fall · ⑦ ist Rohstoff, nicht Inhalt.

6k · Die Absichts-Klärung — eine Kartenart, erweitert 📝 geschrieben · nicht gebaut · kein Eigentümer

Gemessen 07.08. (02_SKILLS/tgv-skill-klaerung/skill.py:302-320 · 06_DASHBOARD/core_shell.html:1005 · komponenten_data.js Eintrag klaerung-card, status:"live"): ⭐ Die Klär-Karte ist gar nicht dokumentgebunden. Nur fünf Felder sind es (document_id · doc_label · doc_meta · drive_file_id · amount) — alles andere ist allgemein: question · check_md · recommendation · sources[] · quick_replies[] · accept/correct_label · resolved_msg · case_type. Und zwei Stellen sind bereits als Weiche gebaut: _confirm.target ist ein Feld, kein fester Wert — und case_type hat in der Shell schon eine eigene Spalte.

⭐ Das Prinzip, das alles ordnet: WER ANGEFANGEN HAT, BESTIMMT DEN ORT.
Das System fragt (ein Beleg kam mehrdeutig an) → die Karte gehört in die Liste. Sie ist Post, die auf dich wartet.
Du hast angefangen („ich will Kurse verkaufen“) → die Karte gehört ins Gespräch. Sie ist die Antwort auf deine eigene Frage.
⛔ Landeten Absichts-Karten in derselben Warteliste, fühlte sich das an wie Hausaufgaben für etwas, das der Nutzer gerade selbst gewollt hat. Dieselbe Karte, zwei Orte — der Standard-Ort ergibt sich aus dem Auslöser, nicht aus dem Kartentyp. Technisch trägt das schon: registerCard("klaerung_card") rendert überall, auch im Gespräch (selbstverankerter klHost-Dock).

Und der KAI-Dialog entscheidet bereits, WANN gefragt wird — die Drei-Fall-Regel steht wörtlich in 08_OPS/chat_engine/grounding.py: ① bestätigte Aktion → ausführen, keine neue Frage erfinden · ② zumutbar klar, Detail offen → mit GENANNTER Annahme handeln · ③ echte Mehrdeutigkeit → kurz nachfragen. ⭐ Das ist der Wizard, und er ist schon da — er beantwortet die Frage, die einen Wizard schlecht macht: wann darf man fragen? ⛔ Was fehlt: Fall ② und ③ hinterlassen nichts. Die Annahme steht in einem Satz und verschwindet; die Rückfrage steht im Verlauf und verschwindet.

Was ergänzt werden mussWarum — aus der Messung, nicht aus dem Gefühl
① answer_kindHeute kennt die Karte nur bestätigen / korrigieren. Eine Absicht braucht auch wählen (aus N) und freitext. quick_replies[] gibt es schon — es fehlt die Aussage, ob die Auswahl verbindlich ist oder ein Vorschlag.
② Eine Karte je offener Frage⛔ Nicht eine Karte mit drei Fragen, sondern drei Karten mit gemeinsamer Absichts-Nummer. So bleibt jede Karte atomar, der Lebenszyklus einfach, und die Liste zeigt Fortschritt statt eines Formulars.
③ _confirm.target: "intent"Die Antwort wird in die Absicht geschrieben, nicht in ein Dokument. Das Feld existiert bereits.
⭐ Und Fall ② bekommt endlich einen Ort: Heute sagt KAI „ich nehme an, du meinst X“ — und niemand kann später widersprechen, weil es nirgends steht. Künftig wird die Annahme ein Feld an der Absicht: sichtbar, korrigierbar, mit Herkunft. Ohne Karte, ohne Unterbrechung — der Nutzer wird nicht gefragt, aber er kann nachsehen.
Fall ① erzeugt Arbeit. Fall ② erzeugt eine Annahme. Fall ③ erzeugt eine Karte.

UX — was vorzudenken ist: Gruppierung zweistufig, aber degradierend (nicht jede Karte hat eine Absicht über sich; keine erfundene Gruppe „Sonstige“) · parallel als Standard, sequenziell nur bei erklärter Abhängigkeit — ein Wizard, der zwingt, ist der Wizard, den niemand mag; eine entfallende Karte muss sichtbar verschwinden · Fortschritt an der Absicht („2 von 3 geklärt“) · jede Karte einzeln beantwortbar, jederzeit abbrechbar · Steckbrief der Absicht nach dem K-26-Muster (was will ich · was ist angenommen · was ist offen · welche Verträge gedeckt · Fertigungsgrad) · Sortierung nach BLOCKADE, nicht nach Alter · Endzustand als Übergang (offen → geplant), nicht als Leere · ⛔ kein Massen-Beantworten (fünf Absichts-Fragen auf einmal bestätigen heißt, keine gelesen zu haben) · ⛔ kein eigener Screen — die Klärungs-Seite bekommt eine Gruppierung, keinen Zwilling.

⚠️ Zwei Messungen fehlen und gehören VOR den Bau (#354): ob klRenderList case_type wirklich als Spalte durchreicht, und ob der Karten-Dock mehrere Karten hintereinander trägt oder immer nur eine.

⛔ Zustand ehrlich: GESCHRIEBEN. Nicht gebaut, nicht verdrahtet, kein Eigentümer, nichts abzunehmen. Es hängt an der Absicht als Objekt (#349) — eine Karte, die auf eine Absicht zeigt, kann nicht vor der Absicht existieren.

6l · Was auf dieselbe Lücke wartet

Rolle / VorhabenWarum es blockiert ist
KVP-Agent (4d)⛔ hat keinen Rohstoff — er sieht Ereignisse, aber nie Wünsche
Klärungs-Dialog⛔ KORREKTUR 07.08. (JC): Die frühere Formulierung „auf das falsche Objekt gerichtet" war falsch. Die Klärung ist universal und richtig gebaut — 02_SKILLS/tgv-skill-klaerung/skill.py: list_pending · confirm_doc · confirm_txn · revert_doc, mit Dry-Run, Golden-Read-Back und Undo-by-default.
⭐ „Absicht" ist der Oberbegriff, kein Konkurrent: „dieses Dokument richtig einordnen" ist eine Absicht — heute nur eine implizite, vom System abgeleitet. Eine Klär-Karte ist bereits die Präzisierungs-Stufe einer Absicht, sie hat nur keine Absicht über sich, an der sie hängt.
⛔ Die echte Lücke ist die Richtung: Klärung geht heute nur vom System aus („mir ist etwas unklar, entscheide du"). Es fehlt die Gegenrichtung vom Menschen („ich will X, hilf mir, es genau zu machen"). ⇒ Kein Umbau — ein zweiter Eingang zu einer Maschine, die schon läuft.
⚠️ Offen und ungemessen: die heutigen Karten kennen bestätigen · korrigieren · zurücknehmen. Eine Absicht braucht die Frageform „was ist hier noch unklar?" — ob dieselbe Kartenart beides trägt, ist eine Messung, keine Meinung.
Promotions-Gate (Modul-Katalog)⛔ hat keinen Eigentümer — in der Governance-Trias fehlt die Rolle, die Fähigkeiten kuratiert. Wir haben einen Dokumentalisten für Belege und niemanden für Werkzeuge.
Output-as-Input · Telemetrie-Fundus · Anti-Amnesiealle drei brauchen die Absicht als Anker — man kann nicht lernen, was funktioniert hat, wenn man nicht weiß, was gewollt war
Screen-Builder-Agent (E-53)kann nur aus Verträgen zusammensetzen, nicht aus einem Ordner mit Dateien
Reihenfolge (bewusst): Nicht vor HEIMHOLUNG#01 bauen. Abschnitt 6 ist die Klammer über Heimholung, Werkzeugkasten und Screen-Builder — er wird billiger, wenn diese drei stehen. Aber er ist jetzt entschieden, weil er deren Reihenfolge bestimmt. Wirkort: Register #349 · Entscheide E-67/E-68.

6m · Entitäts-Wissen — was TGV über eine Firma, ein Projekt, einen Menschen weiß (Ebene ②) 📝 geschrieben · Vorlage bei JC · #2157

Anlass JC 19.09.: „C3 ist die deutsche CONVIS Consult & Marketing GmbH, C4 die französische. convis GmbH ist ein Kunde von C3!! Das müsstest du schon längst parat haben." Er hat recht: der Satz stand seit Iter 44 in einer Migration (05_SCHEMA/088_iter44_a3_entity_signatures_aliases.sql:55 „KEIN c3-Alias auf convis gmbh“). Er stand nur nicht an dem Ort, den ORCH, KAI und Tower lesen. Das ist die Lücke aus 6a, an einer Firma gemessen: ein Wissen ohne Adresse ist ein Wissen, das man jedes Mal neu verliert.

Kanon (EINE Quelle: mandanten + entity_signatures)Rechtsname · Land · USt-ID · Rolle
C3 · c3-convisCONVIS Consult & Marketing GmbH · DE · DE812421871 · HRB 102141 B · eigene Entität. Beleg: 77 Eingangsbelege mit diesem Empfängerblock und entity_signatures.
C4 · c4-convisCONVIS Consult & Marketing SARL · FR · FR34442540068 · eigene Entität. ⚠️ mandanten.name sagt „Convis SARL (C4)“, also nicht den Rechtsnamen. Mig 233 hat nur C3 korrigiert.
convis GmbHKUNDE von C3 (debtor_customers, 8 Ausgangsrechnungen, Ansprechpartner Herr Stephan Ludwig, gleiche Anschrift Auerbachstr. 10). ⛔ Nicht C3. Und: JCs Mail-Signatur bei j.binetti@convis.com nennt sie. Deshalb trägt jede Weiterleitung von dort den Namen (246 von 887 Belegen kamen so herein).
⚠️ offen (JC)DE813141231 und DE812909449 stehen als C3-USt-IDs in 08_OPS/ablage_kanon.yaml:19. Die erste steht in keinem Belegtext (#7200), die zweite nur auf einer Google-Rechnung (#7802). Nicht geraten, sondern gefragt.
⛔ Gemessen 19.09. (nur lesend): wo die falsche Gleichung „C3 = Convis GmbH“ WIRKT, nicht nur steht
① entities.name für C3 lautet „C3 Convis GmbH“ (live-Tabelle). ② Der Cron ⑦ (betriebs-crons.yml:292) ruft 08_OPS/fesp2_d_entity_retriage.py auf. Dort wird aus :224 „Empfänger enthält GmbH“ → C3 und aus :255 „Aussteller convis + gmbh“ → C3. Er schreibt nie selbst, legt JC aber falsche Ein-Klick-Vorschläge mit Zitat vor. ③ 24 Belege haben als provider „convis GmbH“: gelesen aus der Signatur des Weiterleiters, nicht aus dem Beleg. ④ #8473 (Rechnung an „convis GmbH“) und #8155/#8156 (Vorgänge der convis GmbH) liegen im C3-Bestand. ⑤ kb_suppliers geht als LIEFERANTEN-HINWEIS in den ORCH-Prompt (08_OPS/agent_orch01/plan_service.py:123). Drei Zeilen sind richtig: „convis GmbH → C3, Einnahmen“ (#341, #371, #1090), also der Kunde. Zwei sind fraglich: #889 mit dem Muster „convis“ trifft jede Convis, auch C4 und C3 selbst; #1153 „Convis GmbH intern → Betrieb“ macht convis GmbH zur Kostenstelle. ⭐ Die Zeilen allein sind kein Fehler. Gefährlich werden sie, sobald der provider aus der Signatur stammt (③): dann liest ORCH „Einnahme von C3“ an einer Adobe-Rechnung. ⑥ Zwei Tests schreiben den Fehler fest, dazu rund 40 Konzept- und Mockup-Texte.
⭐ Die Klasse dahinter ist nicht „falscher Name“, sondern „Kontext als Inhalt gelesen“: die Signatur dessen, der weiterleitet, ist keine Aussage des Belegs. Vgl. feedback_einstufung_aus_dem_dokument_nicht_aus_regeln.
Bestand: wo Wissen über eine Entität heute liegtZustand (6i) · Wand
„Second Brain je Mandant/Entität/Projekt/User“geschrieben: 00_LEITDOKUMENT/KI_FIRST_KLASSIFIKATION_WERKBANK_KONZEPT.md:154 und JE-081 „Entitäts-Steckbrief lernt aus Chat“ (offen seit 27.06.). Kein Schema, kein Code.
contacts · contact_roles (Mig 251)verdrahtet (Skill kontakt-finden, KAI) · Mandant + Stufe. Rolle kunde gibt es schon. ⭐ Das ist der natürliche Ort für „convis GmbH ist Kunde von C3“.
kb_suppliersverdrahtet in ORCH als einziger Entitäts-Hinweis ({{supplier_prior}}) · nur nach entity-Text gescoped, nicht nach mandant_id
persona_profiles (Mig 202)verdrahtet in KAI (app.py:3534), aber 0 Zeilen · mandant_id ist Text statt uuid (05_SCHEMA/PROPOSED_persona_profiles_fuenf_achsen.sql)
entity_signatures (+ aliases)verdrahtet, deterministisch (party_role, Signatur) · nach Entitäts-Slug geschlüsselt
agent_knowledge · knowledge_graph_*nur MCP bzw. Gabriel-Stub · ⛔ ohne Mandanten-Wand. Für Entitäts-Wissen nicht verwenden.
nachbarschaft.py („was taten wir mit ähnlichen Belegen“)gebaut, bewusst nicht verdrahtet: 75 von 778 hätte die Nachbarschaft falsch gelenkt (02.09.). ⭐ Die Lehre für 6m: Statistik über Nachbarn ist kein Wissen über die Entität.
⭐ Vorschlag — kein neuer Speicher, sondern EIN Ort und EIN Weg zu ORCH
1 · Der Ort: Wissen über eine Gegenpartei (Kunde, Lieferant, Bank, Ansprechpartner, Konditionen, Gepflogenheiten) liegt in contacts/contact_roles + notes. Es ist damit je Mandant und trägt die Stufe (6h: die Lehre erbt die Stufe ihrer Quelle). Wissen über die eigene Entität (Rechtsname, USt-ID, Marken) liegt in mandanten/entity_signatures. Kein drittes Regal.
2 · Das Lernen: JC sagt es einmal, per Text oder Diktat (KI_FIRST:156). KAI schreibt es als Vorschlag mit Herkunft (wer, wann, aus welchem Satz), und der Mensch bestätigt. Vorrang (6h): Mensch vor Ableitung.
3 · Die Nutzung als HINWEIS, nie als Regel: ORCH bekommt neben {{supplier_prior}} einen Block {{entitaets_hinweise}}. Er enthält nur Fakten aus Mandanten, die der Aufrufer sehen darf (user_mandant_roles), und nur bis zu seiner Stufe. Der Prompt sagt: „Der Beleg entscheidet; der Hinweis erklärt, was du siehst.“ Beispiel: „convis GmbH ist Kunde von C3. Ein Beleg AN convis GmbH ist nicht C3-eigen. Die Signatur ‚convis GmbH‘ unter einer Weiterleitung ist JCs Absender, kein Lieferant.“
4 · Die Wand: Default-Deny. Ein Hinweis aus C3 erreicht nie einen C4- oder Anna-Lauf. Gegenbeweis-Pflicht wie §Sicherheit: ein Viewer auf C4 bekommt den C3-Hinweis nicht.
5 · Der Guard: check_firmennamen_kanon.py sperrt die Gleichung „C3 = Convis GmbH“ in Repo-Texten, Prompts und Tests. Der Kanon kommt aus der DB, nicht aus einer zweiten Liste.

⛔ Zustand ehrlich: GESCHRIEBEN. DDL nur PROPOSED (kb_suppliers.mandant_id, persona_profiles.mandant_id → uuid). Datenkorrekturen (entities.name, mandanten.name C4, 24 provider, #889/#1153 in kb_suppliers) liegen als SQL-Vorschlag bei JC. Wirkort: Register #2157 · Memory reference_entitaeten_firmennamen_kanon.

6m· — Entscheidungsvorlage für JC: vier Fragen, die nur du beantworten kannst ✅ entschieden 19.09. · JE-179

Lage: Kanon, Bestand und Fehlerorte sind gemessen (oben). Guard, Cron-Korrektur und Test-Umstellung baut die Bahn ENTITAETEN#01 ohne dich (Tower-OK 19.09.). Offen sind nur Dinge, die in keinem Beleg eindeutig stehen. Jede Frage hat eine Empfehlung. Ein „OK“ nimmt alle vier Empfehlungen an, abweichende Punkte nennst du mit Nummer.

FrageVariante A (Empfehlung)Variante BWas du danach siehst
E1 · Die zwei unbelegten C3-USt-IDs DE813141231 (#7200) und DE812909449 (#7802, Google)Streichen aus der Zuordnungsliste. C3 wird nur noch an DE812421871 erkannt. Die Google-Nummer prüfst du einmal in deinem Google-Rechnungsprofil.Beide behalten, weil du sie kennst. Dann nenne bitte, wem sie gehören.A: Ein Beleg mit einer dieser Nummern landet in der Klärung statt still in C3.
E2 · Stellt convis GmbH C3 jemals Rechnungen (C3 = Kreditor)?Nein: convis GmbH ist nur Kunde von C3 (contact_roles.rolle = kunde). #341/#371/#1090 (Kunde → C3-Einnahmen) bleiben. #889 (Muster „convis“, zu breit) und #1153 („intern → Betrieb“) werden deaktiviert.Ja, auch Lieferant: dann zwei Rollen, und die Richtung entscheidet je Beleg der Inhalt.A: ORCH-Hinweis „Kunde von C3, Belege AN convis GmbH sind nicht C3-eigen“.
E3 · #8473 Herzapfelhof, 161,72 €, Rechnung an „convis GmbH“, liegt in C3Nicht C3-eigen: Status „fremd/abgelehnt“, kein Paket an den Buchhalter.C3 hat bezahlt und rechnet weiter: bleibt in C3, mit Vermerk „Weiterberechnung“.A: fällt aus dem C3-September-Paket heraus.
E4 · Namen in der DB: entities.name C3 und mandanten.name C4Rechtsnamen: „CONVIS Consult & Marketing GmbH“ / „CONVIS Consult & Marketing SARL“, dazu das Kurz-Label C4 = „Convis (C4)“, analog zu Mig 233. SQL liegt bereit: 05_SCHEMA/PROPOSED_entitaeten01_firmennamen_kanon.sql.Nur C4-Rechtsname, Label bleibt leer (der Umschalter zeigt dann den langen Namen).A: Umschalter zeigt „Convis (C3)“ und „Convis (C4)“, Belege und Pakete den Rechtsnamen.
Vorschau, wie ein Beleg nach A aussieht:
• #8380 „#c3 adobe“: heute Lieferant „convis GmbH“ → nach A Lieferant aus dem Anhang (Adobe), Absender-Signatur ignoriert, Mandant bleibt C3.
• #8473 Herzapfelhof: heute C3 · offen → nach A „nicht C3-eigen“, mit Zitat „convis GmbH, Auerbachstraße 10“ als Grund.
• Cron-Vorschlag: heute „Empfänger enthält GmbH → C3“ → nach A nur „Empfänger = CONVIS Consult & Marketing GmbH (entity_signatures)“ → C3. Jede andere GmbH bekommt keinen Vorschlag mehr.

OK-Frage: „OK zu E1–E4 wie empfohlen?“ Ein Wort genügt. Danach spielt die Bahn das SQL vor, und du führst es im Supabase-SQL-Editor aus.
✅ JCs Antwort 19.09. (JE-179) — zwei Empfehlungen waren FALSCH, und das gehört hierher, nicht in eine Fußnote:
E1 — „Diese Information sollte durch Ablesen von Rechnungen dir ersichtlich sein.“ Richtig: TGV entscheidet aus den Belegen. Gelesen (Volltext, rag_chunks, Felder, auch mit Leerzeichen): DE812909449 steht wörtlich auf der Google-Rechnung #7802 als USt-IdNr. von „Convis Consult & Marketing GmbH“ → bleibt als C3-Nummer, aber ⚠️ sie ist nicht die amtliche (DE812421871): das Google-Rechnungsprofil ist vermutlich falsch gepflegt. DE813141231 steht in keinem Belegtext, nur im extrahierten Feld von #7200 → unbelegt, fliegt aus ablage_kanon.yaml.
E2 — ⛔ Empfehlung war falsch. convis GmbH wird auch Lieferant von C3 („du hast noch keine, aber es kommt“). Beide Richtungen, zwei Rollen. Nur #889 (Muster „convis“ trifft jede Convis) fällt. #1153 bleibt.
E3 — ⛔ Empfehlung war falsch. #8473 ist ein C3-Lieferantenbeleg, vom Lieferanten falsch an „convis GmbH“ adressiert; die Rechnungsänderung ist angefragt. ⭐ Für ORCH/KAI: eine Fehladressierung durch den Lieferanten ist ein Klärpunkt (Korrektur anfordern), keine Zuordnung zur Kundenfirma. Genau so verhält sich der Cron seit #2163: fremde Firma im Empfänger → kein Vorschlag, Mensch entscheidet.
E4 — wie empfohlen, präzisiert: der Rechtsname trägt offiziell kein „C3“/„C4“ davor. name = Rechtsname, short_label = „Convis (C3)“/„Convis (C4)“.
Steckbrief-Grunddaten (von JC geliefert): gemessen stehen sie seit 15.05. (Mig 079) vollständig in entity_signatures — HRB, USt-ID, Steuernummer, D-U-N-S, EORI, Gründung, Stammkapital, beide Geschäftsführer, BIC, IBAN (gesetzt, hier nicht zitiert); C4: RCS, SIRET, NAF, IDCC, TVA, D-U-N-S, Organisme de formation. 0 Abweichungen, nichts zu schreiben. Was fehlt, ist nur die Struktur: D-U-N-S, EORI, Kapital und Gründung stehen in notes als Freitext.

6n · Second Brain / digitaler Zwilling: wie ein Dokument, ein Foto oder ein Satz an KAI ins richtige Gedächtnis kommt 📝 Vorlage bei JC · #4014

Anlass, JC am 11.10. wörtlich: „Bitte mir erklären was bedeutet Gabriel als triage? können wir dadurch das thema Errinerung ( second Brain) damit verbinden? Ein doc oder einen Info in der Kai chat gibt informationen die das second brai der Entität oder der Person zuspeist? Ich brauche einen Erklärung wie ist unsere Konzept second brain / Digitales zwilling unter Nutzung NUXING von alle arbeiten in Gabriel ( was als Memory APP angedacht ist).“
Den Horizont beschreibt 00_LEITDOKUMENT/KONZEPT_DIGITALER_ZWILLING_LEBENSGEDAECHTNIS.md (26.07.: vier Schichten, Vertrauens-Pakt, Gabriel als rückwirkender Zwilling und TGV als vorausschauender). Dieser Abschnitt ergänzt den Fluss dazu: Eingang → Erkennen → Gedächtnisraum → Abruf. Er ist am Bestand gemessen, live und nur lesend am 11.10.

① „Gabriel als Triage-Entität“, in einfachen Worten
Triage ist der erste Schritt nach jedem Eingang: ORCH entscheidet, wem ein Dokument gehört. Daraus folgen Mandant, Ablage-Eimer und wer es sehen darf. Heute kennt die Triage vier Ziele: C3, C4, kivisai und privat (08_OPS/agent_orch01/taxonomy.py:23, Mail-Prompt 08_OPS/tgv-skills-service/mail_intake.py:879). Was keines dieser Ziele trifft, wird unassigned und geht in die Klärung.
Gabriel gibt es schon als Entität mit eigenem Mandanten (live: entities.slug = gabriel, Eimer tgv-mb-lm-gabriel in 08_OPS/ablage_kanon.yaml:46). Nur die Triage kennt ihn nicht. Deshalb kamen alle 58 Gabriel-Dokumente, davon 34 Fotos, über gabriel.html herein und keines per Mail oder Inbox.
„Gabriel als Triage-Entität“ (TRIAGE#02, #4004, OK-Frage ②) heißt: Gabriel wird das fünfte Ziel. Ein Foto oder Dokument mit Gabriel-Bezug, das per Mail kommt, landet dann direkt in Gabriels Mandanten und Eimer, hinter Gabriels Wand (Projektrolle und Gabriel-Stufe).
⛔ Eine Erinnerung entsteht dabei noch nicht. Eine Fiche mit Personen, Orten und Ereignissen entsteht heute nur, wenn jemand in gabriel.html „Fiche vorschlagen“ drückt (proposeFicheFromDoc :3272, runKernSchleife :5580 → Skill source-to-fiche). In der Eingangskette schreibt keine Stelle in memoir_*. Gesucht wurde in dispatch.py, mail_intake.py und 08_OPS/agent_orch01/*.py.
⛔ Für JCs eigene Fotos ist es nicht der richtige Weg. Gabriel ist ein eigener Mandant, in dem Familie und Redaktion als Rollen mitlesen. FOTO#02 hält fest: der „Gabriel-Weg“ ist die Mechanik und nicht Gabriels Eimer (#3967). JCs Foto bleibt in JCs Raum (JE-211, JE-193).

⭐ Gabriel ist also zweierlei. Erstens ein Mandant: Gabriels Lebenswerk. Zweitens eine Mechanik, die Memory-App: Quelle → Fiche → Personen, Orte, Ereignisse → Rückfragen → Synopsis. Das Second Brain braucht diese Mechanik in jedem Gedächtnisraum. Alle Erinnerungen in Gabriels Mandanten zu legen wäre der falsche Weg.
② EingangWas heute damit geschieht (gemessen 11.10.)Wand beim AbrufWas fehlt
Dokument (Upload, Inbox)documents plus rag_chunks (2090 Textstücke, jedes mit mandant_id und Stufe). KAI findet sie über search_knowledge_scoped.✅ Mandant ∩ Entität ∩ Decke ∩ Projekt (05_SCHEMA/263_rag02_projekt_wand_wissenssuche.sql)Das Dokument bleibt Text. Niemand fragt: „Was sagt es über eine Person oder die Entität?“
FotoDrei Ausgänge nach JE-212. Den Ausgang „Erinnerung“ baut FOTO#02 (#3967, PR offen): Zustand erinnerung, der Eimer bleibt der der Entität.✅ wie DokumentKeine Geschichte und keine Personen am Foto. photo-select läuft nur in Gabriel.
KAI-Gesprächchat_sessions und chat_messages (1458 Nachrichten), ein Thread je Scope (Mig 203). KAI sieht die letzten 12 Züge (08_OPS/chat_engine/agent_loop.py:31).✅ eigener NutzerNichts wird verdichtet (Ebene ⑤ in 6g). Für „merk dir …“ gibt es keinen Schreiber: remember_rule schreibt nur Mail-Routing-Regeln (TGV -App files/tgv_mcp_server.py:667).
MailIMAP-Abruf (mail_intake.py:1770) → Triage → weiter wie ein Dokument.✅ wie DokumentGabriel ist kein Ziel (TRIAGE#02 ②).
Gabriel-Eingabe (Text, Audio, Scan)source-to-fiche → 62 Fiches · 141 Personen · 90 Orte · 128 Ereignisse, dazu 98 Textstücke im Gabriel-Mandanten.✅ Projektrolle und Gabriel-Stufe (Mig 113/115). ⛔ Schreibwand fehlt noch: Mig 301 (#4003)Das ist das einzige strukturierte Erinnerungs-Gedächtnis, und es lebt nur in Projekt 5 (gabriel.html:2377).
Fakt über Person oder Entitätpersona_profiles (Mig 202): der Leser in KAI ist verdrahtet, aber die Tabelle hat 0 Zeilen. Der Umbau auf fünf Achsen liegt als PROPOSED vor (#1262, JC-GO 02.09.; live ist mandant_id noch text). Gegenparteien stehen in contacts und contact_roles (6m).⚠️ Persona hat heute nur eine Eigentümer-RegelEs gibt keinen Schreiber, der aus Dokument oder Gespräch einen Fakt macht (JE-081).
Fluss des Second Brain Vier Eingänge laufen durch Triage und Gedächtnis-Erkenner. Der Mensch bestätigt, dann landet der Inhalt in einem scopegebundenen Gedächtnisraum mit zwei Regalen. KAI ruft nur hinter der Wand ab. EINGANGERKENNENGEDÄCHTNISRAUM (scopegebunden)ABRUF Dokument Foto (drei Ausgänge) Mail Satz an KAI ① Triage: welcher Raum? gebaut · Gabriel fehlt als Ziel (TRIAGE#02 ②) ② Gedächtnis-Erkenner Erinnerung? · Fakt? · nichts? neu, als Baustein aus source-to-fiche + bild_art Mensch bestätigt Vorschlag mit Herkunft (6m ②) je Raum: JC+C3 · JC+Privat · JC+Projekt · Familie+Raum Regal Erinnerungen Fiche · Personen · Orte · Ereignisse Rückfragen · Foto nach Jahr/Monat gebaut in Gabriel (memoir_*) Regal Steckbrief (Fakten) über Person, eigene Entität, Gegenpartei persona_profiles · contacts (6m) Tabellen da · 0 Schreiber KAI User-Sicht ∩ Scope ∩ Session Stufe erbt die Quelle (6h) Wand gebaut gebaut teilweise gebaut neu (Baustein) ⛔ Kein Pfeil führt von einem Raum in einen anderen: ein globaler Mischspeicher ist ausgeschlossen.
③ VarianteWiederverwendet (NUXIN)Neu, als BausteinDatenschutzfolgen
⭐ A · Gabriel-Mechanik als Baustein in jedem Raum (Empfehlung)Die memoir_*-Tabellen sind schon projektgebunden (get_project_ids_for_user und can_user_see_confidentiality, Mig 113/115). Ein neuer Gedächtnisraum ist deshalb ein neues Typ-B-Projekt wie 00-26-001-life-memory-gabriel, ohne neue Tabelle. Weiter genutzt werden source-to-fiche, photo-select, memory-search-chat, rag-ingest-project, gabriel.html als Memory-App, die Gabriel-Lesewerkzeuge für KAI (08_OPS/chat_engine/executors_gabriel.py:117), der Foto-Ausgang „Erinnerung“ (FOTO#02) und für Fakten persona_profiles/contacts wie in 6m.(1) Gedächtnis-Erkenner nach der Triage: er schlägt vor und schreibt nie selbst. Muster sind source-to-fiche und bild_art. (2) „merk dir“ an KAI erzeugt eine Vorschlagskarte (Fiche oder Fakt) im aktiven Raum. (3) Die Memory-App mit Projekt als Parameter statt fest Projekt 5. (4) Gabriel als Triage-Ziel (TRIAGE#02 ②).Die Wand aus Mandant, Projektrolle und Stufe steht schon. ⛔ Vorbedingung ist Mig 301 (#4003: auf 15 memoir_*-Tabellen war Lesen auch Schreiben). Ohne sie schreibt jeder Viewer in jedes neue Gedächtnis. Die Erkenntnis erbt die Stufe ihrer Quelle (6h). Gabriel behält seine eigene Skala, neue Räume nehmen die Haus-Stufen.
B · Nur Steckbrief und Foto-Regalpersona_profiles mit store.py und compose_persona, dazu contacts und FOTO#02. Fotos liegen als Zustand erinnerung, sortiert nach Jahr und Monat.Das PROPOSED 05_SCHEMA/PROPOSED_persona_profiles_fuenf_achsen.sql wird angewandt (DDL ist JCs Hand). „merk dir“ schreibt dann einen Fakt.Die Wand ist genau das PROPOSED. Bis dahin liest Persona ins Leere (fail-open). ⚠️ Grenze: „Wer ist auf dem Foto mit Tante Gina?“ (Zwilling, Schicht 2) bleibt unbeantwortbar, weil am Erlebnis keine Personen, Orte und Ereignisse hängen.
⛔ C · Alles in GabrielAlles von Gabriel, nichts Neues: die Triage schickt jeden Erinnerungs-Kandidaten in Gabriels Mandanten.nichts⛔ Verstößt gegen JE-193 („kein globaler Mischspeicher“) und gegen die Mandantenwand: Gabriels Familien- und Redaktionsrollen sähen Inhalte aus JCs C3 oder Privat. Steht hier nur zur Abgrenzung.
④ Empfehlung: A, mit dem Steckbrief aus B darin. Ein Raum hat zwei Regale: Erinnerungen über die Gabriel-Mechanik, Fakten über persona_profiles und contacts (6m). Reihenfolge, gebaut wird erst auf JCs Wort:
① Mig 301 anwenden (Schreibwand, liegt beim Tower). ② TRIAGE#02 ②: Gabriel als Triage-Ziel. ③ FOTO#02 mergen. ④ Memory-App mit Projekt-Parameter und ein erster Raum „JC + Privat · Erinnerungen“. ⑤ Gedächtnis-Erkenner und die „merk dir“-Karte. ⑥ Persona auf fünf Achsen.
Was JC danach sieht: ein Foto aus dem Urlaub landet nicht mehr in der Belegliste. Es liegt in „JC + Privat · Erinnerungen“ unter Jahr/Monat, mit einem Fiche-Vorschlag („Wer ist darauf? Wo war das?“), den JC bestätigt. Auf „Wer war bei diesem Urlaub dabei?“ antwortet KAI aus diesem Raum. Aus C3 oder aus Gabriel antwortet er dabei nie, außer JC ist gerade in diesem Raum.

OK-Frage: „OK zu Variante A in dieser Reihenfolge?“ Ein Wort genügt. Abweichende Punkte nennst du mit Nummer.
Nebenbefunde (gemessen 11.10., nur lesend), an den Tower gemeldet und hier nicht behoben
• Zwei Schreibweisen für Gabriel: die 73 Gabriel-Quell-Textstücke tragen in rag_chunks.entity den Wert gabriel-binetti, ihre 73 Dokumente aber gabriel. Die Entitätswand der Live-Suche liest d.entity und hält. Der Filter p_entity vergleicht dagegen c.entity: ein auf Gabriel verengter Abruf fände also 0 Stücke. ⚠️ Das ist ein Verdacht, gelesen am Funktionstext und an den Zahlen. An einer Ausführung bewiesen ist er nicht.
• Alle Gabriel-Stufen haben in rag_conf_rank den höchsten Rang (Mig 241). KAI mit der Standard-Decke intern sieht deshalb keine Gabriel-Erinnerung. Für Gabriel ist das gewollt, neue Räume sollen es nicht übernehmen.
• Der Name remember_rule verspricht Gedächtnis, das Werkzeug schreibt aber Mail-Routing.
• KONZEPT_DIGITALER_ZWILLING_LEBENSGEDAECHTNIS.md war bisher nur von der Foto-Vorlage aus verlinkt. Ab jetzt ist es auch von hier erreichbar.

7 · RAG und fachliche Arbeit — verbindlicher Bauplan

Beschlossen durch JC am 17.09.2026. Umsetzung mit Claude Code ab Freitag, 18.09.2026. Status: Zielarchitektur freigegeben, Umsetzung und Live-Abnahme offen. Dieser Abschnitt ist die maßgebliche Ergänzung zu den historischen Betriebsständen weiter oben; er behauptet keinen bereits erfolgten Rollout.

Ziel: Einmal aufgenommen, vollständig erschlossen, für berechtigte Nutzer durch KAI befragbar. Dieselbe vollständige Extraktion versorgt ORCH und die fachlichen Skills. Ein Fehler der fachlichen Einordnung blockiert die Wissenssuche nicht. Fehlende oder unklare Rechte blockieren die Sichtbarkeit sehr wohl.

Begriffe: RAG bedeutet, dass KAI passende, berechtigte Quellstellen für eine Antwort abruft. Ein Chunk ist ein nachvollziehbarer Textabschnitt. Eine Indexgeneration ist ein zusammengehöriger, geprüfter Satz von Chunks einer Originalversion. Facharbeit erzeugt zusätzlich strukturierte Ergebnisse und gegebenenfalls autorisierte Aktionen.

7a · Ein Eingang, gemeinsame Grundlage, zwei Aufgaben

  1. Aufnehmen: Original im bestehenden privaten Bucket sichern; Dokument-ID, Originalversion/Fingerprint und zulässigen Datenraum bestimmen. Inhalt ist untrusted data und darf keine Werkzeugaufrufe oder Berechtigungen vorgeben.
  2. Vollständig erschließen: vorhandene Parser/OCR nach Format verwenden; Seiten, Tabellen, Anlagen und Beziehungen erhalten. Vorschautext darf eine frühe Triage unterstützen, ist aber kein Vollständigkeitsnachweis. Unbekannte Formate, verschlüsselte oder beschädigte Dateien werden mit Grund und automatischem Wiederaufnahmeweg ausgewiesen.
  3. Prüfen: erwartete Bestandteile gegen verarbeitete Bestandteile zählen und Qualitätsfehler festhalten. Eine leere Seite kann korrekt sein; eine nicht gelesene Seite darf nicht als leer gelten. Vollständig verarbeitet bedeutet keine Garantie fehlerfreier OCR.
  4. Wissen bereitstellen: Chunks und Mistral-Embeddings in der vorhandenen Datenbank erzeugen, prüfen und als vollständige Generation aktivieren. KAI erhält ausschließlich aktuell berechtigte Quellen.
  5. Fachlich arbeiten: ORCH nutzt dieselbe Extraktionsversion, entscheidet über vorhandene Fachskills und verfolgt deren Ergebnisse. Wissensindexierung und Facharbeit dürfen nach der gemeinsamen Extraktion unabhängig fortschreiten und wiederholt werden.

Reihenfolge — erst vollständig erschließen, dann einstufen (JC-Grundsatz 19.09.2026): „Die Wahrheit zur Einstufung liegt im Dokument selbst, nicht in der Mail, mit der es versendet wurde. Deswegen wollen wir zuerst chunken, damit ORCH die Grundlage hat zu entscheiden.“ Daraus folgt verbindlich:

RAG beantwortet Quellenfragen, Vergleiche und Zusammenfassungen. Für eine vollständige Dokumentprüfung muss KAI alle relevanten Abschnitte systematisch abarbeiten; Top-k-Suche allein beweist keine Vollständigkeit. Beträge summieren, Buchungen erzeugen, Fristen verwalten oder Reisekosten bearbeiten erfolgt über bestehende strukturierte Werkzeuge und deren Freigaben. Fachlich extrahierte Angaben bleiben mit Originalversion und Fundstelle verbunden; ungeprüfte Angaben werden nicht zu bestätigten Tatsachen. Widersprüche zwischen Quelle und Fachdatensatz bleiben sichtbar.

Unabhängige Zustände: Original gespeichert · Extraktion vollständig/teilweise/fehlgeschlagen · Wissensindex bereit/in Arbeit/fehlgeschlagen · Facharbeit offen/in Arbeit/prüfbedürftig/abgeschlossen. Diese Bedeutungen an bestehende Zustandsfelder anbinden; keine parallele Statusmaschine erfinden. Ein einziges „done“ darf nicht alle vier Aussagen ersetzen.

7b · Wiederverwendung und belegte Lücken

Prüfreichweite: lokaler Quellcode und Live-Schema am 16./17.09.2026; konkrete Original-/Chunk-Prüfung an #8279. Schema, SQL-Datei oder Kommentar sind kein Nachweis wirksamer Live-Rechte. Vor Baubeginn aktuellen master, offene PRs, Migrationsledger und Dienstfassung erneut prüfen.

Vorhandener WirkortWiederverwenden / gezielt ergänzen
08_OPS/credentials/_storage.py; documentsKanonischer Originalzugriff; ID, Bucket, Fingerprints, Versionsfelder. Keine zweite Originalablage. Dateizeiger nicht selbst rekonstruieren.
02_SKILLS/tgv-skill-parse-docling/skill.py; bestehende PDF/OCR-Wege und RegistryVollständige gemeinsame Extraktion anschließen; tatsächliche Formatunterstützung und Eingabeverträge messen. Keine Providerumstellung; EU-/Datenschutzvorgaben beibehalten.
02_SKILLS/tgv-skill-rag-ingest/skill.py; rag_chunksVorhandene Chunks/Embedding-Spalten nutzen. Kurzer DB-Text, „Chunks existieren“ und übersprungene Embeddings dürfen nicht mehr als Vollständigkeit gelten. Löschen-vor-Ersetzen durch geprüfte Aktivierung ersetzen.
08_OPS/rag_wand.py; 08_OPS/chat_engine/scope_gate.pyMandant/Vertraulichkeit und serverseitigen Benutzerscope wiederverwenden; unbekannte Zuordnung bleibt gesperrt. Alle Schreib- und Lesepfade inventarisieren.
08_OPS/chat_engine/executors_rag.py; RPCs search_knowledge_scoped, search_knowledge_lexicalProduktive Suche weiterverwenden; Rechte, aktive Generation und Quellenbezug in beiden Wegen gleich durchsetzen. 08_OPS/rag01/rag_hybrid_search.py ist ein Auswertungswerkzeug, kein produktiver Ersatz.
08_OPS/agent_orch01/agent_loop.py, verifier.py; 02_SKILLS/tgv-skill-contract-extract/skill.pyORCH und Fachskills erhalten gemeinsamen vollständigen Text samt Version und Abdeckung. Vorschau nicht „Volltext“ nennen. Fachauftrag und tatsächliche Ausführung nachweisen.
08_OPS/tgv-skills-service/app.py; agent_events; vorhandene Wiederholungs-/JobwegeOriginalabruf, Benutzerrechte, Audit und Wiederaufnahme weiterverwenden. Keine neue Queue/Agentenebene ohne nachgewiesene Lücke.

Referenzfall #8279, CIT TRAVAUX: 35 Seiten und etwa 67.533 extrahierte Zeichen im Original; bisher zwei RAG-Chunks aus rund 5.282 Zeichen DB-Text. Erfasster Dokumenttyp „Vertrag“, Originaltitel jedoch „ASSIGNATION AU FOND DEVANT LE TRIBUNAL“. Das ist ein Test für vollständige Erschließung und eine zu überprüfende Klassifikation, kein Anlass, blind einen Vertrag anzulegen. Der Parser meldete fehlende Eingabe; vorhandene Chunks wurden später idempotent übersprungen. Keine personenbezogenen Dokumentinhalte in öffentliche Testfixtures übernehmen.

7c · Daten- und Sicherheitsvertrag vor Implementierung

7d · Ausführungsplan für Claude Code ab 18.09.2026

Die Pakete sind Arbeitsschritte, keine neu gegründeten Lanes. Federführung: umsetzende Claude-Code-Lane; TOWER koordiniert Abhängigkeiten, Review, Merge und Deploy. Freitagsbeginn ist kein Versprechen, alle Pakete am selben Tag produktiv abzuschließen.

Paket / ReihenfolgeKonkrete LieferungTor zum nächsten Schritt
P0 · Bestand und VertragCLAUDE.md, Memory, diesen Abschnitt, Register, Komponenten und Registry lesen. Master/offene PRs/Livedienst vergleichen. Alle Ingest-/Such-/Originalpfade und bereits laufende Reparaturen erfassen. Bestehende Tabellen/Versionen/Jobs gegen 7c abgleichen; minimale Datenänderung, Rechteprüfung und Rollback hier dokumentieren.Datei-/Schema-Fundstellen und noch reproduzierbarer Fehler. Keine Doppelimplementierung. DDL nach geltendem TGV-Freigabeweg; eine Architekturfreigabe ist kein Nachweis bereits angewandter Migrationen.
P1 · Vollständige ExtraktionKanonischen Originalzugriff mit vollständigem Parser verbinden, gemeinsame Extraktion samt Abdeckung persistieren. Vorschau und Volltext unterscheiden. PDF, Scan, Tabellen, Mail/Anlagen und nicht unterstützte Formate mit expliziten Ergebnissen behandeln.Synthetische Testquelle mit eindeutigen Fundstellen am Anfang, in der Mitte und am Ende; fehlende Seite und Parserfehler werden erkannt. Fachskill liest dieselbe Version.
P2 · Index sicher erneuernGeneration/Idempotenz/atomare Aktivierung in bestehenden Ingest einbauen; fehlende Embeddings sind Fehler. Benötigte Migration separat mit Preview, Verify und Rollback vorbereiten.Wiederholung, Teilfehler, Prozessabbruch und zwei gleichzeitige Versionen getestet. Letzter vollständiger Stand bleibt korrekt; neue Version wird nie teilweise aktiv.
P3 · Rechte und KAIBeide Suchwege, Quellenbezug und Originalabruf mit aktuellem Scope verdrahten. Direkte DB-Zugänge und Cache prüfen. KAI kann gezielte Suche von vollständiger Dokumentarbeit unterscheiden und nennt Teil-/Altstände.Positive und negative Rechtefälle aus 7e bestanden; Widerrufsverhalten belegt. Keine Abnahme nur mit service_role oder Owner.
P4 · ORCH und FacharbeitTriage darf früh beginnen; Facharbeit nutzt geprüfte gemeinsame Extraktion. RAG läuft auch bei unbekanntem Dokumenttyp oder Fachfehler. Vorhandene Fachskills liefern verknüpfte, versionierte Ergebnisse; neue Dokumentarten erst nach Registry-/Taxonomieprüfung.Fachskill-Ausfall blockiert Wissensindex nicht; erneute Fachausführung erzeugt keine Dubletten oder unautorisierten Aktionen. #8279 wird nicht allein wegen alter Triage zum Vertrag.
P5 · Referenzfall, Bestand, BetriebZuerst #8279 kontrolliert nachverarbeiten und über KAI abnehmen; danach Dry-Run-Inventar unvollständiger Bestandsdokumente, Kostenabschätzung und begrenzte wiederaufnehmbare Stapel. Zustände für Nutzer verständlich anzeigen.PRs grün, deployed SHA/Dienstfassung nachgewiesen, Live-Abnahme und Rollback geprüft. Bestandsbericht nennt vollständig/teilweise/gesperrt/fehlgeschlagen mit Nenner und Prüfreichweite.

7e · Abnahmematrix und dauerhafte Wächter

Vorhandene Prüfungen zuerst erweitern: 07_TESTS/agent_chat01/test_rag_executor.py, test_envelope_scope_caller.py, test_scope_verengung_kommt_an.py, test_s2s_scope_278.py, test_beleg_link_contract.py, 08_OPS/check_projekt_wand_wissenssuche.py und vorhandene Vertrags-/Parserprüfungen. Vor Aufruf aktuelle CLI/Fixtures lesen. Neue Tests sichern reale Fehlerklassen; jede negative Kontrolle muss durch eine gezielte Verletzung rot werden können. Testdaten synthetisch oder zugriffsgeschützt.

Claude-Code-Startauftrag: Diesen Abschnitt 7 vollständig umsetzen, beginnend mit P0. Bestehende Arbeit vor Änderungen erneut prüfen und übernehmen. Keine zweite RAG-Plattform, keine zusätzliche Agentenebene, keine neue Taxonomie aus Vermutung. Prüfberichte mit Quellenstand, Benutzerrolle, erwarteter und tatsächlicher Wirkung führen. Pro Paket den Ist-Stand hier aktualisieren; erst nach gemessener Live-Abnahme als produktiv markieren. Produktionsdaten-Nachlauf und DDL nach den geltenden TGV-Verfahren ausführen. Offene Geschäftsentscheidungen konkret vorlegen, technische Routine selbst lösen.

Ist-Stand je Paket

P0 — erledigt am 18.09.2026 (TOWER#57, nur gelesen; Registerzeile #2098). Geprüft gegen origin/master d7a070ca0 und lesend gegen die Datenbank (Spalten von rag_chunks und documents, Ereignisse). Nicht geprüft: RPC-Definitionen, RLS-Policies und Migrationsledger live, die Dienstfassung auf Hetzner.

P1 — ausgeliefert, Live-Abnahme offen (Registerzeile #2099). Gebaut am 18.09.2026 von der Bahn RAG#01, gemergt über die Deploy-Naht 2 (#2794) am 19.09.2026 um 09:39; der Dienst meldet Fassung 1.12.167. Gemessen am 19.09. (nur gelesen): seit dem Deploy kein einziger Lauf von tgv-skill-rag-ingest oder tgv-parse-docling in agent_events. Ausgeliefert heißt deshalb noch nicht abgenommen; produktiv erst nach dem ersten gemessenen Lauf an einem echten Beleg.

OCR — JC-Entscheid 18.09.2026, 23:50: Mistral OCR ist Standard, je Mandant umschaltbar. Umgesetzt in P1, nicht live.

Vergleich an 8 echten Belegen (19.09.2026, nur gelesen, 08_OPS/rag01/r2_proof_docling_vs_mistral.py). Das Skript lief seit seinem Bau am 07.08. nie — und wäre an allen acht gescheitert: keiner trägt mehr eine Drive-ID. Jetzt über den Bucket-Zeiger. Preis Mistral OCR 0,001 USD je Seite (kb_model_prices), Docling ist ein eigener Dienst ohne Stückpreis.

BelegArtTextschicht (P1-Leser)DoclingMistral OCRKosten Mistral
#8064Zahlungsbeleg · jpgkeine (Bild)nicht gemessen ¹1 Seite · 382 Zeichen0,0009 €
#8023Quittung · jpegkeine (Bild)nicht gemessen ¹1 Seite · 1.380 Zeichen0,0009 €
#8021Quittung · jpgkeine (Bild)nicht gemessen ¹1 Seite · 798 Zeichen0,0009 €
#7919Rechnung · jpgkeine (Bild)nicht gemessen ¹1 Seite · 2.015 Zeichen0,0009 €
#8007Sonstiges · pngkeine (Bild)nicht gemessen ¹1 Seite · 6 Zeichen0,0009 €
#8150Rechnung · pdfvollständig · 2/2 Seiten · 1.517 ZeichenTextschicht · 1.516 Zeichen2 Seiten · 1.478 Zeichen0,0018 €
#8145Rechnung · pdfvollständig · 3/3 Seiten · 4.523 ZeichenTextschicht · 4.523 Zeichen3 Seiten · 5.582 Zeichen0,0028 €
#8079Rechnung · pdfvollständig · 2/2 Seiten · 1.396 ZeichenTextschicht · 1.395 Zeichen2 Seiten · 1.637 Zeichen0,0018 €

Summe Mistral OCR: 12 Seiten, 0,0109 €. Lesart: bei PDFs mit Textschicht liefern alle drei Wege praktisch denselben Text — OCR ist dort überflüssig und wird deshalb nicht gerufen. Bilder liest nur Mistral; die Qualität der Zeichen ist hier gezählt, nicht inhaltlich geprüft. Ein gescanntes PDF ist unter den acht nicht; die Seitenauswahl (nur Scan-Seiten) ist an einer synthetischen Probe live belegt (1 von 2 Seiten gelesen und bezahlt). ¹ Docling antwortete bei allen fünf Bildern HTTP 401: auf diesem Rechner fehlen die Docling-Zugangsdaten in der .env. Das ist keine 0, sondern nicht gemessen.

Genauigkeit und Laufzeit, gemessen 11.10.2026 (SOUVERAEN#04, #4050, 08_OPS/souveraen04_extrakt_vergleich.py --ocr). Der Vergleich oben zählt Zeichen. Gemessen ist jetzt, ob die Zeichen stimmen: 12 echte Rechnungs-PDFs mit Textschicht wurden gerastert (Textschicht weg, wie ein Scan), über die Produktions-Naht volltext.mistral_ocr_seiten gelesen und gegen ihre eigene Textschicht gemessen — 17 Seiten. Wörter wiedergefunden: Median 99,4 % (schlechtester Beleg 88,1 %) · Beträge: 66 von 68 · 2,0 s je Seite (Median, höchstens 7,1 s, 18 Belege inkl. 6 echter Scans/Fotos). Beide verfehlten Beträge und der schlechteste Wert liegen an #8281, dessen eigene Textschicht verklebt ist (3.000,001.200,00) — dort irrt die Messlatte. Die Zeichen-Ähnlichkeit (Median 0,75) taugt nicht als Maß: sie bestraft Reihenfolge und Tabellenform (#8467: 0,48 bei 100 % Wörtern). ⭐ Live verdrahtet, nicht mehr nur „umgesetzt in P1“: der Volltext-Leser las #8519 (28.09., 4 Seiten) und #8250 (11.10., 1 Seite) mit pypdf+mistral-ocr-latest.

P2 — Migration als Vorlage bei JC (19.09.2026, Registerzeile #2102), nicht angewandt. 05_SCHEMA/PROPOSED_rag01_p2_indexgeneration.sql: die neue Generation entsteht in rag_chunks_aufbau, die kein Lesepfad kennt; rag_generation_aktivieren() prüft Anzahl, Lückenlosigkeit und jedes Embedding und tauscht dann in einer Transaktion. Scheitert die Prüfung, bleibt der alte Stand stehen; eine ältere Generation aktiviert sich nie über eine jüngere. Die Such-RPCs ändern sich nicht. Der Code dazu folgt nach dem Apply.

P2 — Grundlinie gemessen und gesichert, Code wartet auf die Migration (20.09.2026, Registerzeile #2266). Ein Abnahmekriterium wie „der letzte vollständige Stand bleibt korrekt“ lässt sich nur prüfen, wenn der Zustand vorher gemessen ist; sonst vergleicht die Abnahme mit einer Erinnerung. 08_OPS/rag01/check_index_grundlinie.py stellt dafür fünf Fragen (Vektor · Wand · lückenlose Chunk-Folge · Lauf-Kennung · Fassung) und läuft schon ohne die Migration. Stand live: 1.937 Chunks an 677 Belegen, dazu 105 ohne Beleg; 0 ohne Vektor, 0 ohne Mandant, 2 ohne Stufe (bekannt, bei JC), 0 Löcher und 0 Dubletten in der Folge; 415 Chunks vom neuen Leser, alle mit Lauf-Kennung, 1.522 Altbestand davor. Zwei Urteile sind bewusst kein Rot: Altbestand ohne Leser-Stempel wird gezählt statt angeklagt, und eine abweichende Fassungs-Prüfsumme heißt „Fassungsfrage“ — sie nennt die Belege, denn zwei gespeicherte Zahlen zu vergleichen ist kein Urteil über den Index. Dabei gefunden, fremde Bahn: sechs Mail-Anhänge (#8385, #8434, #8435, #8442, #8443, #8444) tragen am Beleg eine andere Prüfsumme als ihre Chunks; an der Datei nachgerechnet stimmt die Chunk-Zahl, der Wert am Beleg ist falsch (an den Eingangsweg gemeldet).

#8279: gehört zu C4, soll für die ganze Entität C4 und für C3 (Muttergesellschaft) erreichbar sein; JC-Entscheid 19.09. (über TOWER#57): Stufe „intern“, ganze Entität C4; die C3-Sichtbarkeit ist eine Frage der Mandanten-Hierarchie, nicht des Belegs. Am 19.09. um 18:00 als erster Beleg des Nachlaufs neu indexiert (siehe P5).

P4 — Einstieg ausgeliefert mit Deploy-Naht 4 (Dienst 1.12.174), Live-Abnahme offen (19.09.2026, Registerzeile #2104). Der Dispatcher lässt ein PDF zuerst vollständig erschließen (direkt hinter der Dublettenprüfung), bevor ORCH einstuft; ORCH liest danach den Volltext statt der Vorschau. Jeder ORCH-Ruf nennt im Ereignis den Erschließungsstand; ein Ruf ohne Volltext heißt router.orch_ohne_volltext. Vom Tower entschieden (19.09.): ORCH wird nicht gesperrt (#2055 gilt für die fachliche Einordnung); Stufe und Entität setzt VERTRAULICH#01 nur aus einer vollständigen Erschließung. Dafür reist der Erschließungsstand als plan.extraktion unverändert in den Plan. ORCH sieht jetzt jeden Abschnitt: bis 200.000 Zeichen den ganzen Text, darüber jeden Abschnitt einzeln mit Signalen; plan.abdeckung sagt immer, wie — ein stiller Schnitt ist ausgeschlossen. Gemessen an #8279: 24.287 statt 3.629 Eingabe-Token, und der Stufen-Vorschlag kippt mit dem Volltext von vertraulich auf intern. Euro nicht berechenbar, weil kb_model_prices für das Live-Modell keinen Preis führt.

P5 — Bestands-Inventar gemessen, Nachlauf gelaufen (19.09.2026, Registerzeilen #2137 und #2175). Nur gelesen, OCR aus, kein Modellaufruf, Werkzeug 08_OPS/rag01/inventar_volltext.py mit dem echten Leser. Nenner: alle 808 Belege mit Datei.

KlasseBelegeBedeutung
Index deckt das Original387Chunk-Text ≥ 90 % des gelesenen Originals
Index mit Lücke64zusammen ~560.000 fehlende Zeichen; bei 50 hält der Index höchstens 2.000 Zeichen (12 genau 2.000 — die Kappung des Vorschau-Lesers). Größte: #8084 (83 von 66.076), #8081, #8279, #8042
ohne Index61keine Chunks; Grund je Beleg: messe_204_ungechunkt.py
OCR nötig3Scan ohne Textschicht, kein Index
Scan mit OCR-Index36vom Batch-Weg per OCR indexiert; ohne OCR nicht nachprüfbar, nie als „deckt“ gezählt
nicht lesbar64 „.pdf“ sind Bilder, 2 unbekanntes Format
nicht gemessen25158 nur auf Drive; sonst CSV, Mail, Text, Bild, Office — anderer Leseweg

Nachlauf-Kandidaten (Lücke, OCR nötig, ohne Index): 128 Belege, dafür 4 OCR-Seiten und rund 202.000 Embedding-Token. Einen Euro-Betrag gibt es nicht: kb_model_prices führt für mistral-embed keinen Preis. Der Nachlauf selbst ist eine Freigabe von JC; laut Bauplan zuerst #8279 nach seiner Einstufung, danach begrenzte Stapel — mit der P2-Migration ohne Löschlücke.

Nachlauf 19.09.2026, 18:00–18:13 (JC-Wort über TOWER#57, Fenster 18–22 Uhr). Ohne P2 und trotzdem ohne Löschlücke: 08_OPS/rag01/nachlauf_volltext.py schreibt die neuen Chunks per Upsert über die alten und löscht danach nur die überzähligen Indizes; vor jedem Beleg wird die Wand (Mandant, Stufe) gegen den Bestand geprüft, bei der ersten Auffälligkeit bricht der Lauf ab. Ein Trockenlauf um 14:30 fand 8 auffällige Belege; sie sind ausdrücklich ausgenommen (Herabstufung streng_vertraulich → intern bei #8042, #8188, #8410; Mandantwechsel bei #8043, #8044; Wand nicht auflösbar bei #8484, #8486, #8487 — Befund an VERTRAULICH#01).

StapelgeschriebenFehlerChunks vorher → nachherZeichen vorher → nachher
1 (mit #8279)649 → 3826.336 → 99.785
21005 → 254.611 → 45.225
310011 → 3618.443 → 77.545
410012 → 6912.299 → 145.382
51009 → 215.261 → 22.829
61006 → 215.414 → 17.933
7553 → 277.281 → 71.466
810010 → 7022.331 → 166.780
91005 → 195.820 → 20.162
101007 → 2210.823 → 23.565
11820 → 160 → 13.070
121000 → 310 → 42.128
Nachfahrt der 11 (18:12, mit Fix #2175)1100 → 130 → 8.553
zusammen120077 → 408118.619 → 754.423

Alle 120 mit Erschließung „vollständig“ aus dem Original; 4 OCR-Seiten; 382.737 Embedding-Token — fast doppelt so viel wie die Schätzung (Zeichen/4 ohne Mailtext), die Schätzregel ist also zu knapp. #8279: 2 → 24 Chunks, 5.682 → 67.261 Zeichen. Die 11 Fehler hatten eine Ursache: NUL-Zeichen aus pypdf, die Postgres nicht annimmt (22P05). Keiner der 11 hatte vorher einen Index, verloren ging also nichts. Die Wurzel liegt im Baustein volltext und ist behoben (#2175, PR #2877, Dienstfassung 1.12.188, wartet auf das Deploy-Wort); die 11 wurden mit dieser Fassung aus dem Worktree nachgefahren. Nicht im Nachlauf: #7326 (Volltext kürzer als der Index, übersprungen) und die 8 ausgenommenen. Noch offen: Abnahme über KAI an #8279 und die Live-Abnahme von P1 im Dienst — seit dem Deploy am 19.09. ist kein neuer Beleg eingegangen.

P3 — Rechte und KAI: Lesewege inventarisiert, eine Wache ergänzt (19.09.2026, Registerzeile #2180). Kein zweites Inventar: die Lesewege-Tabelle „Leseweg × Decke × Wache“ führt VERTRAULICH#01 an EINER Stelle, konzept_sicherheit §6 (dort auch das RPC-Gate von search_knowledge_scoped; die Tabellen-Policies von rag_chunks stehen in §5). RAG#01 hat die Wege auf rag_chunks beigesteuert: KAI Vektor- und Lexik-Suche (Mitgliedschaft des Aufrufers, Stufen-Cap in der RPC, bewacht), memory-search-chat (Projekt-Tor + Stufen-Nachfilter, bisher ohne Test — jetzt test_lesewege_memory_search_2180.py in Schritt ㊵, beide Richtungen, Gegenprobe: ohne Tor bzw. ohne Filter je 2 rot), MCP lookup_pipeline_doc (service_role, liest nur source_type='user_doc' — 6 Pipeline-Handbücher, Stufe intern, keine Belege; der ganze MCP-Server ist nur als lokales Einnutzer-Werkzeug tragbar, bewacht von test_mcp_nur_lokal_2181.py, VERTRAULICH#01), n8n-Webhook tgv-skill-rag-search (live am 19.09. inaktiv gemessen; Löschung der Funktion liegt als PROPOSED bei JC). Offen für P3: die Positiv-/Negativfälle aus 7e über KAI selbst (Teil-/Altstände nennen) und das Widerrufsverhalten.

7f · Der Gesamtworkflow eines neuen Dokuments

Dieser Ablauf verbindet Touch Once, Human First, Sicherheit, Dokumentmanagement, KAI und fachliche Arbeit. Er ersetzt keine Schwester-Konzepte: dort stehen die jeweiligen Detailverträge. Er macht sichtbar, wann sie im selben Dokumentweg gelten. Die Stufen sind keine starre Warteschlange: nach der gemeinsamen vollständigen Erschließung laufen Wissensindex und Facharbeit unabhängig; Rechte, Herkunft, Version und Lebenszyklus gelten in jeder Stufe.

StufeErgebnis und verbindliche Anschlüsse
0 · Absicht und ScopeBestehende Absichten, Mandant, Entität, Projekt und Befugnisse bestimmen. Nur Fragen stellen, die den Weg wirklich verzweigen. Scope kommt serverseitig aus Mitgliedschaft und verengt sich nur.
1 · Eingang und OriginalDatei, Mail oder Anlage einmal erfassen; Roh-Original vor jeder Verarbeitung sichern. Herkunft, Elternbezug und Fingerprint bewahren. Eine Mail kann selbst das Original sein; unklare Fälle bleiben auffindbar.
2 · Identität und SchutzIdentische Datei, neue Fassung, fachliche Dublette und Interco-Fall unterscheiden. Mandant, Entität, Projekt und Vertraulichkeit vor jeder Sichtbarkeit bestimmen; unaufgelöst bleibt fail-closed. Hier gilt nur ein vorläufiger Schutz: bis Stufe 3b entschieden hat, ist der Beleg nicht eingestuft und für niemanden sichtbar. Absender, Mail und Betreff sind Hinweise, keine Einstufung.
3 · Vollständige ErschließungParser/OCR lesen Seiten, Tabellen und Anlagen vollständig. Abdeckung, Fehler und Extraktionsversion werden nachgewiesen. Vorschau ist nicht Volltext; Teilfehler werden nicht als Erfolg markiert.
3b · Einstufung aus dem DokumentORCH entscheidet Vertraulichkeitsstufe und Entitäts-Zuordnung auf der vollständigen Extraktion aus Stufe 3, nicht auf Vorschau oder Mail (JC-Grundsatz 19.09.2026). Naht: VERTRAULICH#01 (#2795, #2796). Erst danach werden Chunks sichtbar und Fachskills gestartet; ein nur teilweise gelesenes Dokument wird mit Vorbehalt eingestuft.
4a · WissenswegGeprüfte Chunks und Embeddings als aktive Generation bereitstellen. KAI antwortet mit Quellen, Sichtumfang und ehrlicher Teil-/Altstandsmarkierung. Semantische und lexikalische Suche verwenden dieselbe Wand.
4b · FachwegORCH plant passende Fachskills auf derselben Extraktionsversion: Parteien, Vertrag, Rechnung, Frist, Zahlung, Projekt und weitere strukturierte Ergebnisse. Fachfehler blockiert den Wissensweg nicht.
5 · Klärung und FreigabeNur echte Unsicherheit, Konflikte, sensible Fälle und schreibende Aktionen erreichen den Menschen. Vorschlag, Korrektur, Bestätigung, Undo und tatsächlicher Vollzug bleiben getrennt und nachweisbar; die betroffene Arbeit läuft danach gezielt weiter.
6 · Ergebnis und RückflussKAI, Karten, Fachscreens und Belegöffnung zeigen dieselbe berechtigte Wahrheit. Jede Aussage trägt Quelle, Version und Bearbeitungsstand. Korrekturen erzeugen Lernereignisse für Antwortqualität, Systemverbesserung und berechtigtes Kontextwissen.
7 · LebenszyklusÄnderung, Hoch-/Runterstufung, Projektwechsel, Archivierung, Aufbewahrung, Export und Löschung aktualisieren Original, Fachobjekte, Index, Quellen, Cache und Rechte. Ein alter Link oder Chunk darf keine alte Berechtigung konservieren.

Durchgehende Invarianten: Quelle an jeder Aussage und jeder Zahl; Original und Version reproduzierbar; keine Rechte aus Prompt oder Client; jeder Schreibvorgang mit der vorgesehenen Freigabe; keine Teilindex-Aktivierung; eindeutige Zustände für gespeichert, vollständig erschlossen, durchsuchbar, fachlich bearbeitet und prüfbedürftig. Aus jedem Lauf entsteht eine sichtbare Lücke oder ein geprüfter Erfolg, nicht stilles Vergessen.

Bestehende Bausteine und Lücken: Originalablage, Dokument-/Ereignisfelder, Dublettencheck, ORCH, Fachskills, Klärung mit Undo, RAG-Tabellen, zwei produktive Suchwege und Pattern-Promoter bestehen. Noch zu verdrahten beziehungsweise nachzuweisen sind Vollständigkeits- und Generationenvertrag, Rechtegegenproben über alle Lesepfade, Wiederaufnahme nach Klärung, sichere Nutzung gelernter Muster sowie der Bestandsnachlauf. Der vollständige Bau- und Verdrahtungsplan steht im zugehörigen Word-Dokument und wird nach jedem Paket mit diesem Abschnitt abgeglichen.

7g · Lesequalität, Zerlegung und Lesetiefe — einmal lesen, viele Leser (RAG#09, #4064)

JC 11.10.2026 wörtlich: „wie sichern wir eine optimale Qualität der OCR Scans? und dass die chunks verlustfrei erstellt werden? haben wir im Workflow nur einen Scan-Durchgang? bei ORCH am Prozess-Anfang? oder weitere durch die Sub-Agenten? oder Skills?“ und „Ich frage mich ob dieser pauschale Wert 3200 für alle Art von Input die TGV bekommen wird der richtige Weg ist? Was ist mit Verträgen über 200 Seiten? […] Ist nicht eine Differenzierung der Input-Token-Limits je nach Prozessschritt ein passender Weg? Wie machen es die Profis, damit auch die Token-Kosten minimiert / optimiert bleiben?“ Status: Konzept. Es ist nichts gebaut, und der Bau wartet auf JCs Wort (§7g-5).

⭐ Die kurze Antwort. ① 3200 ist keine Lesegrenze. Die Zahl gibt nur an, in welche Stücke der Wissensindex den Text schneidet. Ein Vertrag mit 200 Seiten wird ganz gelesen und ergibt etwa 140 Chunks. ② Die Lesegrenzen liegen woanders. Sie sind heute schon je Schritt verschieden, nur nie bewusst festgelegt: ORCH 200.000 Zeichen · Rechnung 12.000 · Steuer 6.000, gelesen aus einer Vorschau von 2.000 · KAI-Detailansicht 20.000 · KAI-Suche 6 Chunks. ⇒ JCs Idee „Budget je Prozessschritt“ ist richtig, nur fehlt dafür bisher der Plan. ③ Ein Beleg wird nicht einmal gelesen, sondern bis zu viermal. OCR wird für dieselbe Scan-Seite bis zu zweimal bezahlt. ④ Eine Prüfung der OCR-Qualität gibt es nicht.

7g-1 · Gemessen am 11.10.2026 (nur gelesen)

FrageMesswertFundstelle / Instrument
Wie oft wird das Original gelesen?Bis zu 4×: parse-docling (Volltext), pdf-text-snippet (Vorschau), pdf-invoice-extract (eigenes pypdf, ohne OCR) und rag-ingest (liest neu, statt den Volltext zu übernehmen). OCR bis zu 2× bezahlt: parse-docling und rag-ingest bauen je ein eigenes OcrWahl.parse-docling/skill.py:490-492 · tgv-skill-pdf-text-snippet/skill.py:313 · pdf-invoice-extract/skill.py:1247 · rag-ingest/skill.py:854-856
Wer liest den gespeicherten Volltext?ORCH, contract-extract und die KAI-Detailansicht lesen extracted_markdown. tax-extract liest nur die Vorschau (2.000 Zeichen). Der Erschließungsstand (vollständig/teilweise) steht in keiner Spalte von documents, sondern nur in Ereignis, Plan und source_meta.tax-extract/skill.py:75,332 · executors_klaerung.py · dispatch.py:907-923
Deckt der Index das Original?869 Belege mit Datei: 159 vollständig (neuer Leser) · 387 deckt · 5 Lücke · 19 ohne Index · 1 OCR nötig · 36 OCR-Index ungeprüft (606 Scan-Seiten) · 9 nicht lesbar · 253 nicht gemessen (66 CSV, 40 nur auf Drive, 34 Mail, 67 Bilder, 13 Office u. a.). Gegen 19.09.: Lücke 64 → 5, ohne Index 61 → 19.08_OPS/rag01/inventar_volltext.py, OCR aus
Wurde Text abgeschnitten?#8042 (16 Seiten): Der Index hält 2.000 von 46.270 Zeichen. Das ist genau die Kappung der Vorschau. Der Beleg ist seit 19.09. vom Nachlauf ausgenommen, weil er herabgestuft wurde (VERTRAULICH#01). Die übrigen 4 Lücken betreffen Belege mit 1 bis 4 Seiten.Inventar, Klasse index_luecke
Fertig, aber nie indexiert12 der 19 Belege ohne Index sind NIE_VERSUCHT, darunter 5 Verträge im Zustand „done“ (#8505 mit 12 Seiten, #8506, #8507, #8508, #8536). Der Auslöser am Kettenende startet rag-ingest nur für Finanzbelege. Die Taxonomie plant ihn auch für VERTRAG, an diesen fünf ist er aber nie gelaufen.dispatch.py:1522-1531 · taxonomy.py:104 · messe_204_ungechunkt.py
Längster Beleg#7707: 58 Seiten, 120.532 Zeichen, 45 Chunks, deckt. Längster Vertrag: #7987 mit 38 Seiten und 24 Chunks (OCR-Index). Im Bestand liegt kein Beleg über 58 Seiten, ein Vertrag mit 200 Seiten ist also noch nie durchgelaufen. Gemessen: 1.922–2.078 Zeichen je Seite (#8279, #7707).Inventar · rag_chunks
ORCH: wie viel liest er?343 Pläne seit 19.09., alle verfahren=voll (keiner über 200.000 Zeichen). Eingabe-Token: Median 2.344, p90 3.606, Maximum 35.513 (#7707). Zusammen 960.160 Token ≈ 0,44 €. Befund: Alle 96 PDF-Pläne kamen über Retriage, und 56 davon tragen keinen Erschließungsstand (0 bis 1.019 Zeichen). ORCH urteilte dort auf der Vorschau. Das Retriage-Tor liest außerdem keine Chunks.agent_events orch.plan_served · agent_loop.py:43-45 · dispatch.py:1264
Token je Schrittkai.chat: 467 Aufrufe, 8,43 Mio. Eingabe-Token, 6,06 € (Ø 18.041 je Aufruf) · pdf-invoice-extract: 260 Aufrufe, 384.422 Token, 1,31 € · rag-ingest: 146 Aufrufe, 208.585 Token, 0,25 €. ORCH bucht in skill_call_costs keine Token (nur in agent_events). OCR-Seiten bucht der Dienst nicht (bekannt, P1).skill_call_costs 20.05.–11.10.2026 · kb_model_prices
OCR-QualitätWird nicht geprüft. TGV fragt Mistral nur nach Markdown. Die vorhandenen „confidence“-Werte sind Selbsteinschätzungen der LLMs, keine OCR-Messung.volltext.py:423 · Prüfreichweite: alle *.py/*.sql/*.js

7g-2 · Heute gegen Ziel

HEUTE · bis zu 4 Lesungen, OCR bis zu 2× bezahlt Original parse-docling · OCR € pdf-text-snippet · 2.000 Z. invoice-extract · ohne OCR rag-ingest · OCR € noch mal tax-extract liest nur die Vorschau ZIEL · einmal lesen, viele Leser Original Extraktion 1×+ OCR-Tor ORCH · Volltext Fachskills · Budget Index · Eltern/Kind KAI · nennt Abdeckung neu gelesen wird nur eine beanstandete Seite

7g-3 · Vier Bausteine mit Varianten

BausteinA · heuteBCEmpfehlung
(1) OCR-QualitätstorKeine Prüfung. Nur „Seite ohne Text gilt als nicht gelesen, nicht als leer“ ist gesichert.Plausibilität ohne Mehrkosten: Zeichen je Seite, Beträge, Datum und IBAN-Prüfziffer gegen die Fachfelder.B, dazu die Seiten-Konfidenz von Mistral (confidence_scores_granularity). Ein zweiter Durchgang nur für Seiten unter der Schwelle, gelesen von einem zweiten Leser als Gegenprobe (docling-OCR auf Hetzner, EU). Widersprechen sich die Beträge, geht der Beleg in die Klärung statt still weiter.C. Die Schwelle ist ein Wert mit Herkunft nach §8 (zuerst Vorgabe, AUTO erst nach Messung). Erster Prüffall: die 36 OCR-Belege mit 606 ungeprüften Seiten.
(2) Zerlegung je Belegart3200/400 für alles. Der Seitenanker seite:N ist vorhanden.Nach Struktur: Rechnung und Quittung als ein Chunk, wenn sie kurz sind · Vertrag und Urteil nach Überschrift oder Klausel · Kontoauszug je Buchung, mit Tabellenkopf · Mail und Anhang getrennt (gibt es schon). Dazu Eltern/Kind: das Kind (Absatz, Klausel) wird gesucht, das Eltern-Stück (Abschnitt, Seite) geht an KAI.Semantische oder LLM-Zerlegung: kostet je Beleg einen Modellaufruf. Laut Chroma ist der Gewinn gegenüber gut eingestellter Zerlegung nach Regeln klein.B, aber erst messen, dann umschalten (messe_chunk_groesse.py, §8d, je Belegart). ⛔ Ein Eltern-Abruf ist ein neuer Leseweg. Er geht durch dieselbe Wand wie die Suche (§7c), nie über einen direkten Tabellenzugriff.
(3) Ein Lesen, Lesetiefe nach BedarfJeder Skill liest selbst, zum Teil nur die Vorschau.Die Extraktion wird einmal gespeichert (Text, Seiten, Abdeckung, Fingerprint), und alle Leser lesen daraus. ORCH stuft auf dem Volltext ein (JC 19.09.).B, dazu Lesetiefe in Stufen: 0 Vorschau, nur für Dublette und Format · 1 gespeicherter Volltext für ORCH, Fachskills und Index · 2 gezielt neu lesen, nur wenn das Qualitätstor eine Seite beanstandet, eine neue OCR-Fassung kommt oder ein Fachskill das Layout braucht (Tabelle, Unterschrift). Dann werden nur die betroffenen Seiten gelesen. KAI nennt bei jeder Antwort die Abdeckung, und ein Prüfauftrag über den ganzen Vertrag arbeitet alle Abschnitte ab, statt sich auf die Top-k-Suche zu verlassen (§7a).C. Auf JCs Frage: ORCH stuft nicht auf einer Vorschau ein, und die Sub-Agenten scannen nicht neu. Neu gelesen wird nur, was das Tor beanstandet.
(4) Token-Budget je SchrittVerstreute Konstanten im Code (Tabelle unten).Eine Budget-Tabelle je Schritt in tunable_params, mit Leser (§8b).B, dazu AUTO aus Messung (§8d).B jetzt, C später. Die Kosten zeigt die Tabelle unten.

Budget je Schritt — heute und Vorschlag, gerechnet für einen gescannten Vertrag mit 200 Seiten (≈ 400.000 Zeichen bei gemessenen ~2.000 Zeichen je Seite; Preise aus kb_model_prices, 0,92 €/USD):

SchrittHeuteVorschlagKosten bei 200 Seiten
Lesen / OCRNur Scan-Seiten, aber bis zu 2× (siehe 7g-1)1×, nur Scan-Seiten. Den Bestand über den Batch-Weg zum halben Preis200 × 0,001 USD = 0,18 € (heute bis 0,37 €)
ORCH EinstufungBis 200.000 Zeichen ganz, darüber in Abschnitten von 60.000 mit Signalen agent_loop.py:43-45Bleibt so. Grenze als Budget-Zeile≈ 115.000 Token (gemessen ~3,5 Zeichen je Token) ≈ 0,05 €
Fachskill Rechnung12.000 Zeichen pdf-invoice-extract:133Bleibt (eine Rechnung passt fast immer hinein), aber aus der gespeicherten Extraktion—
Fachskill VertragGanzer Text, ohne SchnittJe Klausel über die Eltern-Stücke, danach zusammenführenGrößenordnung wie ORCH
Fachskill Steuer6.000 aus einer Vorschau von 2.000 tax-extract:75,332Aus dem Volltext—
Wissensindex3200/400 für allesJe Belegart (2-B)≈ 230.000 Token × 0,10 USD/M ≈ 0,02 €
KAISuche: 6 Chunks · Detail: 20.000 ZeichenKind-Treffer mit Eltern-Kontext. Prüfauftrag: alle Abschnitte, Abdeckung wird genanntHeute Ø 18.041 Token je Aufruf ≈ 0,013 €
Das Einlesen eines Vertrags mit 200 Seiten kostet etwa 0,25 €, heute wegen der doppelten OCR bis 0,45 €.⇒ Kostenhebel ist nicht „weniger lesen“, sondern ① nicht doppelt lesen und ② KAI nicht bei jeder Frage den halben Vertrag schicken: Eltern/Kind liefert genau den Abschnitt. Unter den Schritten, die Token buchen, ist KAI der größte: 8,43 Mio. Eingabe-Token, 6,06 € (skill_call_costs). ORCH (0,44 €) und OCR sind dort nicht gebucht.

7g-4 · Wie es verbreitet gemacht wird — nur mit Quelle

7g-5 · Empfehlung und OK-Frage an JC (über TOWER)

Lage: Gelesen wird vollständig (Lücken 64 → 5 seit 19.09.), aber mehrfach. Die Qualität der Scans prüft niemand. Die Lesegrenzen sind zufällig entstanden, und eine davon (Steuer) liest nur die Vorschau. Empfehlung, in dieser Reihenfolge, je ein PR mit Messung vorher und nachher: ① Ein Lesen (3-C): spart die doppelte OCR und schließt die Vorschau-Leser · ② OCR-Tor (1-C) · ③ Zerlegung je Belegart (2-B), zuerst gemessen, dann umgeschaltet · ④ Budget-Tabelle (4-B). Die OK-Frage: „JC, OK für ①–④ in dieser Reihenfolge — und darf der zweite OCR-Durchgang einer beanstandeten Seite automatisch laufen (Kosten nur je beanstandeter Seite), statt jede beanstandete Seite einem Menschen vorzulegen?“

7g-6 · Befunde dieser Messung, die nicht in den Bau gehören — Fortsetzung über TOWER

Reichweite: Repo-Code auf master f22dd1cc9 · Live-Datenbank am 11.10.2026, nur gelesen (rag_chunks, documents, agent_events, skill_call_costs, kb_model_prices) · Inventar mit dem echten Leser, OCR aus. Nicht gemessen: die laufende Dienstfassung auf Hetzner · n8n · ob die Mistral-Konfidenz live geliefert wird · die Güte der Antworten (nur Auffindbarkeit und Abdeckung) · die Zeichenqualität der 36 OCR-Belege.

8 · Eintuning durch den User — AUTO ist ein Nachweis, kein Vorgabewert

JCs Auftrag, 06.10.2026, wörtlich: „dazu erwarte ich eine nachhaltiges KONZEPTION deinerseits und eine pragmatische Parameter/Einstellungsseite für Admins mit Erklärungen!!!! Bitte einbauen aber erst wenn du ein Gesamtkonzept der Eintuning durch user [hast] (mit ggf überall AUTO, damit der User sich darauf verlassen kann dass TGV es automatisch optimiert, wenn der user nicht weiss was er eingeben soll." ⇒ Drei getrennte Forderungen: Gesamtkonzept zuerst („erst wenn"), Erklärungen statt Felder, und AUTO als Vorgabe, die niemand verstehen muss. Dieser Abschnitt ist das Konzept; die Fläche selbst ist der zweite Schritt.

⭐ DER SATZ, AUF DEN ALLES ANDERE HINAUSLÄUFT: AUTO ist eine Herkunft, kein Wert. Ein fester Vorgabewert, der „AUTO" heißt, ist ein Hardcode mit besserem Etikett. AUTO heißt: TGV hat gemessen und gewählt — und sagt, was es gewählt hat, warum, und wann. ⇒ Darum trägt eine AUTO-Zeile ihren Nachweis im Schlüssel, nicht in der Prosa daneben (§8d). Ein AUTO ohne Beleg ist dann nicht „schlecht dokumentiert", sondern schematisch unmöglich.

8a · Die Lage, gemessen: die Fläche ist gebaut und unverdrahtet

Anlass war die Beobachtung, CHUNK_CHARS = 3200 stehe an fünf Stellen, „ein Parameter, der an fünf Stellen steht, hat keinen Ort". Gemessen ist es anders — und schlimmer. Der Ort existiert dreifach gebaut: die Ablage tunable_params (05_SCHEMA/248_admin02_tunable_params_flaeche.sql:95-101, beide Zeilen leben), der getippte Leser chunk_chars() (08_OPS/tgv_tunables.py:138) und die Zeiger-Spalte code_ref mit eigenem Wächter. ⭐ Nicht der Ort fehlt, die Leser fehlen — und das ist eine ganz andere Reparatur.

Gemessen am 06.10.2026 mit 08_OPS/mess_parameter_ort.py (netzfrei, schreibt nichts, Selbsttest grün auf 4 Achsen je blind UND unscharf). Die Einheit eines Lesers ist die Datei, und als Leser zählt nur ein Aufrufknoten im Syntaxbaum — nicht eine Nennung im Text:

SchlüsselAblageLeserHardcode-Zwillinge daneben
klaer_schwelleja1 · 08_OPS/agent_orch01/einstufung_entscheid.py:790
llm_modelja00
max_tokensja00
chunk_charsja03 · rag01/ingest_core_privat.py:75 · tgv-skill-rag-ingest/skill.py:129 · tgv-skill-rag-ingest-project/skill.py:59
chunk_overlapja03 · …:76 · …/skill.py:130 (heißt dort OVERLAP_CHARS) · …/skill.py:60
gesamt_maxja01 · 08_OPS/chat_engine/executors_rag.py:638
p_top_kja00
p_min_scoreja00
Acht Schlüssel sind einstellbar. Einer wird gelesen.⇒ Sieben Werte, die ein Verwalter heute verstellen kann, ohne dass irgendetwas anders passiert. Das ist keine fehlende Funktion, sondern eine versprochene: die Fläche, der Helfer und der Seed sind gebaut, nur ruft die Produktion sie nicht. JCs Maßstab „Verdrahtung zählt" hat hier seinen Beweisfall — sieben Zeilen ohne Leser sind der Beleg, dass ein Baustein ohne Leser kein Baustein ist, sondern eine Zusage.
⛔ WARUM EIN GREP DIESE ZAHL NICHT FINDET — und das gehört zum Konzept, nicht zur Fußnote. Die erste Fassung des Messwerkzeugs suchte Namen im Text und war in beide Richtungen falsch, an derselben Zeile: ⓵ zu voll — sie zählte zwei Prosa-Nennungen als Leser (einen Docstring-Satz und eine Zeile im erzeugten anforderungs_register.html); ein Blatt, das einen Ruf beschreibt, ruft nichts. ⓶ zu leer — sie verpasste den einzigen echten Ruf, weil der Import ihn umbenennt (import klaer_schwelle as _klaer_schwelle, gerufen als _klaer_schwelle()). ⭐ Ein Instrument, das Text liest, kann „wer RUFT" nicht beantworten — es sieht Namen, keine Rufe. Dieselbe Falle trägt die Fläche selbst: max_tokens steht als API-Körperfeld, llm_model als Log-Feld, p_top_k als RPC-Parameter im ganzen Haus. Wer am Wort zählt, meldet hier vier Leser, wo einer ist.

8b · Drei Lücken je Parameter — und wer eine schließt, hat nichts geschlossen

Ein Schalter wirkt erst, wenn alle drei Stücke stehen. Sie fehlen unabhängig voneinander, und genau deshalb hat die Fläche heute den Anschein von Fertigkeit:

StückFrageFehlt es, dann …Stand 06.10.
① AblageGibt es eine Zeile, die den Wert hält?… ist jede Eingabe sofort wieder weg.8 von 8 da
② LeserFragt der Code sie, bevor er handelt?… ist die Eingabe wirkungslos, und zwar still. Der schlimmste der drei Fälle: der Verwalter sieht einen Erfolg.1 von 8
③ SchreibrechtDarf der, dem wir den Schalter zeigen, ihn auch setzen?… ist der Schalter Dekoration, oder er schreibt für alle Mandanten.alle 8 super_admin

Dieselbe Dreiteilung hat die Vorarbeit schon gemessen und als Satz formuliert: „Drei verschiedene Lücken (Ablage · Leser · Schreibrecht) — wer eine schließt, hat nichts geschlossen." ⇒ Für die Seite ist das eine Bauvorschrift: eine Zeile darf nur dann als schaltbar erscheinen, wenn alle drei Stücke belegt sind. Für die übrigen gilt §8e.

8c · Was AUTO ist — vier Zustände, und zwei davon dürfen nie gleich aussehen

Eine Einstellung hat nicht „einen Wert", sondern einen Wert und eine Herkunft. Vier Zustände, und der Unterschied zwischen ① und ② ist der ganze Sinn der Übung:

ZustandWas der User liestWas es technisch heißt
① AUTO · gewählt„TGV hat 3200 Zeichen gewählt — gemessen am 04.10. an 895 Dokumenten. Warum: bei 800 Zeichen rutschten Treffer nach vorn, aber der Unsinn stieg mit."herkunft='auto' + messbeleg zeigt auf einen echten Lauf. Nur dieser Zustand darf „AUTO" heißen.
② VORGABE · noch nicht gemessen„Steht auf 3200 — unser Hauswert. Für dich noch nicht gemessen; TGV misst, sobald genug Belege da sind."herkunft='vorgabe', kein Messbeleg. ⛔ Ehrlichster Zustand und der häufigste. Sieht er wie ① aus, ist AUTO von einem Hardcode nicht zu unterscheiden — genau JCs Sorge.
③ HAND„Du hast 2400 gesetzt, am 06.10. — zurück auf AUTO."herkunft='hand' + wer + wann. AUTO überschreibt das nie, auch nicht nach einer besseren Messung — es schlägt vor.
④ GESPERRTDer Grund, in seiner Sprache — siehe §8e.Mindestens eines der drei Stücke aus §8b fehlt belegt.
Die Rangfolge, damit „verlassen können" (JCs Wort) eine Mechanik ist: HAND schlägt AUTO-Messung schlägt Hauskanon. Wer einmal selbst gesetzt hat, wird nicht von einer Automatik überfahren; wer nie etwas gesetzt hat, bekommt das Beste, was TGV messen konnte; und wo nichts gemessen ist, gilt der Hauswert sichtbar als solcher. ⭐ Das Muster „Kanon → zulässiger Override → konkreter Wert" ist im Haus schon gebaut und läuft: llm_aufgaben mit UNIQUE (aufgabe_key, mandant_id), Leseform holt beide Ebenen (08_OPS/modell01/policy_laden.py:67), Auswahl „Mandanten-Zeile schlägt Vorlage" (:152). ⇒ Die Fläche erbt diese Form, sie erfindet keine zweite.

Und AUTO ist selbst eine Einstellung — die einzige, die der User immer versteht: „soll TGV das für mich entscheiden?" Steht sie auf ja, ist der Wert ein Zwischenstand einer Messung, kein Beschluss. Deshalb darf ein AUTO-Wert sich ändern, ohne dass jemand etwas falsch gemacht hat — und deshalb muss jede Änderung ihren Beleg mitführen, sonst ist sie von einem Fehler nicht zu unterscheiden.

8d · AUTOs Form: der Nachweis steht im Schlüssel, nicht in der Prosa

Die Form dafür ist im Haus schon erfunden und gilt als die beste ihrer Art: das Telemetrie-Trio (05_SCHEMA/285_telemetrie01_achse_und_turn_STAGED.sql:239-264) speichert nicht nur die Zustimmung, sondern _von und _am dazu — und ein CHECK erzwingt, dass der Wert ohne seinen Nachweis nicht setzbar ist. Übertragen auf Einstellungen:

FeldWas es trägt
wertder geltende Wert
herkunftauto · vorgabe · hand — die vier Zustände aus §8c (gesperrt ergibt sich, es wird nicht gespeichert)
gewaehlt_am / gewaehlt_vonwann, und bei hand: von wem
messbelegZeiger auf den Lauf, der diesen Wert gewählt hat — und auf die Zahl, die ihn trug
⛔ Die eine Bedingung, die AUTO von einem Hardcode trennt: CHECK (herkunft <> 'auto' OR messbeleg IS NOT NULL). ⇒ Ein AUTO ohne Erklärung ist nicht verboten, es ist unmöglich. Eine Grenze, die man umgehen kann, ohne dass eine Probe fällt, ist eine Absicht — sie gehört in den Schlüssel, nicht in eine Prüfung daneben.

Woher der Messbeleg kommt — und was er nicht ist. 08_OPS/rag01/messe_chunk_groesse.py ist gebaut (431 Zeilen) und misst je Chunk-Größe vier Zahlen, die zusammengehören: Rang des richtigen Treffers · wer dabei verdrängt wird · ob der Unsinn mitsteigt · Aufrufe und 429er. Es sagt in seinem eigenen Kopf, was es nicht misst: „Auffindbarkeit, nicht Antwortgüte" — ein Chunk kann den richtigen Rang haben und zu wenig Kontext für eine brauchbare Antwort tragen. Und es schreibt nichts.

⇒ Es ist der Beweis-Erzeuger für AUTO, nicht AUTO selbst. Die Unterscheidung ist nicht akademisch: der Lauf ist korpusweit und kostet Embedding-Aufrufe, kann also nie zur Laufzeit je Dokument entscheiden. AUTO ist deshalb periodisch: ein Lauf wählt, schreibt Wert und Beleg, und der Dienst liest beides. ⭐ Ein Nebeneffekt ist das stärkste Argument für genau EINEN Ort: das Messwerkzeug importiert ingest_core_privat als Quelle der Chunk-Logik (messe_chunk_groesse.py: import ingest_core_privat as ING) — wandert die Konstante in die Fläche, folgt die Messung von selbst. Bleiben es drei Stellen, misst das Werkzeug irgendwann etwas anderes, als der Dienst tut, und niemand merkt es.

⛔ Die Verdrahtung der drei Chunk-Leser ist ein unteilbarer Zug — wer sie halb macht, macht sie falsch. 08_OPS/heimholung02/mutationsprobe.py:253 schreibt die Literalzeile vor: sie ersetzt Textanker wie "CHUNK_CHARS = 3200" und "if last_space > CHUNK_CHARS * 0.6:", um den Paritäts-Test rot zu machen. Wird die Größe im Schleifenrumpf ein Ruf, zeigen zwei dieser Anker ins Leere. ⭐ Korrektur an der ersten Fassung dieses Satzes, nachgelesen statt vermutet: dort stand *„meldet grün als überlebt"* — das ist falsch. Dieser Lauf zählt seinen Anker, bevor er schreibt (original.count(suchen) != 1 ⇒ durchgerutscht, dann [STUMPF] und rc=1). ⇒ Der Zug bleibt unteilbar, aber aus dem anderen Grund: wer die Leser verdrahtet und die Anker liegen lässt, macht die Probe stumpf und seine Bahn rot — er fälscht sie nicht. Ein Prüfer, der seinen eigenen Anker zählt, ist gegen genau diese Klasse schon gebaut — das war nachzulesen, nicht zu vermuten. Dazu verlangt 07_TESTS/heimholung06/test_rag_ingest_paritaet.py:26 die Chunk-Logik beider Skills zeichengleich. ⇒ Zwei Skills + Mutationsprobe + Paritäts-Test in einem Zug. ⭐ Und die „fünfte Stelle" ist gar keine Definition: 08_OPS/check_code_ref_zeigt_ins_leere.py:342 ist ein Fixture-String im Selbsttest. Von fünf Stellen sind drei Definitionen und zwei Wächter — wer alle fünf „aufräumt", entwaffnet zwei Prüfer.

8e · Was der User sieht — eine Erklärung je Zeile, und bei Sperre das WARUM

JCs Auflage: „ein gesperrter Schalter zeigt nicht nur DASS er gesperrt ist, sondern WARUM, in seiner Sprache — fehlt die Funktion, fehlt das Feld, oder gilt er fürs ganze Haus." Die drei Gründe sind genau die drei Stücke aus §8b, von hinten gelesen:

GrundWas dem User stehtWoran es gemessen wird
Fehlt das Feld„Dafür gibt es bei uns noch keinen Platz — wir bauen ihn."keine Zeile in der Ablage (Achse 1)
Fehlt die Funktion„Du könntest das einstellen, aber noch würde es nichts ändern — TGV fragt diesen Wert noch nicht."kein Aufrufknoten (Achse 2) — heute 7 von 8
Gilt fürs ganze Haus„Dieser Wert gilt für alle Mandanten. Nur der Betreiber kann ihn ändern."owner_tier='super_admin' bzw. Schreib-Policy (Achse 3)
⛔ Die „NUR HAUS"-Zeilen sind die gefährlichsten der Fläche — 13 von 49 in der Vollerhebung. Sie werden gelesen, sehen schaltbar aus, und ein Griff würde alle Mandanten auf einmal ändern. ⭐ Deshalb ist „grau dargestellt" keine Umsetzung: die Wand gehört an den Zugang, nicht in die Anzeige. Ein Mandantenverwalter, der den Schreibweg direkt ruft, muss serverseitig abgewiesen werden; die graue Darstellung ist die Höflichkeit darüber, nie der Schutz. (Dieselbe Klasse wie die Mandanten-Wand beim Suchen, nicht nur beim Anzeigen.)

Und die Erklärung ist Pflichtinhalt, nicht Hilfetext. Jede Zeile trägt vier Sätze, die ein Mensch ohne Vorwissen lesen kann: was es tut · was passiert, wenn du es hoch­stellst · was passiert, wenn du es runterstellst · woher der jetzige Wert kommt (§8c). Fehlt der dritte Satz, ist der Schalter eine Falle; fehlt der vierte, ist AUTO ein Gerücht.

Geerbte Vorbedingung, nicht Aufgabe dieser Fläche: die secSettings-Nabe und zwei weitere Menü-Renderer rufen das Klassen-Tor klasseErlaubt nicht (gemessener Fremdbefund, eigener Eigner). ⇒ Die Seite wird nicht an eine ungetorte Nabe gehängt. Kein Datenabfluss — die Endpunkte dahinter antworten per Mitgliedschaft des Aufrufers — aber eine Fläche mit gesperrten Zeilen darf nicht ausgerechnet über den Weg erreichbar sein, der die Rolle nicht prüft.

8f · Was ohne den Schlüssel-Umbau gilt — eine Erlaubnis, die das Schema nicht halten kann

Die Fläche verspricht Mandantenfähigkeit an einer Stelle, an der sie sie nicht hat. owner_tier lässt 'mandant' ausdrücklich zu und der Tabellenkommentar sagt „mandant-justierbar (dann RLS-scoped, Default-Deny)" — aber der Primärschlüssel ist PRIMARY KEY (key) allein. ⇒ Zwei Mandanten können denselben Schlüssel nie verschieden belegen. Dazu liest der einzige produktive Leser ohne jeden Mandanten-Filter (08_OPS/tgv_tunables.py: ?key=eq.<key>&select=value&limit=1) und fährt mit dem Service-Schlüssel an der RLS vorbei.

⛔ Diese Klasse ist gefährlicher als ein Verbot: eine Erlaubnis, die das Schema nicht erfüllen kann, wird gelesen, geglaubt — und scheitert erst beim zweiten Mandanten. Sie steht in derselben Familie wie ein im Kanon beschriebenes Recht ohne einen einzigen Treffer im Haus und wie ein dokumentierter Exitcode, den es nie gibt. Bis zum Umbau gilt deshalb: jede Zeile dieser Fläche ist eine HAUS-Zeile — unabhängig davon, was owner_tier trägt. Die Seite zeigt sie nach §8e als „gilt fürs ganze Haus", und sie verspricht keine Mandanten-Spalte, solange der Schlüssel keine tragen kann.

Der Weg hinaus ist bekannt und erprobt, nicht neu: die mandantenfähige Form läuft im Haus bereits als llm_aufgaben — UNIQUE (aufgabe_key, mandant_id), beide Ebenen gelesen, Mandanten-Zeile schlägt Vorlage, und eine Schreib-Policy (mandant_id IS NOT NULL) AND is_mandant_admin(…), die den Hauswert schützt. ⇒ Erben, nicht erfinden. ⚠️ Der Umbau selbst ist DDL an einer lebenden Tabelle mit RLS-Versprechen und liegt als Entscheidungsvorlage bei JC — er ist nicht Teil dieser Fläche.

Entschieden JC 10.10.2026 (#3785, Variante Ⓐ „zurücknehmen“), damit der Nächste nicht neu abwägt: die Fläche bleibt Haus-Fläche, und der Schlüssel sagt es selbst — 05_SCHEMA/294_parameter05_tunable_params_haus_flaeche_STAGED.sql verengt owner_tier per CHECK auf 'super_admin' und hält die Spalte mandant_id (Mig 262, die zweite Tür derselben Erlaubnis) per CHECK auf NULL; Gegenbeweis in der Transaktion. Ⓑ (der Umbau oben) kommt erst, wenn ein Mandant es verlangt. Der Prüfer 08_OPS/mess_parameter_ort.py Achse 3 liest dafür den Stand (Seed + angewandte spätere Migrationen), nicht mehr nur den Seed. ⚠️ Bis JC Mig 294 fährt, gilt der Absatz darüber unverändert (PARAMETER#05, #3950).

8g · Enthaltungen — was gemessen ist und was nicht

Befragt, und das ist die Reichweite jeder „kein Leser"-Aussage oben: die Regale 08_OPS · 02_SKILLS · 06_DASHBOARD, alle .py geparst (1074 Dateien im Blick), dazu der Seed Mig 248 und der Helfer tgv_tunables.py. Ausgenommen sind 07_TESTS (ein Test beweist den Helfer, nicht die Verdrahtung) und der Messlauf selbst.

Nicht befragt — und was deshalb offen bleibt: der ausgelieferte Dienst (gemessen ist Repo-Code, nicht die laufende Fassung auf Hetzner) · die n8n-Instanz · die Wirkung der Werte, wo ein Leser existiert (dass klaer_schwelle gelesen wird, ist gemessen; dass die Schwelle das Verhalten ändert, nicht) · ob 3200 heute der richtige Wert ist (das misst §8d und ist ungefahren) · die Baseline von check_werte_ohne_leser.py, die tunable_params-Spalten ausdrücklich stundet — grün heißt dort nicht leserlos-frei.