# Architecture overview (Phase 1, 2026-11-02) ``` ┌──────────────────────────── Python (nanobind, GIL released) ────────────────────────────┐ │ raid.api: ols · realized_measures · garch_fit · validate_bars · calendar_sessions · … │ └───────────────────────────────────────┬────────────────────────────────────────────────┘ CLI `raid` ──────────────────────────────────────────┤ ▼ ┌─────────────── core ───────────────┐ ┌───────────── data ─────────────┐ ┌──────── statistics / estimators / models ────────┐ │ types (Timestamp µs UTC, Date, │ │ MarketCalendar (XNYS rules, │ │ reductions (Neumaier, pairwise, Welford) │ │ Interval, Backend, Precision) │ │ DST, early closes, 391/211 bars)│ │ rolling (sum/mean/var/cov/corr, re-summation) │ │ error (RaidError + codes) │ │ BarSeries (columnar OHLCV + │ │ covariance (classical, HC0–3, HAC, cluster) │ │ log (structured, redaction) │ │ session index, QualityReport) │ │ ols (QR/SVD/ridge/WLS, sufficient stats, rolling) │ │ rng (xoshiro256++ streams) │ │ returns (session-aware), resample│ │ realized (RV, BPV, RSV±, RQ, J, TriPV, RCov) │ │ thread_pool, hash (SHA-256) │ │ io: CSV fixtures, Parquet/Arrow │ │ models/garch (GARCH/GJR/EGARCH, N/t, QML, forecasts)│ │ estimate / plan / manifest │ │ findata client (Phase 2) │ │ har, bootstrap (Phase 4) │ └────────────────────────────────────┘ └────────────────────────────────┘ └───────────────────────┬──────────────────────────┘ ▼ ┌───────────── backend::Backend (batched primitives over CSR panels) ─────────────┐ │ sum_squares · sum_abs_adjacent · semivariances · sum_fourth · rolling_sum_squares │ │ regression_stats (X'X, X'y, y'y) · garch_nll_batch │ ├───────────────────────────────┬───────────────────────────────────────────────────┤ │ CpuBackend (FP64, threads) │ MetalBackend (FP32 + compensation, Phase 3) │ └───────────────────────────────┴───────────────────────────────────────────────────┘ ``` Design rules (from the charter, enforced in code): - **FP64 reference first.** Every primitive has a CPU FP64 implementation; the Metal backend must match it within the method's documented tolerance or report `precision=fp32` with a warning — never silently. - **Estimators are backend-independent.** They consume `backend::Backend` through `resolve(plan)`; the plan decides `auto|cpu|metal`, determinism, threads, chunking and fallback. `Estimate` always carries backend, precision, convergence, warnings, runtime and provenance. - **No silent data manufacturing.** `BarSeries` never forward-fills; `QualityReport` counts what is missing/invalid; returns are computed within sessions only; the 16:00 closing print is part of the regular session (391 bars). - **CSR panels.** Batched kernels take `values + offsets`; ragged panels (different session lengths, delisted series) are first-class; rectangular panels get a dense view for linear algebra. - **Provenance.** Inputs are hashed (SHA-256), FinData dataset versions and request IDs are kept, manifests record host, compiler and plan; `Estimate::to_json()` is the interchange format for Python, CLI and experiment records. - **Failure is explicit.** `Estimate::ok()` requires convergence; optimisers report iterations, evaluations, gradient norm and a message; rank deficiency and ill-conditioning raise warnings; invalid parameters give +inf likelihood. Threading: a global `ThreadPool` (hardware concurrency or `RAID_THREADS`) with `parallel_for` over series; the calling thread helps; exceptions propagate. Determinism: per-series Neumaier sums have a fixed order, so CPU results are bitwise reproducible across thread counts (tested).