Catchment data contract is now uniform: every catchment must ship <name>_Observations.csv (including the T temperature column), <name>_CemaNeigeInfo.csv, and projection files; data.py enforces this once at load time and consumers no longer carry per-feature fallbacks
get_available_catchments returns (name, period) 2-tuples — the has_snow flag is gone since every remaining catchment supports snow
Tightened typing across api/, data.py, logging.py, and models/: removed 14 stale # type: ignore comments, narrowed LazyFrame.collect() returns with assert isinstance(..., pl.DataFrame), and replaced a typing.cast in projection.py
Leaf catchment dataset (src/holmes/data/Leaf_Observations.csv) and all the scaffolding it required (snow-model auto-reset, snowConfigView greying-out path in the frontend, and per-handler ColumnNotFoundError fallbacks for the missing T column)
HolmesFileNotFoundError exception and the WebSocket not_found_error branch — missing catchment data now flows through the regular error channel
read_cemaneige_info and read_projection_data no longer special-case missing files
RemoveCalibration in simulation.js now clears holmes--simulation--start, holmes--simulation--end, and holmes--simulation--multimodel from localStorage when all calibrations are removed, so the persisted state matches the in-memory reset
WAGENINGEN hydrological model (8-parameter HOOPLA HM19 port of the Warmerdam et al. 1997 model with threshold-based soil-moisture production, capillary rise, cosine ET envelope, fast/slow flow dissociation via the x5 threshold, and fractional-delay routing) support in model registry, config, and simulation dispatching
TANK hydrological model (7-parameter Perrin variant of the Sugawara 1979 cascade of four linear reservoirs S→R→T→L with dual-threshold side-outlets on the surface store, geometric drain-time scaling, cascading ET satisfaction, and fractional-delay routing) support in model registry, config, and simulation dispatching
MORDOR hydrological model (6-parameter Garçon 1999 formulation with four cascading reservoirs U→L→Z→N, proportional rainfall partitioning, nonlinear cubic groundwater discharge, and three-component double-sided UH2 routing with exponent 2.5) support in model registry, config, and simulation dispatching
MARTINE hydrological model (7-parameter Perrin variant of the Mazenc et al. 1984 BRGM model with overflow production, quadratic direct routing, dual-pathway intermediate reservoir, and linear groundwater recession) support in model registry, config, and simulation dispatching
CREC hydrological model support in model registry, config, and simulation dispatching
CREC model documentation page with mathematical formulation, 6-parameter description, and model comparison table update
GARDENIA hydrological model support in model registry, config, and simulation dispatching
HYMOD hydrological model support in model registry, config, and simulation dispatching
HBV hydrological model (9-parameter Bergström/Forsman HBV0 variant) support in model registry, config, and simulation dispatching
XINANJIANG hydrological model (8-parameter Perrin variant of the Zhao et al. 1980 saturation-excess model) support in model registry, config, and simulation dispatching
SACRAMENTO hydrological model (9-parameter Perrin variant of the Burnash et al. 1973 NWSRFS model) support in model registry, config, and simulation dispatching
IHACRES hydrological model (7-parameter Perrin variant of the Jakeman et al. 1990 model with PET-modulated drying constant and parallel fast/slow linear routing) support in model registry, config, and simulation dispatching
TOPMODEL hydrological model (7-parameter Perrin variant of the Beven & Kirkby 1979 model with sigmoid recharge/ET partitioning, exponential groundwater store, and quadratic surface routing) support in model registry, config, and simulation dispatching
NAM hydrological model (10-parameter HOOPLA HM12 port of the Nielsen & Hansen 1973 Nedbør-Afstrømnings-Model with seven reservoirs and a fractional-delay unit hydrograph) support in model registry, config, and simulation dispatching
PDM hydrological model (8-parameter HOOPLA HM13 port of the Moore & Clarke 1981 Probability-Distributed Model with Pareto soil store, cubic ground reservoir, two-stage linear cascade, and fractional-delay routing) support in model registry, config, and simulation dispatching
MOHYSE hydrological model (7-parameter HOOPLA HM10 port of the Fortin & Turcotte 2007 MOdèle HYdrologique Simplifié à l'Extrême with capacity-limited infiltration, dual soil/groundwater linear reservoirs, and gamma unit hydrograph routing) support in model registry, config, and simulation dispatching
SMAR hydrological model (8-parameter Perrin variant of the O'Connell et al. 1970 Soil Moisture Accounting and Routing model with 16-layer soil column, exponentially decaying ET, dual linear/quadratic routing, and fractional-delay routing) support in model registry, config, and simulation dispatching
SIMHYD hydrological model (8-parameter HOOPLA HM15 port of the Chiew et al. 2002 SIMple HYDrological model with exponential infiltration, saturation-proportional interflow/recharge, and dual linear routing reservoirs) support in model registry, config, and simulation dispatching
Warmup period filtering for projections: read_projection_data now computes an is_warmup column marking the first 3 years of each member's time series, and both _aggregate_projections and _evaluate_projection exclude warmup data from their calculations
Projection API now sends raw per-member timeseries (projection) alongside the aggregated data (aggregated_projection), enabling CSV export of the full ensemble
Horizon dropdown labels now display the date range (e.g., "H50 (2041-01-01 to 2070-12-31)")
E2E tests verifying exported CSV content for projection data and results (column structure, ensemble member count, indicator values) for both Baskatong and Au Saumon
Simulation and projection APIs now correctly compare snow model against "none" string instead of None, fixing snow model detection after the 3.4.1 sentinel change
Simulation API explicitly casts hydro parameters to float64, preventing dtype errors when JSON round-trip through JavaScript produces integer values
Projection file upload now resets previous results, preventing stale charts from persisting
Projection remove calibration now properly clears config state
Fixed calibration bug where selecting transformation "none" (high flows) would break calibration by being incorrectly converted to null — the snow model's null sentinel was colliding with the transformation's legitimate "none" value
Backend now sends "none" as a string instead of null for the "no snow model" option, normalizing to None only at the API boundary
Parameter slider step precision increased from 0.1 to 0.01 for non-integer parameters
Renamed bucket model parameters from descriptive names (c_soil, alpha, k_r, delta, beta, k_t) to generic names (x1–x6), matching the convention used by GR4J and CEQUEAU
Calibration bar chart x-axis tick labels are now limited to 10 to prevent overlapping when many iterations are displayed
Cleaned up model registry docstrings to avoid hardcoded model lists
Added CEQUEAU model documentation: overview, mathematical formulation from Perrin (2000), 9-parameter description, and differences from original 11-parameter CEQUEAU
Added comprehensive Concepts documentation with mathematical formulations:
GR4J model: production store, unit hydrographs, routing store equations
Bucket model: linear reservoir theory, flow partitioning, comparison with GR4J
Eager file existence checks in data.py for read_catchment_data, read_projection_data, and _get_available_period to properly handle missing files with lazy Polars operations