# Statistical time-series code review

Use this checklist for exploratory health, behavior, finance, or other longitudinal correlation engines. Passing unit tests is not sufficient: reproduce edge semantics with small deterministic probes.

## Review sequence

1. **Trace missingness end to end**
   - Inspect ingestion as well as analysis loaders. Confirm API failures, absent fields, parse failures, and schema defaults do not become numeric zero.
   - Distinguish an explicitly observed zero from unknown/not collected.
   - Verify dashboards and legacy views use the same complete-case definition as the engine.

2. **Audit composite targets**
   - Require exactly one valid observation for every required dimension.
   - Reject or deterministically resolve duplicate/conflicting dimensions; set equality alone is insufficient because dictionary overwrite can hide duplicates.
   - Test complete all-zero, partial, unknown-dimension, duplicate-identical, and duplicate-conflicting days.

3. **Verify temporal pairing and filter scope**
   - State lag direction explicitly: predictor at `d` and outcome at `d + lag`, or the reverse.
   - Construct synthetic shifted series and require the expected lag to recover the association.
   - Prove pairs crossing treatment/regime boundaries are excluded.
   - Define `eligible` after structural lag/boundary exclusions; do not report structurally impossible pairs as missing observations.
   - In interactive explorers, require lag/phase panels to fail closed when the metric selection is empty or unmatched. Never interpret an empty selection as “show every aggregate.”
   - Change period and cadence controls while snapshotting the trend and every aggregate panel. If server-validated lag/phase aggregates are not scoped to those controls, disclose their independent computation scope prominently or hide them; do not let a global “7 days/weekly” state imply that full-history daily aggregates were recomputed for that view.

4. **Validate event semantics**
   - Phase boundaries must use a controlled, affirmative event meaning (for example, actually administered), not ambiguous nouns such as `dose` or `injection` unless the schema contract guarantees their meaning.
   - Test scheduled/planned/cancelled/missed events as negative cases and actual administration as positive.

5. **Review Spearman inference, not only rho**
   - Spearman handles monotonicity and average ranks for ties, but ordinary asymptotic p-values assume independent pairs and can be unreliable in small, heavily tied samples.
   - Longitudinal daily series commonly have serial correlation; overlapping lag tests amplify dependence. Use block/circular-shift permutation, another time-series-aware null, or suppress inferential signal labels.
   - Minimum `n` and unique-value gates prevent degeneracy but do not repair invalid p-values.

6. **Audit Benjamini-Hochberg exactly**
   - Confirm reverse cumulative minima and restoration to original order against known vectors.
   - Preserve valid `p=0.0`; never use `p or 1.0`. Check `None` explicitly.
   - Define the family before computation (for example target × phase across every tested feature and lag) and ensure grouping matches documentation.
   - Verify signal thresholds are machine-readable and consistently presented, not only embedded in prose.

7. **Check sparse laboratory features**
   - Require provenance, exact numeric values, explicit unit, and an actual observation date.
   - Validate dates strictly: accept exact `YYYY-MM-DD` or a fully parseable, explicitly supported ISO-8601 datetime—not merely a valid ten-character date prefix followed by arbitrary text. Probe values such as `2026-01-03 nonsense` and `2026-01-03Tgarbage`; they must be rejected so a malformed specimen date cannot suppress the documented report-date fallback.
   - If specimen-date fallback to report date is supported, document its precedence and test valid specimen, invalid specimen plus valid report, both invalid, and malformed-prefix-plus-suffix cases.
   - Exclude censored/interval values unless a documented censored-data method is used.
   - Group every provenance-valid row for the same allowlisted parameter/unit/day before numeric parsing or censor filtering. An invalid, censored, identical, conflicting, or alias-equivalent duplicate must not disappear before duplicate resolution.
   - Never mix incompatible units. Normalize known equivalents or keep them as separate features.
   - Define same-parameter/unit/day duplicate semantics; arbitrary last-row overwrite is not acceptable.

8. **Check derived platform data quality**
   - Require the intended quality tier and completed/stable days.
   - Verify unit normalization, source deduplication, local-day bucketing, and exclusion of provisional current-day values in the upstream canonical layer.

9. **Verify persistence boundary**
   - Persist aggregate identifiers, sample counts, estimates, uncertainty/multiplicity values, status, and provenance flags only.
   - Assert absence of dates, paired vectors, free text, source filenames/names, raw payloads, and record-level identifiers.

## Deterministic probes worth running

- Perfect monotonic vectors: many libraries return `p=0.0`; ensure BH keeps zero.
- Predictor shifted by +1/+2 days around a phase transition.
- Seven required dimensions plus a conflicting duplicate.
- Nutrition/API row with failed detail lookup and absent nutrients.
- Ambiguous medication events (`scheduled`, `planned`, `dose`, `injection`, `administered`).
- Two validated same-day lab results with the same parameter/unit but different values.

## Final interactive selection/period/event release probe

For Explorer-style dashboards, do not stop after proving only the empty state. Run one synthetic browser session through the complete state transition and record exact rendered counts:

1. Snapshot the initially selected metric IDs and exact Lag, Phase, and detail-row counts.
2. Clear every metric and require exactly `0` Lag rows, `0` Phase rows, and `0` detail cards, with explicit selection guidance in all three panels.
3. Reselect a known preset/metric set and require non-zero, selection-matched counts in all three panels. This catches implementations that fail closed correctly but cannot recover.
4. Change period and cadence while selected. If server aggregates intentionally remain unchanged, require prominent scope copy saying that those controls affect only the client-scoped trend/event/scatter views and that the aggregate date scope is not present in the bundle. Record the before/after counts rather than saying only “unchanged.”
5. Inspect the serialized synthetic bundle and rendered event lane together: report total/validated/computed aggregate counts; confirm explicit lag direction; require event types to contain affirmative administration only; and keep `last_administered` distinct from `next_planned`. Planned/cancelled/missed records may remain in the medication fixture as negative controls but must not enter administered event lanes or phase boundaries.
6. Capture browser console/page-error count. Keep generated fixture, HTML, and ad-hoc probe files outside the repository, stop the temporary server, then rerun `git diff --check` and `git status --short` to prove the review itself did not alter the working tree.

When reporting, lead with `APPROVE` or `CHANGES REQUIRED`, then give the exact `initial → empty → reselected` counts, test totals, contract/event counts, and any files created or modified by the review.

## Approval rule

Return approval only when point estimates, inferential labels, missingness accounting, event phases, persisted/dashboard representations, and the empty-to-reselected interaction transition all obey the same statistical contract. Green synthetic/full tests do not override a demonstrated semantic counterexample.