## Ergebnis des Code-Audits ### Kritische Befunde - Die bestehende Korrelation in `~/.hermes/assets/Gesundheit/scripts/nutrition_insights.py:249–278` ist für Sprint 2 **nicht sicher wiederverwendbar**: - fehlende Symptomtage werden mit `0.0` imputiert (`symptoms.get(..., 0.0)`), - Pearson ohne p-Wert, Konfidenzintervall oder Multiple-Testing-Korrektur, - keine Medikations-/Zeittrend-/Wochentag-Stratifizierung, - `n` entspricht Ernährungstagen, nicht tatsächlich vollständig beobachteten Paaren. - Food-Insights und Phasenmittelwerte wiederholen dieselbe Missing-as-zero-Problematik (`nutrition_insights.py:299–314, 341–367`). - Das Dashboard bildet den Nutrition-Symptom-Chart nur aus `symptome`, während die Quick-Logs in `symptom_log` liegen (`health_dashboard_v3.py:382–392`). Tabelle und Chart können daher unterschiedliche Resultate zeigen. - `health_manager.py:332–370` ist Legacy-Code: falsches Labordatum (`ermittlung_datum`), unvalidierte Werte, Pearson-Pivot und keine Provenienzprüfung. **Nicht erweitern.** - Nutrition-Makros sind noch nicht als statistisch belastbar dokumentiert: `yazio_nutrition_sync.py:108–118` weist selbst auf einen ausstehenden YAZIO-Einheiten-Audit hin. `fnum()` wandelt fehlende/ungültige Werte zudem in Null um. - Aktuelle Medikationsphasen beruhen nur auf dem ersten Hyrimoz-Datum und einer festen 56-Tage-Grenze; Stopps, Neustarts, Dosiswechsel und Washout werden nicht modelliert. - Laborwerte sind sparse Events, keine täglichen Features. Forward-Fill wäre medizinisch und statistisch unzulässig. ## Empfohlener täglicher Feature-Vertrag Gemeinsamer Schlüssel: `Europe/Zurich`-Lokaltag, ausschließlich abgeschlossene Tage. Jeder Wert benötigt mindestens: ```text day, feature_id, value, unit, observed, quality, source_contract, medication_phase ``` - **Apple Health:** ausschließlich `apple_health_analytics.daily_points(...)`, `stable_only=True`, `quality="direct"`. Coarse-Fallback ausschließen; Source-/Unit-Konflikte und naive Zeitzonen mindestens als Quality-Flags führen. Keine Rohzeilen summieren. - **Nutrition:** aus `nutrition_daily_summary_v2`; Tag nur beobachtet bei `item_count > 0`. Fehlender Nährstoffschlüssel bleibt `NA`, niemals `0`. Histamin nur zusammen mit `histamine_unknown_count` bzw. Unknown-Anteil. kcal/Makros bis zum Einheiten-Audit als `experimental_unit_unverified`. - **Symptome:** primär genau sieben `daily_quick_score`-Dimensionen aus `symptom_log`, jeweils 0–3. Tages-Total nur bei vollständigen sieben Dimensionen. Ein expliziter Nulltag ist beobachtet; ein fehlender Tag ist `NA`. Legacy-`symptome` separat halten, nicht addieren. - **Medikation:** Tagesphase als kategorialer Confounder, nicht als kontinuierlicher Effekt: `baseline_pre_treatment`, `early_treatment`, `stable_treatment`, optional `washout/unknown`. Lags dürfen keine Phasengrenze überschreiten. - **Labore:** nur `validierungsstatus='validiert'`, `verified_against_original=1`, `reference_range_source='scanned_original'`, exaktes numerisches `wert`, nichtleere Einheit und `abnahme_datum` (Fallback höchstens `befund_datum`). Zensierte Werte wie `<3` nicht numerisch umdeuten. Kein Daily-Forward-Fill; stattdessen Laborevent mit vorher definierten 3/7/14-Tage-Expositionsfenstern. ## Mindestregeln - Berechnung ausschließlich als Complete-Case-Paare. - `n < 14`: nur `insufficient_n`, kein Korrelationswert zur Interpretation. - `14 ≤ n < 30`: rein explorativer Effekt, keine inferenzielle Aussage. - Belastbarere p/q-Ausgabe erst ab `n ≥ 30`; adjustierte Modelle erst ab mindestens 10 Beobachtungen pro Parameter. - Pro Phase separat mindestens 14 Paare und ausreichende Varianz; konstante oder nahezu konstante Serien ablehnen. - Maximal 40 % Missingness im definierten Analysefenster; Ziel-Coverage mindestens 60 %. - Keine Lags über Medikationsphasen, Datenlücken oder provisorische Tage. - Vorab festgelegte Lags, z. B. Nutrition/Apple → Symptome `0–3 Tage`; Labore nur über fest definierte Rückblickfenster. - Confounder mindestens: Medikationsphase, Kalendertrend und Wochentag. Schlaf/Aktivität nur kontrollieren, wenn fachlich Confounder und nicht Mediator. - Ergebnisse immer als Assoziation/Hypothese kennzeichnen; niemals Trigger, Wirkung oder Kausalität behaupten. ## Statistik - Primär **Spearman-Rangkorrelation** wegen ordinaler Symptome, Ausreißern und nichtnormalen Health-Daten. - Phasenstratifizierte Complete-Case-Analyse. - Benjamini-Hochberg-FDR innerhalb einer klar definierten Testfamilie aus Predictor × Target × Lag × Phase. - Für inferenzielle Ergebnisse bevorzugt 7-Tage-Block-Bootstrap/-Permutation wegen serieller Autokorrelation; klassische iid-Spearman-p-Werte allein reichen nicht. - Effekt, `n`, eligible target days, missing pairs, CI, p, q und Quality-Flags ausgeben. - Keine automatisierte Selektion nur anhand `|rho|`; vorab definierte Featurefamilien und Lags verwenden. ## Exakte Integrationspunkte 1. Neue Engine neben Analytics v2: - `scripts/health/multimodal_correlations.py` - produktiv gespiegelt nach `~/.hermes/assets/Gesundheit/scripts/`. 2. Schema: - neue aggregierte Tabelle `multimodal_correlation_results`, - DDL in `database/schema.sql`, - idempotente Migration in `scripts/health/health_system_migrate.py`, - danach `database/schema_manifest.json` aktualisieren. - Keine Rohwerte, Datumslisten, Source-Namen oder Patiententexte speichern. 3. CLI: - `health_pipeline.py correlations` für Berechnung/Upsert, - `dashboard` liest ausschließlich persistierte Aggregate. 4. Refresh: - nach erfolgreichem YAZIO-/Symptom-/Apple-Sync zuerst Korrelationen, danach Dashboard; - still bleiben, wenn Inputs/Fingerprint unverändert sind. 5. Dashboard: - neue Tabelle im bestehenden Abschnitt `Charts & Korrelationen`, - Status, `n`, Missingness, Phase, rho/CI/q und Safety-Text anzeigen, - bisherige unsichere `nutrition_correlation_results` nicht mit Sprint-2-Ergebnissen vermischen. 6. Labore: - ausschließlich DB-Provenienzpfad; nicht `parse_reference_xlsx()` oder Legacy-`HealthManager.compute_correlations()` verwenden. ## Tests Ein bereits vorhandenes, unversioniertes `tests/test_multimodal_correlations_v1.py` beschreibt sinnvolle erste Verträge: - Missing-Symptomtage bleiben fehlend. - Explizite Nulltage gelten als beobachtet. - Spearman und keine Kausalitätsbehauptung. - Medikationsphasen werden getrennt; Lags überschreiten keine Grenze. - Labore benötigen strikte Provenienz, exakte Zahl und Einheit. - Apple akzeptiert nur direkte, abgeschlossene Punkte. - Benjamini-Hochberg ist monoton und `q ≥ p`. - Persistenz enthält nur Aggregate. Zusätzlich erforderlich: - sieben Symptomdimensionen vollständig/unvollständig, - keine Doppelzählung `symptome` + `symptom_log`, - Nutrition-NA statt Null und Unknown-Anteil, - Source-/Unit-Konflikte bei Apple, - provisorischer aktueller Tag, - Restart/Stop/Dosiswechsel/Washout der Medikation, - Laborduplikate und widersprüchliche Einheiten, - keine Forward-Fills und keine censored-value-Umdeutung, - konstante Serien, Missingness-/Varianz-/n-Gates, - FDR-Familiengrenzen und Block-Bootstrap, - Dashboard-Safety-Copy und kein Rohdaten-Leak. ## Verifikation / Änderungen - Bestehende Suite ausgeführt: **40 Tests bestanden**; **8 erwartete Fehler**, da `scripts/health/multimodal_correlations.py` noch fehlt. - Repo- und Runtime-Versionen von Apple Analytics, Pipeline und Dashboard sind hashgleich. - **Keine Dateien erstellt oder verändert.** - `tests/test_multimodal_correlations_v1.py` war während des Audits als fremdes/unversioniertes Concurrent-Artefakt vorhanden; nicht von mir angelegt oder bearbeitet.