## NICHT APPROVED Sprint 2 ist derzeit **nicht statistisch sicher genug für explorative Nutzung**. ### Important Findings 1. **BH-Korrektur verfälscht exakte `p=0` zu `1.0`** `multimodal_correlations.py:318` ```python results[index].p_value or 1.0 ``` SciPy liefert bei perfekter Rangkorrelation bereits ab `n=14` `p_value=0.0`; dieser Wert wird hier zu `1.0`. Dadurch entstehen falsche `q=1`-Ergebnisse. Es muss explizit auf `None` geprüft werden. 2. **Spearman-Inferenz ignoriert Zeitreihenabhängigkeit und diskrete Ties** `multimodal_correlations.py:264` `spearmanr()` behandelt Ties für `rho`, verwendet aber den asymptotischen p-Wert. Bei `n=14–30`, stark diskreten Symptomwerten, serieller Autokorrelation und überlappenden Lags ist dieser p-Wert nicht verlässlich. BH korrigiert nur Multiplizität, nicht die ungültige Nullverteilung. Block-/Shift-Permutation oder eine andere zeitseriengerechte Inferenz ist nötig, bevor `q≤0.10` als Signal bezeichnet wird. 3. **Fehlende YAZIO-Nährwerte werden upstream zu expliziten Nullen** `yazio_nutrition_sync.py:92–99, 137–144, 275–288, 323–352`; anschließend `multimodal_correlations.py:133–152` Fehler beim Produktabruf werden geschluckt; fehlende/ungültige Nährwerte werden durch `fnum()` zu `0.0`. Diese Nullen gelangen als vollständige kcal-, Protein- und Histaminbeobachtungen in die Korrelation. Das verletzt Complete-Case-Semantik und unterscheidet echte Null nicht von „unbekannt“. 4. **Sieben-Dimensionen-Total ist bei Duplikaten nicht eindeutig** `multimodal_correlations.py:113–126` Die Prüfung verlangt sieben unterschiedliche Schlüssel, nicht exakt eine valide Beobachtung je Dimension. Doppelte, widersprüchliche Zeilen werden in nicht spezifizierter Cursor-Reihenfolge überschrieben. Die kanonische `schema.sql` enthält den vom Quick-Add erzeugten Unique-Index nicht. Synthetisch ergaben sieben Nullwerte plus ein doppelter Aphthen-Wert von 3 einen akzeptierten Totalwert `3.0`. 5. **Dashboard zeigt weiterhin unvollständige Symptome als Summenscore** `health_dashboard_v3.py:392–401` Der Chart „Histamin-Load und dokumentierte Symptomtage“ summiert alle geladenen Symptomzeilen, ohne `daily_quick_score`, sieben vollständige Dimensionen oder valide Severity zu verlangen. Unbekannte Severity wird sogar auf `1` gesetzt. Damit widerspricht die Visualisierung der Complete-Case-Engine und kann partielle/Legacy-Tage als beobachteten Totalwert darstellen. 6. **Medikationsstart akzeptiert mehrdeutige Ereignistypen** `multimodal_correlations.py:208–215` Neben eindeutig verabreichten Ereignissen gelten auch die bloßen Typen `dose` und `injection` als tatsächliche Gabe. Synthetisch starteten beide die Behandlungsphase. Ohne strikt kontrolliertes Event-Vokabular beziehungsweise explizites `administered`-Flag kann ein Plan-/Dokumentationseintrag die gesamte Phasenstratifizierung verschieben. 7. **Labor-Duplikate werden willkürlich überschrieben** `multimodal_correlations.py:181–203` Mehrere validierte Werte desselben Parameters, derselben Einheit und desselben Tages werden nach `ORDER BY id` still durch den letzten Wert ersetzt. Synthetisch wurde bei CRP `1.0` und `9.0` ausschließlich `9.0` verwendet. Es fehlt eine definierte Same-Day-Semantik wie Ablehnung, Median oder Zeitstempel-Auswahl. 8. **Reported Missingness zählt strukturell ausgeschlossene Lag-Tage als fehlend** `multimodal_correlations.py:293–310` `eligible_target_days` umfasst alle Ziel-Tage der Phase; `missing_pairs=eligible-n` zählt damit bei Lag `k` auch die ersten `k` Phasentage beziehungsweise Randtage, für die wegen der Phasengrenzen bewusst kein Paar zulässig ist. Im synthetischen Lag-2-Test wurden in jeder Phase zwei solche Tage als „missing“ ausgewiesen. Der Korrelationsjoin selbst war korrekt, die persistierte Missingness nicht. ### Bestandene Prüfpunkte - Positive Lag-Richtung ist korrekt: Prädiktor `d` → Symptom `d+lag`. - Phasengrenzen werden beim Pairing ausgeschlossen. - Explizite Symptom-Nullen bleiben beobachtet. - Mindestgate `n≥14` und mindestens drei unterschiedliche Werte je Achse ist implementiert. - BH-Familienbildung erfolgt wie dokumentiert je Ziel × Phase über berechnete Features/Lags. - Signaltext verlangt formal `q≤0.10` und `n≥30`. - Laborprovenienz, Einheiten-Trennung und Ausschluss zensierter Werte sind konservativ umgesetzt. - Apple-Punkte werden auf `quality=="direct"` gefiltert; produktiv schließt `daily_points()` den laufenden Tag aus. - Resultattabelle persistiert nur Aggregate, keine Tageswerte, Notizen oder Quellnamen. ### Verifikation - Vollständige Suite: **55 passed** - `py_compile`: erfolgreich - `git diff --check`: erfolgreich - Zusätzliche synthetische Prüfungen für Lag-Richtung, Phasengrenzen, BH-Nullwerte, Medikationsereignisse, Symptom-/Labor-Duplikate und Missingness ausgeführt. - Keine Produktionsdaten, Reports oder Secrets gelesen. - **Keine Dateien erstellt oder verändert.**