Run one model
The supported operator interface is meteo forecast build, the CLI that
@azohra/meteo.forecast installs (pnpm exec meteo forecast build).
Model-specific builder modules are implementation details. Downstream
automation should use the CLI so external site and output paths are scoped
consistently.
-
Confirm the model declaration. Read Choose models and Model capabilities. The slug in
models.jsonis its identity. -
Preflight the paths and model selection. This step performs no network access and writes nothing.
Terminal pnpm exec meteo forecast build --model hrrr-conus --sites ./sites.json --output ./public/data --dry-runSuccess is one line,
Would build hrrr-conus for N site(s) from … into …, with both paths resolved absolute and nothing written. -
Use a short smoke cap when appropriate. Append
--max-steps 2to the dry run to select the first two scheduled steps. It limits forecast steps and leaves sites and fields unchanged. -
Point the engine at your published root. A real build reads the published dataset to detect what is already there, and the dry run does not. The engine does not guess where the dataset is, so without configuration a real build exits with
PublisherConfigurationError. SetMETEO_DATA_BASEto the public URL your dataset will live at.Terminal export METEO_DATA_BASE="https://forecasts.your.club/data"Environment and credentials covers the day-one state of that URL and the S3 mode that reads the bucket directly.
-
Run the build. Remove
--dry-run(and--max-steps, if you used it) for the full declared horizon. -
Inspect the output before deploying it. The model manifest and each expected site profile must share the same
referenceTime. If this command prints one line, they do.Terminal jq -r '.referenceTime // .run.referenceTime' public/data/hrrr-conus/manifest.json public/data/hrrr-conus/sites/*.json | sort -uFor byte-level validation, parse each file with the raw-text guards from
@azohra/meteo.briefing/contract. Every consumer runs the same check.
Complete command surface
meteo forecast build (--model SLUG | --all) --sites PATH [--output PATH] [--max-steps N] [--history | --no-history] [--dry-run]
meteo forecast publish (--model SLUG [--data PATH] | --models) [--dry-run] [--cache-live VALUE] [--cache-closed-months VALUE]
meteo forecast terrain (--sites PATH|dataset [--output PATH] | --check | --sync)
meteo forecast runs-index [--output PATH]
meteo forecast catalogue [--output PATH]A site catalogue is required (--sites or METEO_SITES). Which sites an
operator publishes is their decision, so there is no default. Passing the
literal dataset builds from the sites.json published at the dataset
root, so site identity needs no home in an operator’s repository. The output
root defaults to ./data. --model and --all are mutually exclusive.
Unknown model slugs, missing or unreadable site files, invalid site
catalogues, and unusable output paths fail with an actionable error.
History publication is the operator’s choice and is on by default. Every
successful build also appends to the
append-only month archives and their
sidecar indexes. --no-history publishes current documents only.
publish uploads one model’s tree in publication order and refuses to
publish backwards. With --dry-run it prints the verdict and the plan
without moving a byte. terrain regenerates
site-context.json.
terrain --check answers fresh or stale for the published context
against the published catalogue, and terrain --sync regenerates and
publishes the context when the answer is stale. runs-index regenerates
runs.json wholesale from the published manifests. catalogue emits the
packaged models.json. Teaching-scenario generation is source-checkout
tooling and is not part of the engine surface.
Each builder detects the latest complete provider run and exits without
rewriting output when that referenceTime is already published. The engine
reads what is already published from the published dataset itself, at the
root configured in step 4. The same source seeds the month archives that
history appends continue. A successful
new run writes current profiles, appends history, and writes the model
manifest. Environment and credentials is the
complete variable list. Schedule builds
applies the catalogued publication cadence to recurring jobs.
When a build fails
A build fails with an error instead of publishing a wrong document. These are the errors you will see.
- A missing or non-finite required sample throws
`${provider} returned no ${fieldName} for ${site.name}`. - The shared writer refuses a NaN that survives to publication with
`non-finite value ${value} at ${path} — refusing to publish`. - A site outside the model’s sampling guard fails with an out-of-grid error.
- A real build without a configured published root exits with
PublisherConfigurationError(step 4).
A failed build exits non-zero before the deploy step your scheduler gates on (Schedule builds). The previous publication stays live, and the next tick tries again.
Render what you built
Rendering belongs to the read side.
Render a first Meteogram is the
complete walkthrough, covering fetch, validation, scene and SVG. Point its base at
your own published root (the same URL as METEO_DATA_BASE) instead of the
sample dataset, and use your own model and site slugs. When the page loads
a manifest and profile pair from cached static storage, use loadForecast()
from @azohra/meteo.briefing/transport so a pair
that describes two runs is retried once and reported as stale if it still
disagrees.
Before that URL exists, the same walkthrough runs unchanged against the
built directory: serve --output locally
(npx serve public/data, or any static file server) and point base at it.