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