Zum Inhalt

Saga-Lehren — Methodische Konstitution

Die Defense-in-Depth-Saga (Phase 1 + Phase 2 + Phase 3 #1-3 + Quick-Win- CI-Integration + Pre-Existing-Drift-Cleanup, ~50h Wall-Clock, 13 Karten) hat 13 methodische Lehren etabliert. Sie gelten produkt-weit und werden bei künftigen Sicherheits-Initiativen als Konstitution referenziert.

Diese Page dokumentiert sie mit Herleitungs-Kontext und Cross-References zu den Karten in denen sie etabliert wurden. Das ist die kanonische Langfassung — die kompakte Liste in der Defense-in-Depth-Architektur-Doku verweist hierher.

Saga-Lehre 1 — Phase-0-Discovery zahlt sich aus

Etabliert in: K-Layer-2 (Phase 1, ~10h) + K-Layer-5 (Phase 1, ~5h)

Kern-Aussage: Read-only Discovery vor Implementierung deckt Sub-Bugs auf, die ohne Discovery erst während des Refactors als teure Korrektur-Schleifen sichtbar würden.

Begründung: L2 wäre ohne den Phase-0-Sub-Bug-Fund („Sources-im- Prompt fehlt") trotz Refactor LLM-blind geblieben — die DB-Prompts hatten kein {{ sources }}-Platzhalter, das LLM sah Sources gar nicht (Trainings-Wissen-Drift). L5 wäre ohne den Phase-0-Frontend-Befund („read-only msg.content") in eine teure α-„drop-turn"-Variante gelaufen statt der UX-neutralen β-Marker-Replace.

Praxis-Anwendung: Vor jeder größeren Saga-Karte: 30-60min Phase 0, auch wenn die Karte simpel scheint. Discovery-Outputs werden als in-Karten-Dokumentation persistiert.

Saga-Lehre 2 — Cluster-X-False-Positive-Lehre

Etabliert in: Phase 2 Cluster-X (Diagnose 1h)

Kern-Aussage: Pattern-Detection NIEMALS auf isolierten Single-Keywords (role, vergiss, ab jetzt). IMMER primary + min_co_matches-Co-Indicators.

Begründung: Single-Keyword-Pattern produzieren tautologische False-Positives: jede legitime Anfrage die zufällig das Keyword enthält wird geblockt. Cluster-X dokumentierte 22+ FP-Tests die nur durch Co-Indicator-Anforderung sauber differenzieren.

Praxis-Anwendung: L3, L5, α-Layer halten dieses Muster konsequent durch. 3/3 (L3) bzw. 22/22 (L5) FP-Tests bestanden.

Saga-Lehre 3 — Audit-Tabellen statt Drop-Behavior

Etabliert in: K-Layer-3 (Phase 1, ~7h) + K-Layer-5 (Phase 1, ~5h)

Kern-Aussage: Bei Filter-Match das Original IMMER persisten (Audit-Trail), niemals drop'en. Pattern-Tuning braucht den Original-Text.

Begründung: Drop-Behavior eliminiert die Empirie für künftige Pattern-Verfeinerung. Sowohl L3 (output_filter_audit) als auch L5 (history_persist_filter_audit) folgen diesem Muster, beide mit RLS und 3 Indizes (chatbot+created, pattern, tenant+created).

Praxis-Anwendung: Drei Audit-Tabellen Saga-weit: output_filter_audit (L3, Migration 0013), history_persist_filter_ audit (L5, Migration 0017), input_filter_audit (α, Migration 0019). Identisches Schema-Pattern — neue Filter folgen der Vorlage.

Saga-Lehre 4 — Layer-Reihenfolge L4 → L3 → L2 → L5 ist saga-korrekt

Etabliert in: Phase 1 (Reihenfolge-Validierung post-merge, 24h Total)

Kern-Aussage: Schnellster Win zuerst (L4 ~1.5h), defensives Netz (L3 ~7h), dann großer Refactor (L2 ~10h), zum Schluss Multi-Tenancy-Foundation (L5 ~5h, RLS-aware).

Begründung: Der Refactor (L2) konnte auf dem L3-Audit-Pattern aufbauen, das L5 wiederum 1:1 kopiert. Hätte die Reihenfolge umgedreht (L5 zuerst), wäre die Audit-Trail-Konvention erst zur L3-Stufe etabliert und L5 hätte sie nachträglich nachziehen müssen.

Praxis-Anwendung: Sign-off-Decision D3 in der Saga; die Reihenfolge wird nicht ohne explizite Begründung geändert.

Saga-Lehre 5 — Defense-in-Depth wirkt nur wenn alle Layer aktiv sind

Etabliert in: Phase 1 (Cross-Layer-Verifikation post-merge)

Kern-Aussage: Mehrere Schichten müssen aktiv sein — niemals nur einen Layer.

Begründung: L3 hat F-01 (Prompt-Leak-Debug-Block) defensiv geschlossen, BEVOR L2 strukturell schloss. Hätte L2 versagt, wäre L3 noch da. Hätte L5 versagt, würde der LLM den Poison vielleicht ignorieren — aber das Audit-Log fehlte.

Praxis-Anwendung: Entwurf neuer Filter prüft explizit: welche Schichten greifen orthogonal? Was passiert wenn Schicht X versagt? Die Failure-Mode-Spalte in der Defense-in-Depth-Layer-Tabelle dokumentiert das pro Schicht.

Saga-Lehre 6 — Saga-Convention zahlt sich aus

Etabliert in: Phase 1 (4 Karten mit identischer Struktur)

Kern-Aussage: Identische Karten-Struktur (Phase 0 → Commits → Smoke → Code-Review → Merge → Plan-Update) reduziert Cognitive Load und macht Bilanzen einfach.

Begründung: Vorhersehbarer Ablauf bedeutet weniger Workflow-Entscheidungen pro Karte; der Karten-Operator kann sich auf den Inhalt konzentrieren statt auf den Prozess.

Praxis-Anwendung: Alle 13 Saga-Karten folgen dieser Struktur. Die Karten-Templates in den User-Prompts spiegeln das wider.

Saga-Lehre 7 — Output-Filter-Co-Indicators MÜSSEN Output-Format-Marker sein

Etabliert in: Phase 2 Cluster 2 (K-L3-Output-Marker-Patterns, ~2.5h)

Kern-Aussage: Pattern-Co-Indicators MÜSSEN aus empirischen LLM-Output-Beobachtungen abgeleitet werden, niemals aus den User-Input-Phrasen die das Pattern abwehren soll.

Begründung: Wenn die Tenant-Persona genau die User-Input-Begriffe enthält, die das Pattern als Co-Indicator nutzt, „funktioniert" das Pattern zufällig: das LLM reproduziert die Persona-Phrasen bei Leak-Angriffen, und die Co-Indicators matchen. Sobald die Persona bereinigt wird (Phase 2 Cluster 1), reproduziert das LLM die Phrasen nicht mehr — es paraphrasiert generisch. Das Pattern stoppt still mit dem Triggern, ohne dass irgendwo eine Fehlermeldung kommt.

Praxis-Anwendung: L3-Pattern verwenden ausschließlich Output-Format-Marker als Co-Indicators (**Chunk N**, ## Inhalts- verzeichnis, code-fence-open, etc.). Phase-0-Empirie-Sweep auf realen Leak-Outputs ist nicht-verhandelbar.

Saga-Lehre 8 — Pre-LLM-Filter-Co-Indicators MÜSSEN User-Input-Vokabular sein

Etabliert in: Phase 2 Cluster 3 (α-Layer JSON-Pressure, ~3.5h)

Kern-Aussage: Lehre 8 ist die deliberate Inversion von Lehre 7. Zur Filter-Zeit eines Pre-LLM-Layers (L5, α) existiert noch keine LLM-Emission, deren Marker man matchen könnte — der einzige Beobachter ist die User-Anfrage selbst.

Begründung: Wer Lehre 7 unreflektiert auf einen Pre-LLM-Layer überträgt, baut ein Pattern, das niemals matcht (Co-Indicators sind im Input nicht da). Wer Lehre 8 unreflektiert auf einen Post-LLM-Layer überträgt, baut ein Pattern, das vom LLM trivial umgangen werden kann (Persona-Cleanup eliminiert die User-Input-Echo-Co-Indicators).

Praxis-Anwendung: Die Saga-Topologie hält das durch Trennung in zwei Module konsequent durch: output_filter.py (Lehre 7) vs. input_filter.py (Lehre 8). Beweis: Cluster-3-Smoke 15/15 PASS, in dem _JSON_PRESSURE (L3, Lehre 7) und _JSON_FORMAT_PRESSURE (α, Lehre 8) für dieselbe Pen-Test-Vulnerability zwei semantisch unterschiedliche Pattern brauchen.

Saga-Lehre 9 — Detection-Event allein ist unvollständige Verifikation

Etabliert in: Phase 3 #1 (α-Layer Pentest-FU-Patterns, ~4h)

Kern-Aussage: Korrekte Smoke-Methodik prüft drei Eigenschaften gleichzeitig: (a) Detection-Event triggert; (b) Token-Stream enthält Leak-Inhalt nicht; (c) Detection-Event-Position relativ zu letztem Token.

Begründung: Saga-Cluster 1-3 haben (a) verifiziert, (b) und (c) implizit als gegeben angenommen. Pentest 2026-05-08 hat diese Annahme widerlegt: für drei Pentest-Findings emittierte L3 zwar correction (a ✅), aber 311-1024 Token-Events waren bereits gestreamt (b ❌), und correction kam +3 Lines nach letztem Token (c ❌). End-User-UX bleibt durch Widget-DOM-Replace OK, aber API-Konsumenten und der Roh-Stream sind exponiert.

Praxis-Anwendung: Smoke-Klasse C „Stream-Position-Verifikation" permanent in scripts/security-smoke.sh und in der Extended-Pentest- Suite-Harness (tests/security_pentest/redteam-harness-extended.mjs).

Saga-Lehre 10 — Stream-Architektur ist eigene Verteidigungs-Schicht

Etabliert in: Phase 3 #2 (Stream-Architektur-Hardening Option C, ~6h)

Kern-Aussage: Pattern-Detection korrekt zu implementieren ist notwendig aber nicht hinreichend. Der Detection-Zeitpunkt relativ zum Token-Stream entscheidet ob Defense funktioniert.

Begründung: Post-Hoc-Detection auf accumulated buffer nach Stream-Ende fängt Pattern-Match, aber Tokens mit Leak-Inhalt sind dem Client zu diesem Zeitpunkt bereits geliefert. Inkrementelle Stream-Prüfung mit Look-Ahead-Buffer + Hard-Stop-Event verschiebt L3-Output-Filter von Post-Hoc-Symptom-Erkennung zu Inline-Stream- Hardening.

Praxis-Anwendung: LookAheadBuffer (K=16 Token Vorlauf) zwischen vLLM-Stream und SSE-Token-Yield; check_output(buffer.accumulated_text) vor jedem Token-Yield; bei Match discard_buffered() + Hard-Stop- Correction (hard_stop: true + clear_previous: true). Topologie post Phase 3 #2: L5 → α → Cache → L2 → LLM-Stream-with-Inline-L3 → L4.

Latenz-Trade-off: K × ~25ms ≈ 400ms zusätzliche TTFT — akzeptabel für Sicherheits-Hardening.

Saga-Lehre 11 — Pattern-Detection hat eine harte Untergrenze

Etabliert in: Phase 3 #3 (L3-Pattern-Coverage gegen 20-Leak-Korpus, ~3h)

Kern-Aussage: Schritt-basierte Bot-Antworten ohne Schema- oder Debug-Marker sind strukturell vom RAG-Erwartungs-Output ununterscheidbar.

Begründung: Der 20-Leak-Korpus enthält 4 pl_para_*-Fixtures, deren Bot-Output rein aus „Schritt 1: …, Schritt 2: …"-Anleitungen besteht — kein Schema-Marker, kein Debug-Block, kein Originaltexte-Header. Post-Phase-3-#3 ist die Coverage 2/4 (über Spillover via Filename- Source-Line-Primary), aber die übrigen 2 Fixtures (code_fence_hide, emotional_pressure) bleiben strukturell unfangbar: ein Pattern, das diese fängt, würde gleichzeitig legitime Step-by-Step-Antworten triggern.

Praxis-Anwendung: L3-Coverage hat eine harte Untergrenze. Antworten ohne distinguishable Output-Format-Marker können Defense-in-Depth nur durch upstream Layer (L2, α, L5) gefangen werden, nicht durch L3-Output-Filter. Empirie-Korpus + Real-Eval-FP-Sweep (gegen tests/evaluation/results/*.json) ist die korrekte Methodik — Coverage maximieren ohne legitime-Antwort-Regression.

Saga-Konvention: für jede zukünftige L3-Pattern-Erweiterung MUSS der Real-Eval-FP-Sweep ausgeführt werden, bevor commit gemerged wird. Korpus-Coverage allein ist nicht ausreichend (Beweis: Code-Review C1-Fix in Phase 3 #3 zeigte deterministisch dass die initial großzügig formulierte [—–_]+-Alternative 2/30 FP gegen Real-Eval-Antworten produzierte).

Saga-Lehre 12 — Pentest-Suite-Hardening als dritter Pfeiler

Etabliert in: Quick-Win CI-Integration (~2.5h, post Phase 3 #3)

Kern-Aussage: Defense-in-Depth-Methodik ist dreidimensional: Detection (Pattern-Coverage) + Architektur (Stream-Position-Timing) + Empirie-Druck (CI mit Threshold-Gates).

Begründung: Ohne kontinuierlichen Empirie-Druck via CI-Regression entsteht Drift: Pattern werden hinzugefügt, Architektur ändert sich, aber niemand prüft systematisch ob die Coverage hält. Eine produktionsreife Defense-in-Depth-Architektur muss aktiv gegen frische Adversarial-Inputs validiert werden, sonst regrediert sie.

Praxis-Anwendung: Versionierte Extended-Pentest-Suite unter tests/security_pentest/, drei sequenzielle CI-Jobs (pattern-coverage → real-eval-fp → live-suite, nightly 03:00 UTC + on-push path- filtered), Threshold-Konfiguration in thresholds.json. Real-Eval-FP- Sweep wird permanent zweite Threshold-Achse (Saga-Lehre 11 von Empfehlung zu Konvention upgraded). Pattern-Coverage ohne FP-Garantie wäre tautologische Sicherheit.

Beweis-Methodik: Pre-Merge-Smoke gegen die Pre-Phase-3-#3-Reference (reference-2026-05-08-pre-phase3-3/) reproduziert die 16 Real Leaks deterministisch (analyzer exit 1) — der Threshold-Mechanismus funktioniert auch retrospektiv gegen den Drift-Stand vor Phase 3 #3.

Saga-Lehre 13 — Cleanup-Disziplin: Drifts vertagt sammeln, vor Architektur-Phasen geschlossen

Etabliert in: Pre-Existing-Drift-Cleanup (~1.5h, post Quick-Win-CI)

Kern-Aussage: Pre-existing Drifts werden während Feature-Karten dokumentiert, nicht gefixt — aber müssen vor strategischen Architektur-Phasen systematisch geschlossen werden.

Begründung: Während der Defense-in-Depth-Saga wurden mehrfach pre-existing Drifts erkannt (mypy-Schulden in query_service.py, tenant/module test failures, mkdocs broken-link), aber bewusst NICHT im Scope der jeweiligen Saga-Karte gefixt — Disziplin um Karten klein und fokussiert zu halten. Die akkumulierten Schulden würden vor v1.0.0 SaaS-Multi-Tenancy aber False-Negatives in der Tenant- Isolation-Validierung produzieren: ein 87-error pytest-Lauf maskiert echte Multi-Tenancy-Regressions hinter Test-Infrastructure-Noise.

Praxis-Anwendung: Cleanup-Karte mit strikten Aufwands-Caps pro Sub-Phase (A mypy 1.5h / B Tests 1h / C mkdocs 30min / D weitere 1h) und Total-Cap 4h. Bei Cap-Überschreitung: Sub-Phase abschließen mit Teil-Fix, Rest in separate Karte vertagen — niemals Cleanup-Scope erweitern. Quick-Win-CI als systematisches Drift-Detection-Tool: erste echte Nutzung der Phase-3-#3-CI-Infrastructure für Drift-Inventur.

Saga-Konvention: Cleanup-Karten sind disziplinarisch gegen Schulden-Wirbel — sie erweitern nicht den Scope der schmerzhaftesten Drift, sondern bekennen offen welche Drifts vertagt sind (separate Folge-Karten mit Schätzungen). Honesty-over-Coverage.

Bilanz Pre-Existing-Drift-Cleanup: -89 pytest-Probleme (107 → 18, 87 errors → clean skips via DSN-gating), -6 mypy-Errors in query_service.py (0 verbleibend in der Datei, 58 → 52 total), -1 mkdocs warning, -9 ruff auto-fixable. Out-of-Scope vertagt: Mypy- Cleanup ~6-8h, Test-Hygiene ~3-4h, Ruff-Stylistik+Format ~2h.

Cross-Reference-Index

Lehre Karte / Phase Kategorie
1 Phase 1 (K-Layer-2 + K-Layer-5) Methodik / Discovery
2 Phase 2 Cluster-X Diagnose Pattern-Methodik
3 Phase 1 (K-Layer-3 + K-Layer-5) Audit-Trail-Konvention
4 Phase 1 (Reihenfolge-Validierung) Karten-Reihenfolge
5 Phase 1 (Cross-Layer) Defense-in-Depth-Argument
6 Phase 1 (Saga-Convention) Prozess-Methodik
7 Phase 2 Cluster 2 (L3-Output-Marker) Output-Marker-Empirie
8 Phase 2 Cluster 3 (α-Layer) Pre-LLM-Filter-Methodik
9 Phase 3 #1 (α-Layer Erweiterung) Stream-Position-Verifikation
10 Phase 3 #2 (Stream-Architektur) Stream-Architektur-Pillar
11 Phase 3 #3 (L3-Pattern-Coverage) Real-Eval-FP-Methodik
12 Quick-Win CI-Integration Pentest-Suite-Hardening
13 Pre-Existing-Drift-Cleanup Drift-Disziplin

Verhältnis zur Saga-Bilanz

Diese Saga-Lehren sind methodische Konstitution, nicht projekt-spezifische Erinnerungen. Sie gelten:

  • Produkt-weit — alle künftigen Customer-Tenants, alle künftigen Bot-Domänen, alle künftigen Sicherheits-Initiativen
  • Saga-übergreifend — auch wenn die nächste große Initiative (v1.0.0 SaaS-Multi-Tenancy) thematisch ganz anders ist, gelten Lehre 1 (Phase-0-Discovery), Lehre 4 (Reihenfolge-Validierung), Lehre 6 (Saga-Convention), Lehre 13 (Cleanup-Disziplin) genauso
  • Bei Konflikt mit Pragma-Versuchen wins die Lehre — z.B. wenn jemand vorschlägt „lass uns nur die schritt-basierten Fixtures eng matchen" (gegen Lehre 11), die Lehre setzt sich durch

Saga-Bilanz und Audit-Trail aller 13 Karten: docs/security-hardening/action-plan.md (im AVS-Repo als Living Document).