## Schlussverdikt: **BLOCK / NICHT SHIP** **P0: 0 · P1: 4 · P2: 1** ### P0 Keine P0-Befunde. ### P1 1. **Bankquelle, Kontorolle und Währung werden nicht fachlich validiert** - `src/jarvis_finance/services/truewealth_productization.py:96-113, 216-229, 338-369` - Kandidaten werden allein über `lower(a.name) LIKE '%raiffeisen%'` ausgewählt. Kontotyp, stabile Quellen-/Kontozuordnung und unterstützte Währung werden nicht geprüft. - Synthetisch reproduziert: - Ein als `credit_card` typisiertes Konto mit „Raiffeisen“ im Anzeigenamen ergab `secure=1`, `can_confirm=True`. - Eine USD-Zahlung ergab ebenfalls `can_confirm=True` und könnte als partieller True-Wealth-Deposit bestätigt werden. - **Auswirkung:** Fremde oder semantisch inkompatible Belastungen können als externe Portfolioeinzahlungen materialisiert werden. - **Fix:** Stabile Source-/Account-ID verwenden; Cash-/Checking-Rolle, aktive Verknüpfung, Ownership, CHF beziehungsweise vollständig kanonisierten FX-Betrag serverseitig und erneut unter Confirm-Lock fail-closed validieren. 2. **True-Wealth-Tageslauf ist innerhalb der Quelle nicht atomar** - `src/jarvis_finance/cli/main.py:196-227` - `src/jarvis_finance/services/truewealth_productization.py:570-603` - `src/jarvis_finance/services/truewealth_valuation.py:317-354` - Cashflow-Automation und Modellbewertung committen jeweils intern. Scheitert die Bewertung nach erfolgreicher Cashflow-Automation, kann `with_source_connection()` den bereits bestätigten Cashflow nicht zurückrollen. - Synthetischer Probe: Nach erfolgreicher Automation und anschließendem äußerem `rollback()` blieb der neue Cashflow persistiert (`persisted_after_outer_rollback=1`). - **Auswirkung:** Ein als fehlgeschlagen gemeldeter Quellenlauf kann Teilwrites hinterlassen. - **Fix:** Transaktionsownership in den Source-Orchestrator ziehen; Cashflow und Bewertung ohne interne Commits innerhalb einer gemeinsamen `BEGIN IMMEDIATE`-Transaktion ausführen oder explizit als getrennte, unabhängig terminal protokollierte Jobs modellieren. 3. **Preview und Audit persistieren rohe Finanz- und Identitätsdaten** - `src/jarvis_finance/services/truewealth_productization.py:216-226, 431-439` - API-Preview und Confirm-Audit enthalten unter anderem `booking_text`, `recipient_identity`, `raiffeisen_account` und `raw_fingerprint`; zusätzlich wird die vollständige Regel einschließlich Attestation gespeichert. - **Auswirkung:** Rohbuchungstext und Gegenparteiinformationen werden unnötig über den Diagnosevertrag und dauerhaft im Audit repliziert. - **Fix:** Öffentlich nur opaque Detection-IDs, Datum, Betrag/Währung, Status und Reason-Codes ausgeben. Im Audit ausschließlich redaktierte Aggregate, Regel-Fingerprint und opaque Lineage-IDs speichern. 4. **Ökonomische Dedupe-Kollisionen sind blockierend, aber nicht entscheidbar** - `src/jarvis_finance/services/truewealth_productization.py:248-268, 287-334` - Gleicher Tag/Betrag/Währung ohne exakte Lineage wird korrekt unsicher; es existiert jedoch kein fingerprint-gebundener `link_existing`-/`record_distinct`-Entscheidungsvertrag. - **Auswirkung:** Ein legitimer zweiter Transfer im gleichen wirtschaftlichen Schlüssel blockiert die gesamte Preview dauerhaft. - **Fix:** Explizite, auditierte und fingerprint-gebundene Kollisionsentscheidungen in Preview-, Confirm- und API-Schema ergänzen; beide Pfade adversarial testen. ### P2 1. **Confirmation-/Activation-ID ist bei Konkurrenz nicht eindeutig abgesichert** - `src/jarvis_finance/services/truewealth_productization.py:398-447, 456-494` - Der Idempotenzcheck erfolgt vor `BEGIN IMMEDIATE`; danach wird der bestehende Auditdatensatz nicht erneut geprüft. Für `(source, action, entity_id)` ist hier keine transaktional erzwungene Eindeutigkeit sichtbar. - **Auswirkung:** Zwei konkurrierende Requests können zwar dank stabiler Transaction-ID keine doppelte Finanzbuchung erzeugen, aber doppelte Audits beziehungsweise einen zweiten nicht-idempotenten Erfolg produzieren. - **Fix:** Idempotenzprüfung unter Write-Lock wiederholen und eindeutigen Confirmation-Payload-Datensatz beziehungsweise Unique Constraint verwenden. ### Verifikation - Neue Sprint-20D-Tests: **23 passed** - Betroffene Performance-/Activation-Regressionen: **61 passed** - Python-Compile-Gate: grün - `git diff --check`: grün - Keine Produktionsdatenbank geöffnet. - Keine Dateien erstellt oder verändert.