The recent+forecast bundle excluded the cell's in-progress local day, on the
premise that Open-Meteo's daily high/low for today aggregates only the hours
elapsed so far. That is true of the MET Norway series -- which starts mid-day
and is correctly gated on diurnal coverage in _metno_to_frame -- but not of the
forecast endpoint, which backfills the rest of today from the model run. The
guard was generalised across by analogy and never verified against the API.
Checked against the live API at four cells between 01:00 and 19:00 local: the
reported daily max always equals the max over all 24 hourly values, and differs
from the elapsed-hours-only max whenever the day has hours left. Los Angeles at
09:16 local reported 93.9F -- the whole-day figure -- where the hours so far
topped out at 76.1F.
The cost was a hole in the middle of every freshly-synced cell's window: a
complete yesterday, no today, a forecast tomorrow, which the daily strip renders
as a missing column. 861 of 1004 prod cells had lost the 25th by the time this
was diagnosed; the 143 that still had it were stale caches predating the change.
FORECAST_DAYS is commented "today + 7 days ahead", which the drop contradicted.
Today is kept unconditionally now. A day that truly cannot be graded, because it
came back with no high/low, is already dropped upstream by _to_frame, so the
local-today helper has no remaining caller and goes with it.
Also removes a verbatim duplicate of both Open-Meteo day-window tests, which the
main-into-dev reconciliation left in the file (the second copy shadowed the
first, so only one of each was ever running).
Content pages keyed cache validity on the full-history hist_end, invalidating ~1-2x/day and paying a 45yr load even to compute the token. Add content_token(cell_id) = PAYLOAD_VER:CONTENT_VER:max_date, backed by an indexed MAX(date) (climate_store.history_max_date / climate.history_max_date), so it survives intra-day top-ups and needs no full-history load.
Steady-state usage of the Open-Meteo API is removed; it remains only as a dormant fallback. Geocoding -> local GeoNames + Nominatim; wind gusts -> Meteostat; history -> NASA POWER (curated cells seeded with keyless ERA5); recent+forecast -> NASA range + MET Norway. Plus a drift-check tool comparing NASA vs Open-Meteo. All keyless, no new infra. Backend suite green in-image (gate).