Skip to content

Forecast architecture

The supported interface of @azohra/meteo.forecast is the meteo CLI (pnpm exec meteo, or node forecast/dist/cli.js from a workspace checkout) and the versioned documents it writes.

Publication flow from model cycle to browser A five-stage sequence across three actors: an upstream provider publishes a forecast cycle; the forecast engine probes completeness, builds each model, and publishes once across the static-dataset boundary; the browser reads manifest and profile and exposes a torn pair as stale.

Inside the builder stage, each step belongs to one module.

Module-owned steps inside the builder stage A pipeline flowing top to bottom inside the builder stage. A configuration node, models.json plus sites.json, feeds a single vertical chain: provider transport owned by providers/transport.ts, gridpoint sampling owned by the datamart and NOAA clients with the grib decoder, and source-shaped hours assembled by the builders on their common skeletons. The hours descend to the accented deriveSiteForecast step in derive.ts, then to contract rounding and validation tests in publish.ts and builders/publication.ts, which fans out to the three published artifacts: the per-site profile under sites/, manifest.json, and the append-only monthly gzip history archive.

AreaRepository homeResponsibility
CLI and scoped pathsforecast/src/cli.ts, forecast/src/config.tsSelect model(s), validate site and output paths, cap forecast steps (--max-steps caps every model, GOES granules included), and dispatch safely. Configuration is passed explicitly and is not held in ambient state
Site cataloguesites.tsLoad the versioned, identity-only site envelope and reject shapes the loader does not speak
Provider transport plumbingproviders/transport.tsOne User-Agent, one request timeout, and the download telemetry that manifests publish
Provider clientsproviders/datamart.ts, providers/noaa.ts, and the workspace’s @azohra/meteo.grib decoderFetch, range-read, decode, sample, and account for transport work
Published-dataset readsdataset.tsRead what is already published (public HTTPS via METEO_DATA_BASE, or the bucket directly when upload credentials are present) to gate rebuilds and seed history
Builder registrybuilders/registry.tsMaps each catalogued model slug to an options-only build entry, in exact model-catalogue order. Each factory imports its builder module (dynamic import()) only when a build runs
Builder helpersbuilders/common.tsThe code every build uses the same way: forecast-slot timestamps, the bounded fetch pool, and source-hour and level skeletons
Buildersbuilders/*.tsVerify run completeness, request declared fields, preserve absence, and assemble source hours
Shared field sciencesentinel.ts, and the moisture functions imported from @azohra/meteo.briefing/deriveInverse-Magnus dew-point depression for models that publish only RH, and masking of ECCC’s “not computed” CAPE/CIN sentinels
Derivationderive.tsProduce published profile blocks and model-dependent derived values. The usable-lift derivation is imported from @azohra/meteo.briefing/derive and stored at the 1 m/s sink
Ensemble aggregationensemble.tsAggregate member profiles, including circular wind and censored counts
Publicationpublish.tsRound contract fields, write JSON, append gzip history, and build the run index
History mechanicshistory.tsSplit gzip members and recompute each month’s sidecar byte-offset index after every append
Site contextterrain.tsOne-shot site-context.json enrichment (elevation, slope/aspect, relief, land cover). The geospatial stack loads only when the terrain command runs
Teaching scenariosscenario/Generate fixed inputs through the same derivation authority. This is source-checkout tooling and is not part of the engine surface

The project overview defines which quantities the forecast engine owns and which belong to @azohra/meteo.briefing, including the one parameterized exception. The Meteogram derivations define the engine’s equations, constants, fallbacks, and renderer-only transformations.

The builder contract defines the required inputs, validation, and publication behaviour for model modules.