The modular risk framework

How twx-phenoweight, twx-risk-severity-library and the weather pipelines map into ag_risk to score each dimension · with two worked examples · 2026-07-16

The engine is fixed; a solution is just a config. Every crop-risk product — Kenya maize today, Vietnam coffee tomorrow — is the same engine wired to three swappable things: data sources (pipelines & models that emit a signal on the grid), a WHEN profile (twx-phenoweight), and HOW-BAD curves (twx-risk-severity-library). Change those three in config and you get a new crop, region, or peril — with no engine change.

1. The pieces — one engine, three swappable inputs

Per dimension, the model does the same three moves: get the signal → phenoweight it (WHEN) → score its severity (HOW BAD), then combine the dimensions. The three inputs are modular; the engine and the combine never change.

The modular system Data sources pipelines & models — emit a signal ERA5 · SEAS5 · SMAP · disease · flood … twx-phenoweight WHEN — timing curves twx-risk-severity-library HOW BAD — severity curves (damage · fraction · return-period) config wires the three, per dimension ag_risk engine per-dimension severity → weight-free combine (fixed — never changes) risk scores
One fixed engine; three swappable inputs wired in config. Add a dimension = add a source + a WHEN curve + a severity curve — all config.
Two more inputs the engine needs — per crop, not per dimension (the scaffolding). The three inputs above are swapped per dimension; every run also needs two per-crop inputs that are easy to overlook: So the honest picture is three swappable inputs (data · WHEN · HOW-BAD) + two per-crop scaffolding inputs (calendar = when the crop grows, mask = where).

2. Worked flow — Kenya maize (today, weather-only)

The shipped setup. Four dimensions, all from the ERA5 (realised) / SEAS5 (forecast) weather pipeline, scored with a maize phenoweight profile and literature severity curves.

Kenya maize flow signals (source) Drought — water deficit + soil moistureERA5 / SEAS5 Heat — EDD / hot nightsERA5 / SEAS5 Cold — frost daysERA5 Water — precip excessERA5 phenoweight (maize) × severity library WHEN × HOW BAD weight-freecombine maize riskscores
Four weather signals → maize phenoweight × severity curves → weight-free combine → per-dimension + combined maize scores.
DimensionSignal (source)Phenoweight (maize)Severity methodVerdict
Droughtwater deficit + soil moisture — ERA5 / SEAS5peaks at silkingcurve — FAO-33/56Directional
HeatEDD + hot nights — ERA5 / SEAS5peaks at silkingcurve — Schlenker / BayerDirectional
Cold (frost)frost days — ERA5grain-fill windowcurve — frost damageDirectional
Water (waterlogging)precip excess — ERA5early-vegetativecurve — Ren 2016Directional
This driver set is a first pass — and what drives a dimension can change. A dimension is a stable name (drought · heat · cold · water); what drives it — the signal(s), the data source / feed, and the severity curve — is config, not fixed. Over time these change with no engine change and no change to the output format: e.g. heat's driver can move from EDD → Bayer's Tmax>35°C-day count, a second driver can be added to a dimension, a feed can be swapped, or a curve re-anchored under calibration. The signals shown above (water deficit + soil moisture for drought, EDD + hot nights for heat, …) are a first, literature-anchored pass and are expected to evolve — only the shown dimensions / values move, the emitted schema stays fixed.

3. Worked flow — Vietnam coffee (same engine, new config, mixed sources)

Now a different crop with heterogeneous data sources. The engine, phenoweight and severity library are unchanged — only the config differs: a coffee phenoweight profile (different timing), coffee severity curves, and signals from weather + an observed satellite feed + two models. Each still lands on the same read contract, gets phenoweighted, and is scored by the library.

Scope note. v1 in Model Foundry is weather-only. The flood / disease / satellite examples below are the extensibility pattern, not the production model — they live on a separate GEE testbed branch for testing and expansion, not in the shipped weather model.
Vietnam coffee flow signals (source) Drought — rainfall/ET + soil moistureERA5/SEAS5 (weather) + SMAP (observed EO) Heat — temperatureERA5 / SEAS5 (weather) Disease — incidencedisease-detection model Flood — inundation fraction + persistenceflood model (Sentinel-1) phenoweight (coffee) × severity library WHEN × HOW BAD weight-freecombine coffee riskscores
weather observed EO model output
Four heterogeneous signals — weather, an observed satellite feed, and two models — flow through the same coffee phenoweight × severity library → combine → coffee scores. The engine didn't change.
DimensionSignal (source)Phenoweight (coffee)Severity methodVerdict
Droughtrainfall/ET (ERA5/SEAS5) + soil moisture (SMAP)flowering / cherry-fillcurveDirectional
Heattemperature — ERA5 / SEAS5floweringcurveDirectional
Diseaseincidence — disease-detection modelwarm-humid windowcurve (incidence→loss, generated upstream)Directional
Floodinundation fraction + persistence (time underwater) — flood model (Sentinel-1)sensitive stagefraction — exposure (fraction) × conditional-damage (persistence)Exposure

How the new sources plug in, concretely:

4. Forecast vs realised — one engine, two run modes

The same engine, curves and phenoweight run in two modes — only the feed, the role and the output store differ:

Two consequences of "same engine, different feed":

5. The point — modularity

Between Kenya maize and Vietnam coffee, the engine, twx-phenoweight and twx-risk-severity-library never changed. Only the config did — which sources feed each dimension, which WHEN profile, which severity curves. Adding disease and flood to coffee was not an engine change: it was a new signal source + a coffee phenoweight window + a severity entry, all declared in config. That is the framework — a fixed scoring structure that any crop, region, peril, or data source plugs into.

Same three moves, every time: get the signal (from any pipeline or model) → phenoweight it (WHEN, from twx-phenoweight) → score its severity (HOW BAD, from twx-risk-severity-library) → weight-free combine. Swap the inputs, keep the engine.

Companion to the twx-risk-severity-library proposal. Kenya maize is the shipped v1; Vietnam coffee is illustrative of the extension path (mixed weather / EO / model sources).