Skip to content

Model catalogue

models.json lists the models a dataset publishes and declares what each one can provide, in a form code can read. The provider facts behind those declarations are in the dated forecast feed reference.

On the wire

FactValue
Published atmodels.json at the dataset root, beside sites.json and site-context.json
ParseparseModelCatalogueJson from @azohra/meteo.briefing/contract
Zod authoritymodelCatalogueSchema, pinning MODEL_CATALOGUE_SCHEMA_VERSION (1)
JSON Schemamodels.schema.json
Discoveryreaders discover models from this document: models, plus the optional smokeModels and observationModels arrays

Entry structure

GroupFieldsConsumer use
Identityslug, label, providerPath identity and reader-facing label
SchedulestepHours, horizonHours, runIntervalHours, typicalPublicationLagHoursTime sampling, horizon, publication cadence, and the upper end of normal publish lag
GridgridKmDeclared horizontal resolution
Lifecycleexperimental, optional sunsetAvailability context and machine-readable retirement
Kinddeterministic or ensembleDocument interpretation without a named-model branch
Capabilitieslevels, omega provenance, heat fluxes, gust/precipitation semantics, smoke coupling, convection, PBL and cloud fieldsDeclared feature presence and labels

stepHours declares the finest published step. It does not promise that step across the whole horizon. NAM drops from hourly to three-hourly output after 36 hours, and GEPS from three-hourly to six-hourly after 192 hours. The dated forecast feed reference records each model’s full cadence.

typicalPublicationLagHours is the upper end of the normal delay between a run’s referenceTime and this dataset publishing it. It is the provider’s complete-availability time plus the operator’s own overhead, rounded up. runFreshness reads it to grade freshness. The values were seeded on 2026-08-10 from the dated [verified] availability times in the forecast feed reference. They are due to be re-verified against the accumulated run archive around September 2026.

Discover models from the catalogue

read-models.ts
import { parseModelCatalogueJson } from "@azohra/meteo.briefing/contract";
export function modelLabels(text: string): string[] {
const catalogue = parseModelCatalogueJson(text);
if (!catalogue) throw new Error("unsupported model catalogue");
return catalogue.models.map(
(model) => `${model.slug}: ${model.label} (${model.capabilities.gust})`,
);
}

Datasets that are not profiles have their own arrays. The optional smokeModels array lists smoke-document models (RAQDPS today) with the same identity and cadence metadata as models, but no profile capabilities. They sit outside models because an entry without capabilities would fail every catalogue guard already deployed, while older guards strip an unknown top-level key harmlessly. If the array is absent, the catalogue predates smoke documents. The smoke document reference covers them.

The optional observationModels array works the same way for observation datasets (GOES-18 DSR and AOD today). Each entry has identity, gridKm, and a cadenceMinutes value used to judge freshness, in place of run scheduling. The observation document reference covers them.

Adding a model to the catalogue needs no package enum change, because the package has no enum of models.

Site context beside the catalogues

site-context.json is published at the dataset root beside models.json and sites.json; the site context reference defines it.

Absence and semantics are declarations

Capability booleans state whether a family of fields exists. Gust and precipitation also declare what the value means, so readers must not label two different time windows as the same measurement. Vertical velocity declares where it comes from and which levels carry it.

Show what the catalogue declares. Do not infer features from the provider, grid size, kind, slug, or another model in the same family. Model capabilities explains what each declaration means for reading a chart, and Choose models helps you pick models for a task.