backend/drift_check.py quantifies the migration's data impact by fetching both
live history sources (NASA POWER primary + the Open-Meteo/ERA5 fallback) for a
sample of cells and reporting, per variable: mean-absolute-difference / bias / max
(raw drift) and grade-band divergence (the share of days whose graded band actually
changes). Since Open-Meteo is ERA5, this doubles as a fidelity check for the ERA5
seed.
Because grades are percentiles within each source's own distribution, a uniform
bias moves MAD but not grades — so the two numbers are read together. Open-Meteo is
kept as a dormant fallback (not deleted), so both sources stay fetchable for this
comparison. The comparison logic is unit-tested; the per-cell fetch runs on a
networked box (python drift_check.py [--limit N] [--days N]).
The recent-observations + forward-forecast bundle is now built without Open-Meteo:
the recent observed window comes from a NASA POWER range (measured, via the range
fetch added for the history flip) and the forward days from MET Norway, merged by
date. Meteostat fills the gusts neither source carries — measured for the observed
days, estimated from wind for the forecast days.
Open-Meteo's forecast API is demoted to the fallback, still gated by its existing
_forecast_cooldown_until rate-limit cooldown; then a stale cache. MET Norway
switched to /compact (same fields, smaller payload) and the bundle TTL relaxed
1h -> 4h. NASA's near-real-time lag leaves a 1-2 day recent-edge gap that grades
as missing, bracketed by history behind and forecast ahead.
Tests updated to the new source order (NASA+MET merge, Open-Meteo fallback, and
the forecast cooldown now gating that fallback); deletion of Open-Meteo is not
done — it stays as the dormant fallback.
Conflict resolved (UNVERIFIED -- tests not runnable locally, docker blocked):
tests/data/test_climate.py keeps BOTH appended test blocks (dev's
forecast-cooldown tests + this branch's NASA-primary tests). Same conflict
exists merging this branch into the split repo's dev.
# Conflicts:
# backend/tests/data/test_climate.py
One root workflow set replaces the four repos' copies (deleted -- root-only
is where Forgejo reads them, and dead copies are a trap): per-domain
build-push with explicit image paths (emi/thermograph/backend|frontend; the
old github.repository-derived path collides in a monorepo), path-filtered
per-domain beta/prod/dev deploys, a domain-input reusable build check, a
single always-reporting PR gate (path-filtered required checks deadlock
auto-merge), a new infra-sync pipeline (host checkout + secrets render on
infra/** pushes), and ports of secrets-guard / ops-cron /
observability-validate to monorepo paths.