prop/docs
Graham McIntire 9f583a16bf
perf(weather/scalar_file): single MessagePack format for both Elixir and Rust
Move ScalarFile from a dual-writer dual-format setup (ETF on the Elixir
side, materialized via NotifyListener; nothing on the Rust side) to a
single chunked-MessagePack format that both languages produce and
consume.

Elixir side:

- ScalarFile now writes gzipped MessagePack `.mp.gz` per chunk via
  Msgpax. Reader decodes with Msgpax + zlib. Atom keys are stripped to
  strings on encode and re-atomized via a whitelist on read so callers
  see the same shape regardless of which side wrote the bytes.
- DateTime values round-trip through ISO8601 strings.
- New cross-language wire-format test that decodes a hand-rolled
  payload mirroring exactly what `rmp_serde::to_vec_named` emits, so a
  format regression on either side fails the suite.

Rust side:

- New `prop_grid_rs::weather_scalar_file` module:
  - 1:1 port of `Microwaveprop.Weather.WeatherLayers.derive/1` plus
    the surface fields `Weather.build_grid_cache_row/4` adds on top
    (lapse rate, mid lapse rate, inversion strength + base, 850/700 mb
    interpolation, surface RH, surface refractivity, ducting flag).
  - `write_atomic` chunks rows into 5°×5° buckets, writes one
    `<lat_band>_<lon_band>.mp.gz` per chunk via tmp + rename, drops
    pre-existing chunks first to keep writes canonical.
  - 5 unit tests covering surface-only rows, upper-air derivation,
    write/read round-trip, chunk band boundaries, and the
    out-of-physical-range surface-temp filter.
- Pipeline integration: both `run_chain_step` (f01..f18) and the f00
  analysis path now build `Vec<ScalarRow>` in the same merged-cell
  pass that builds `CellEntry` and `Conditions`, then fire a parallel
  `spawn_blocking` write that overlaps with scoring. Awaiting the
  scalar future after the score-band writes keeps the failure-surface
  symmetric with the existing profile_future.

Result: every new forecast hour lands with the scalar artifact already
on disk, so /weather reads never fall through to ProfilesFile decode +
per-cell SoundingParams + WeatherLayers derivation. The Elixir-side
`NotifyListener.handle_propagation_ready/1` materialization remains as
an idempotent safety net for hours that pre-date this commit.
2026-04-29 08:26:28 -05:00
..
algo-reports feat(scorer): retire HPBL multiplier and native-duct 1.15× boost 2026-04-25 12:42:56 -05:00
plans chore(mrms): delete pipeline — consumer AsosAdjustmentWorker already disabled 2026-04-19 17:25:59 -05:00
research Phase 3 spike (parked) + Phase 6: temperature anomaly 2026-04-10 08:47:11 -05:00
algo_commercial.md Refactor HRRR fetch to batch points per hour 2026-03-30 17:21:47 -05:00
algo_original.md Refactor HRRR fetch to batch points per hour 2026-03-30 17:21:47 -05:00
algo_updated_with_data.md Refactor HRRR fetch to batch points per hour 2026-03-30 17:21:47 -05:00
analysis_output.txt Normalize ML features to prevent NaN gradient explosion 2026-04-01 09:08:33 -05:00
analysis_output_solar.txt Normalize ML features to prevent NaN gradient explosion 2026-04-01 09:08:33 -05:00
goes-r-research.md HRRR forecast hours (f00-f18) with timeline map UI 2026-03-31 16:44:47 -05:00
RRFS.md Add meteorologist feedback on model choice to RRFS doc 2026-03-31 09:27:23 -05:00
runbook_propagation_pipeline.md perf(prop): cap ScoreCache LRU + drop eager warmers to fix hot-pod OOMs 2026-04-24 18:49:36 -05:00
weather.md perf(weather/scalar_file): single MessagePack format for both Elixir and Rust 2026-04-29 08:26:28 -05:00