## BLOCK ### P1 – Provenienz ist nicht vollständig fail-closed In `src/jarvis_finance/services/performance_activation.py:83-109` akzeptiert die Aggregation unvollständige Preiszeilen: - `COUNT(*)` zählt auch Rows ohne `provider_timestamp`. - `MIN(provider_timestamp)` ignoriert `NULL`. - Dadurch reichen bei zwei gebundenen Rows eine vollständige und eine unvollständige Row aus, um weiterhin Provider, Währung, FX-Provenienz und `price_as_of` auszugeben. Deterministische Gegenprobe nach einem vollständigen Run: ```text missing_timestamp { 'price_as_of': '2026-08-03T19:55:00+00:00', 'price_provider': 'CoinGecko', 'price_currency': 'CHF', 'fx_provider': 'Direkte CHF-Notierung (kein FX-Lauf)' } ``` Erwartet wäre für die unvollständige gebundene Row ein fail-closed Ergebnis mit `null`-Provenienz. Zusätzlich wird Provider nicht ausschließlich aus allen an den Run gebundenen Rows abgeleitet, da die Abfrage vor der Aggregation auf `provider='CoinGecko'` filtert. Eine Gegenprobe mit zwei konsistent an den Run gebundenen `AlternateProvider`-Rows lieferte vollständig `null`, statt den tatsächlich gespeicherten konsistenten Provider abzuleiten. Der Filter macht zudem `MIN(provider) == MAX(provider)` für die berücksichtigten Rows tautologisch. **Erforderliche Korrektur:** Alle über `fetched_at = last_complete.started_at` gebundenen Rows aggregieren und Vollständigkeit explizit prüfen, einschließlich Anzahl nichtleerer Provider-, Währungs- und Provider-Timestamp-Werte. Erst danach Provider/Währung/CHF-Direktprovenienz freigeben. Gegenproben für fehlende Rows, `NULL provider_timestamp`, gemischte Provider und gemischte Währungen ergänzen. ### P0 / P2 - **P0:** keine. - **P2:** keine separaten Findings; die fehlenden negativen Tests sind Teil des P1-Release-Gates. ### Verifikation - Basis und `HEAD`: exakt `1c073e9c4f2f7a3697326a48101bb7027aea052d`; Hotfix liegt als Working-Tree-Diff mit 7 geänderten Dateien vor. - `git diff --check`: erfolgreich. - Sprint-20E-Fokustests: **23 passed**. - Frontend-Fokustests: **23 passed**. - `npm run typecheck`: erfolgreich. - Pydantic-Strict-Contract direkt validiert; neue Felder sind im API- und TS-Vertrag erforderlich und nullable. - Bestehender HTTP-Endpunkttest war lokal nicht ausführbar, weil die venv das von Starlette verlangte Paket `httpx2` nicht enthält. - Read-only eingehalten; keine Dateien erstellt oder verändert.