Skip to content

Builder contract

A builder translates one verified provider feed into the shared source shape, then delegates profile derivation and publication. It does not redefine the public JSON shape or renderer behaviour.

  1. Catalogue agreement. The slug, kind, levels, cadence, horizon, capability presence, and field semantics match models.json.
  2. Complete-run selection. A builder selects a provider run only after its declared final product is available, and skips an already-published referenceTime without rewriting output.
  3. Domain honesty. A sample too far from a site signals out-of-domain clamping; the build fails rather than publishing a boundary value.
  4. Unit and direction normalization. Source values reach the profile contract’s units and meteorological FROM-direction before publication.
  5. Absence stays absent. Missing records, masked sentinels, and unsupported optional fields are omitted, never converted to zero.
  6. Semantics are supplied, not inferred. The verified builder passes gust and precipitation semantics into derive_windgram_profile.
  7. Derived values have one authority. Builders supply source fields; pipeline/src/windgram/derive.py supplies derived.*.
  8. Publication is deterministic at the edge. Shared rounding and JSON writers own precision and serialized shape.
builder source published profile
temperatureC ─┐ surface.temperatureC
dewPointDepressionC ├─→ surface.dewPointC
heat fluxes + sampled levels ├─→ derived.*
optional provider fields └─→ optional surface/level fields

The source dictionary is internal and may carry provider-facing intermediate names such as dew-point depression. The published contract is the stable boundary. Do not expose a builder intermediate merely to avoid an appropriate derivation.

Ensemble builders derive every member independently, then aggregate matching numeric positions. run.members is total membership; EnsembleValue.members counts contributors at that position and can be lower when null or censored member values are excluded. Wind direction uses circular aggregation. Height censoring uses ceiledMembers only on positions where the pipeline records a column ceiling.

Focused builder tests should use committed fixtures or injected transport responses. They must not require live provider access; verification establishes facts and tests make behaviour repeatable.