## Findings - **P1 – Fehlende Cashflow-Historie wird als „keine Cashflows“ interpretiert und erzeugt dadurch belastbare Renditen ohne Beleg.** `src/jarvis_finance/services/portfolio_performance.py:685-739,750-772` Die Berechnung prüft nur vorhandene, aber nicht klassifizierbare Aktivitäten. Sind überhaupt keine Aktivitäten vorhanden – etwa beim kanonischen TrueWealth-Totalwertkonto ohne vollständige Cashflowhistorie – berechnet sie TTWROR und XIRR allein aus Anfangs- und Endwert und meldet beide als `complete`. Dadurch übernimmt auch die Coverage-Matrix in `src/jarvis_finance/services/portfolio_performance.py:135-166` falsche Vollständigkeit. Reproduziert: zwei TrueWealth-Bewertungen ohne Transaktionen ergaben XIRR `0.099713585898`, Status `complete`. Das widerspricht dem dokumentierten Fail-closed-Vertrag und der Coverage-Inventur. **Minimaler Fix:** Explizite, rollen- und periodenbezogene Cashflow-Coverage-Evidenz einführen bzw. vorhandene Source-Coverage auswerten. Ohne bestätigte vollständige Historie müssen TTWROR/XIRR mit `external_cashflow_history_missing` bzw. `cashflow_classification_incomplete` auf `unavailable` stehen. Regressionstest speziell für TrueWealth mit zwei Bewertungen, aber ohne belegte Cashflowhistorie ergänzen. - **P1 – DB erlaubt Drift zwischen auditierter Klassifikation und `accounts.performance_included`.** `src/jarvis_finance/storage/migrations.py:1832-1850` Der Trigger schützt ausschließlich das Setzen auf `1`. Ein klassifiziertes Konto kann direkt auf `performance_included=0` gesetzt werden, während `performance_scope_classifications.included=1` bleibt. Coverage liest die Klassifikation, die kanonische Berechnung validiert zusätzlich das Account-Flag (`src/jarvis_finance/services/portfolio_performance.py:76-84,638-651`). Bei vorhandener Bewertungshistorie endet `/portfolio/performance/coverage` dadurch mit ungefangenem `ValueError` statt einer Matrix. Der Gegenfall – direkte Klassifikationsänderung ohne synchrones Account-Update – ist ebenfalls nicht DB-seitig ausgeschlossen. **Minimaler Fix:** Beide Richtungen DB-seitig atomar koppeln: entweder `accounts.performance_included` nur als triggergepflegte Projektion der Klassifikation behandeln, oder jede Änderung auf `0` **und** `1` nur zulassen, wenn die aktuelle auditierte Klassifikation exakt denselben Wert besitzt. Tests für beide Drift-Richtungen und einen weiterhin erfolgreichen Coverage-Read ergänzen. Keine weiteren P0/P2- oder Testabschwächungs-Findings festgestellt. ## Verifikation - Sprint-14-Backendtests: **24 bestanden** - Relevante Frontendtests: **10 bestanden** - Migrations-/Idempotenz-Gate: **PASS** - Frontend Typecheck und Build: **PASS** - `git diff --check`: **PASS** - Breiter Backend-Testlauf konnte in der verfügbaren Fremd-Venv nicht gesammelt werden: dort fehlen `httpx2` und `pypdf`. - **Keine Dateien geändert oder erstellt.**