## NICHT APPROVED Keine Critical Findings, aber **vier Important Findings** im aktuellen Arbeitsbaum. ### Important Findings 1. **Die „7-Tage“-Blockpermutation verwendet Beobachtungsblöcke statt Kalendertage und permutiert den Restblock nicht** - **Datei:** `scripts/health/multimodal_correlations.py:296-324`, Aufruf ohne Datumsvektor in `:424-445` - Nach Complete-case-Filterung bestehen `xs`/`ys` nur noch aus vorhandenen Paaren. Je sieben solcher Beobachtungen werden als „7-Tage“-Block behandelt, auch wenn sie wegen Missingness über deutlich mehr als sieben Kalendertage verteilt sind. - Bei `n % 7 != 0` wird der Restblock unverändert ans Ende angehängt (`:301`, `:321`). Synthetischer Check für `n=15`: Der letzte Wert blieb in **jeder** Permutation an derselben Position. - Damit entspricht der inferenzielle p-Wert nicht zuverlässig der dokumentierten kalenderbasierten 7-Tage-Nullverteilung. - **Fix:** Paar-Daten einschließlich Outcome-Datum an die Permutationsroutine übergeben, nach festen Kalender-7-Tage-Fenstern blockieren und den letzten Teilblock in die Permutation einbeziehen. Alternativ eine dokumentierte kalenderbewusste Circular-shift-Null verwenden. Tests mit lückenhaften/every-other-day Complete Cases und `n=15/20` ergänzen. 2. **Symptomduplikate können durch einen ungültigen zweiten Wert verborgen werden** - **Datei:** `scripts/health/multimodal_correlations.py:130-147` - Duplikate werden erst **nach** erfolgreichem `_severity`-Parsing gezählt. Ein vollständiger Tag plus zweite Zeile derselben Dimension mit `schwergrad='unbekannt'` wurde synthetisch weiterhin als vollständiger Total-Score `0.0` akzeptiert. - Zusätzlich ist `_severity` in `:118-127` nicht strikt 0–3: Der Regex kann beispielsweise `3.5` als `3` interpretieren. - **Fix:** Zunächst alle Zeilen je bekanntem `(Tag, Dimension)` zählen; nur bei exakt einer Zeile weiterarbeiten. Danach den Wert gegen ein streng kontrolliertes 0–3-Format bzw. die bekannten CLI-Labels validieren. Regressionen für duplicate-invalid, duplicate-identical, duplicate-conflicting und dezimale/out-of-contract Werte ergänzen. 3. **Zensierte Same-Day-Laborduplikate werden vor der Duplikatprüfung entfernt** - **Datei:** `scripts/health/multimodal_correlations.py:226-242` - Die exakte numerische Prüfung erfolgt vor der Gruppierung. Synthetisch wurden für denselben allowlist-basierten Parameter/Einheit/Tag die Werte `1.2` und `<3.0` verarbeitet; `<3.0` wurde verworfen und `1.2` anschließend als eindeutiger Laborwert akzeptiert. - Das verletzt den dokumentierten Vertrag, nach dem zensierte bzw. widersprüchliche Same-Day-Duplikate den Feature-Tag ausschließen. - **Fix:** Zuerst sämtliche provenance-geprüften, allowlist-gemappten Datensätze nach `(safe_feature, day)` gruppieren. Nur Gruppen mit exakt **einem** Quelldatensatz akzeptieren und erst danach dessen Wert auf exakte Numerik prüfen. Regression für „ein exakt numerischer + ein zensierter Datensatz“ ergänzen. 4. **Labordaten akzeptieren ungültige Beobachtungsdaten und können den gesamten Lauf abbrechen** - **Datei:** `scripts/health/multimodal_correlations.py:217-239`; Folgefehler in `:105-106` und `:406` - Es wird nur auf `IS NOT NULL` geprüft und anschließend blind auf zehn Zeichen gekürzt. Ein streng provenance-geprüfter CRP-Wert mit `abnahme_datum='not-a-date'` wurde als `{'not-a-date': 1.2}` geladen. - Sobald ein Ziel vorhanden ist, führt `_day_add()`/`date.fromisoformat()` zu einem Laufabbruch. - `COALESCE(abnahme_datum,befund_datum)` bevorzugt außerdem eine leere oder ungültige Abnahmedatum-Zeichenfolge gegenüber einem möglichen gültigen Befunddatum. - **Fix:** Datum vor Aufnahme strikt als ISO-Kalendertag validieren und kanonisieren; ungültige/mehrdeutige Zeilen konservativ ausschließen. Für den Fallback eine explizite, dokumentierte Abnahme-/Befunddatum-Regel verwenden. Tests für leeres, ungültiges und unmögliches Datum ergänzen. ### Zusätzliche Missingness-Lücke - **Datei:** `scripts/health/multimodal_correlations.py:422-445` - `if not xs: continue` unterdrückt Kombinationen mit `n=0` vollständig. Dadurch werden `missing_pairs`, Ziel-Coverage und `insufficient_n`/`insufficient_coverage` für vollständig fehlende Prädiktorpaare nicht persistiert. - **Fix:** Auch leere Paarvektoren an `_result_for_pairs()` übergeben; die vorhandene Statuslogik kann `n=0` bereits als unzureichend klassifizieren. ### Erfolgreich verifiziert - Vollständige Suite: **65 passed** - Fokussierte Sprint-2-Tests erneut: **21 passed** - AST-Parsing: **OK** - Kanonisches Schema in SQLite `:memory:`: **OK**, 42 Tabellen - `git diff --check`: **sauber** - BH erhält `p=0.0`; `None` wird vor der gruppierten Korrektur ausgeschlossen. - BH-Gruppierung erfolgt je `(target, medication_phase)`. - Schwelle `target_coverage >= 60 %`, strukturelle Lag-/Phasengrenzen, explizite `administered`/`verabreicht`-Ereignisse und konservative disruptive Ereignisse sind im geprüften Pfad vorhanden. - Histamin-Tage erfordern `item_count > 0` und `histamine_unknown_count == 0`. - Persistenzschema enthält nur aggregierte Resultatfelder; keine Tagesvektoren, Datumslisten oder Quellnamen. **Geänderte/erstellte Dateien:** keine. **Produktionsdaten, Reports und Secrets:** nicht gelesen oder verändert.