Skip to content

feat(weather): global severe-weather coverage via WMO SWIC CAP aggregation (#6156 direction decision) #6271

Description

@koala73

#6156 documented that the Weather Alerts panel is structurally US-only and closed with the direction explicitly undecided: "Then decide Open-Meteo-derived vs. CAP-aggregated for real global coverage." PR #6269 is shipping the interim honesty fix (labels + 25 locales). This issue proposes the answer to the open decision and scopes it.

Recommendation: CAP-aggregated, via the WMO Severe Weather Information Centre (SWIC).

Why CAP-aggregated, not Open-Meteo-derived

Open-Meteo's forecast endpoint gives derived conditions — wind speed over a threshold, precipitation over a threshold. NWS gives issued warnings: a government meteorologist decided a warning was warranted and signed it.

Merging those into one panel and one notification category means a user subscribed to "Severe weather alerts" receives a push for a storm no authority ever warned about, indistinguishable from a real NWS warning. That is a worse failure than the current gap — #6156's complaint is that empty reads as "all clear"; the derived path replaces it with alerts that read as official and aren't. If we ever want derived thresholds, they belong on their own key with their own label, not backfilling this one.

SWIC is the same class of source as NWS: official CAP issued by national meteorological and hydrological services.

The endpoint (probed 2026-08-06)

https://severeweather.wmo.int/json/wmo_all.json — no key, no auth, single request.

itemCount: 3511
lastUpdated: 2026-08-06 02:16:24   (pulled ~90s later)
distinct WMO member ids: 61
item keys: id, mid, ra, event, headline, areaDesc, sent, effective, expires, s, u, c, url

s/u/c are coded severity/urgency/certainty. url is a relative path to the source CAP XML under https://severeweather.wmo.int/v2/cap-alerts/ — present on 1,671 of 3,511 items.

Live producers with hosted CAP at time of probe:

Authority Active alerts
ar-smn-es (Argentina SMN) 828
cn-cma-xx (China CMA) 730
in-ndma-xx (India NDMA) 61
cl-meteo-es (Chile) 15
kr-kma-weather-en (Korea KMA) 14
au-bom-en (Australia BoM) 12
fi-fmi-xx (Finland FMI) 6
ph-pagasa-en (Philippines) 2
no-met-en (MET Norway) 2
hk-hko-xx (Hong Kong HKO) 1

Note CMA at 730 — this also serves a chunk of #6146 ("alternative data sources for users from Russia, China, and other regions"), which is where #6156 originally came from.

The hard part: geometry

Most non-US authorities publish geocodes, not polygons. Sampled India NDMA CAP:

<cap:areaDesc>Baran, Jaipur, Kotputli-Behror, Tonk districts of Rajasthan</cap:areaDesc>
<cap:geocode><cap:valueName>LGD District Code</cap:valueName><cap:value>102</cap:value></cap:geocode>

The polygon sits behind a separate sachet.ndma.gov.in fetch. MeteoAlarm is the same story — its Netherlands feed returned 4 areas with a polygon vs 1,732 with only an EMMA_ID geocode. severeweather.wmo.int/json/warningArea-multiviewport.geo.json is RSMC responsibility zones, not per-alert geometry.

Our seeder contract is coordinates[] + centroid (scripts/seed-weather-alerts.mjs:11-27), so a naive port yields alerts that render nowhere.

Proposed: two-tier layer.

  • Polygon tier — sources that publish real geometry (NWS today; MET Norway's api.met.no/weatherapi/metalerts/2.0/current.json returns MultiPolygon GeoJSON directly, verified) render as polygons, unchanged behaviour.
  • Point tier — geocoded alerts render at an admin centroid with the verbatim areaDesc as the label and an explicit precision marker on the record.

This is honest about precision, ships in one pass, and lets the polygon tier grow per-country later without a schema change. The alternative — per-scheme geocode→geometry join tables (EMMA_ID, LGD, …) — is a permanent per-country maintenance tail and should not gate the first release.

Source admission requirements

docs/solutions/integration-issues/authority-gated-cyclone-seed-sources.md set the bar for new meteorological hosts, and it applies here:

  • Explicit source-decision record in the adapter (the JMA EXPERIMENTAL_CAP_NOT_OPERATIONAL / JTWC NOT_ENABLED_PENDING_RAILWAY_PREFLIGHT pattern).
  • Railway transport preflight before enabling severeweather.wmo.int.
  • Bounded host policy — host allowlist, redirect rejection, timeout, response cap. Note: wmo_all.json is ~1 MB, so the HKO-style 256 KiB cap must be raised deliberately for this host with the number justified, not inherited by accident.
  • shared/source-attribution-manifest.json entry. It will land as "status": "terms-review" like the existing api.weather.gov entry.

Scope

  • Railway preflight for severeweather.wmo.int; record the decision in the adapter.
  • SWIC adapter: fetch wmo_all.json, normalise to the existing alert record, map s/u/c to our severity/urgency/certainty.
  • Two-tier geometry: point tier w/ precision marker; keep NWS on the polygon tier.
  • Merge into weather:alerts:v1 behind per-source provenance so a single authority failing cannot empty the panel.
  • Attribution manifest entry + docs/data-sources.mdx.
  • Revisit the fix: disclose US-only weather alert coverage #6269 labels once coverage is no longer US-only — they will be wrong in the good direction.
  • Tests: source-admission, host/redirect/size bounds, geocode-only records render as points, mixed-source merge, one-source-down degradation.

Open question — licensing

I verified the endpoint works. I did not verify redistribution terms. SWIC relays member-state alerts whose terms vary by member; this needs reading before the manifest entry moves off terms-review.

Not in scope

  • MeteoAlarm (Europe) — SWIC already carries some European authorities; revisit only if European density proves insufficient.
  • The .slice(0, 50) truncation defect in the current seeder — filed separately, fix lands first.

Related: #6156, #6146, #6269.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: feedsRSS feeds, news aggregationenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions