# Sichere explorative multimodale Korrelationsanalysen

## Zweck

Workflow für Tageskorrelationen zwischen Wearables, Ernährung, strukturierten Symptomen, Medikation und validierten Laborwerten. Resultate sind ausschließlich Hypothesen für Verlaufskontrolle und Arztgespräche — keine Diagnose, Kausalitätsaussage, Therapieempfehlung oder Entwarnung.

## Feature-Verträge

- **Symptome:** Tages-Total nur, wenn alle festgelegten Dimensionen exakt einmal und im exakten 0–3-Vertrag dokumentiert sind. Fehlend bleibt unbekannt. Ungültige, identische oder widersprüchliche Duplikate machen den Tag unvollständig; alle Quellzeilen vor dem Parsen zählen.
- **Ernährung:** Tageswert nur bei mindestens einem Item und ohne unbekannte Produktklassifikation. Upstream-Nullen nie ungeprüft als echte Null übernehmen.
- **Apple Health:** Nur kanonische direkte Tagespunkte aus der qualitätsgesicherten Analytics-Schicht; keine provisorischen/fallback-basierten Tage stillschweigend mischen.
- **Medikation:** Phasen nur aus explizit verabreichten Dosen. Stopps, Pausen, Neustarts oder Dosiswechsel führen ohne belastbares Intervallmodell konservativ zu `unknown`.
- **Labor:** Nur gegen Original validierte Datensätze aus technischer Parameter-/Einheiten-Allowlist. Alle provenance-validen Same-Day-Zeilen zuerst gruppieren, erst danach Numerik/Zensierung prüfen; ein numerischer plus ein zensierter Datensatz schließt den Feature-Tag aus. Gültiges Abnahmedatum bevorzugen, nur bei fehlendem/ungültigem Abnahmedatum ein gültiges Befunddatum verwenden. Datumsparser fail-closed: nur exaktes `YYYY-MM-DD` oder vollständig parsebare, explizit unterstützte ISO-8601-Datetimes akzeptieren; Präfixe mit beliebigem Suffix (`2026-01-03 nonsense`) und implizit von Standardbibliotheken akzeptierte Kompaktformen separat regressionsprüfen. Persistierte IDs enthalten keinen Freitext oder Quellnamen.

## Statistik

1. Complete-case-Paare einschließlich tatsächlichem Pair-Datum bilden; nie imputieren.
2. Lag-Richtung explizit: Prädiktor an `d`, Ziel an `d + lag`.
3. Keine Paare über Medikationsphasengrenzen; strukturelle Lag-Randtage nicht als Missingness zählen.
4. Zielabdeckung separat von Prädiktor-Missingness messen und Mindestabdeckung erzwingen. Auch Kombinationen mit `n=0` als unzureichend dokumentieren statt unterdrücken.
5. Rangkorrelation verwenden, aber iid-asymptotische p-Werte bei seriell abhängigen Tagesdaten vermeiden.
6. Kalenderbasierte Blockpermutation: feste Kalenderwochen, Reihenfolge innerhalb jeder Woche erhalten und jede beobachtete Teilwoche vollständig mitpermutieren. Nie sieben vorhandene Beobachtungen mit sieben Kalendertagen verwechseln; einen Restblock nicht unbeweglich fixieren.
7. `p=0.0` bei BH explizit von `None` unterscheiden — niemals `p or 1.0`.
8. BH je Ziel und Behandlungsphase über alle gültigen Features/Lags; Mindestpaarzahl, Varianz- und Signal-Gates erzwingen.
9. Rest-Confounding, Autokorrelation, Selektionsbias und Messfehler immer als Grenzen nennen.

## Dashboard und Legacy-Sicherheit

- Beide Diagrammtypen auf vollständigen Kalenderachsen aufbauen; vollständig fehlende Tage und unbekannte Histamintage als `null` darstellen. Prüfen, dass JS/Chart-Code `null` nicht in `0` wandelt. Nicht nur den Achsen-Helper testen: den tatsächlichen Renderer mit Daten an Tag 1 und Tag 3 ausführen und verifizieren, dass Tag 2 als `null` gerendert wird und kein direkter Map-Zugriff einen `KeyError` auslöst.
- Für Dashboard und Engine denselben strikten Symptomvertrag verwenden.
- Unsichere Missing-as-zero-Legacy-Engines weder starten noch deren Safe-/Trigger-, Phasen- oder Empfehlungsresultate anzeigen.
- Partielle CLI-Eingaben als `partial_sum`, `complete=false`, `unspecified=unknown`, nie als Tages-Total.

## Persistenz und Datenschutz

- Nur Aggregate speichern: technische IDs, Lag, Phase, n/Coverage/Missingness, rho/p/q, Status, feste Flags/Interpretation und Zeitstempel.
- Vor `DELETE` oder Schreiben Prädiktor, Ziel, Phase, Status, Methode, Flags und Interpretation allowlisten. Zusätzlich Zähler als nichtnegative Integer, `n ≤ eligible ≤ expected`, `missing = eligible - n`, Coverage als endlichen konsistenten Quotienten sowie `rho ∈ [-1,1]` und `p/q ∈ [0,1]` prüfen. `NaN`, `Inf`, Bool-as-Integer und statuswidrige Inferenzen ablehnen. Erst den gesamten Batch validieren, dann bestehende Resultate löschen; nicht nur dem aktuellen Aufrufer vertrauen.
- Einen Positivtest behalten, der echte `compute_results()`-Ausgabe durch dieselbe strikte Persistenzgrenze speichert, damit Defense-in-depth nicht den legitimen Pfad blockiert.
- Keine Tagesvektoren, Datumslisten, Notizen, Dateinamen oder Quellnamen persistieren.

## Migration und Legacy-Duplikate

- Additiv, idempotent und mit lokaler Sicherung migrieren.
- Unique Index nur bei duplikatfreiem Bestand; Duplikate niemals automatisch löschen oder zusammenführen.
- Quick-Logging muss trotz Legacy-Duplikaten für andere Tage funktionieren. Beim betroffenen Tag sicher abbrechen, ohne bestehende Zeilen zu überschreiben.

## TDD-/Review-Matrix

Regressionen mindestens für:

- explizite Null, vollständig fehlend und partial;
- duplicate-identical, duplicate-conflicting, duplicate-invalid und dezimale/out-of-contract Symptome;
- unbekannte Ernährungsklassifikation;
- numerisches plus zensiertes Same-Day-Labor-Duplikat;
- ungültiges/unmögliches Datum und dokumentierter Befunddatum-Fallback;
- every-other-day Pair-Daten, Ties, Determinismus und vollständig mitpermutierte Teilwochen;
- BH mit `0.0` und `None`;
- `n=0`, Coverage-Gate und Phasengrenzen;
- Freitext-/Source-Prädiktor an der Persistenzgrenze, ohne bestehende sichere Resultate zu löschen;
- vollständige Kalenderachsen mit `null`-Gap-Slots;
- Migration zweimal auf altem und aktuellem Schema sowie Quick-Log mit Legacy-Duplikaten.

Danach vollständige Tests, Lint, Compile, Diff-Check, DB-Integrität, Foreign Keys, Runtime-Dateihashes und ausgeliefertes Dashboard per HTTP prüfen. Unabhängigen Statistik- und Medical-Safety/Privacy-Review nach den letzten Änderungen erneut durchführen; ein älterer Snapshot ist keine finale Freigabe.
