Skip to content

Forecasting: per-pathogen base-facts context (seasonality, base rates) to project anchors to the resolution horizon #56

Description

@smodee

Summary

A current-value evidence anchor is not the same as the resolution-horizon
outcome, and the forecasting stage currently treats it too literally. Surfaced
concretely by q19, but the underlying gap is general: the pipeline has no notion of
a pathogen's dynamics (seasonality, typical annual trajectory, base rates), so it
can't project a current anchor forward to a distant resolution date.

This issue proposes a general knowledge layer rather than a targeted patch.

What prompted this (q19, 2026-07-05)

q19 — "How many EU/EEA countries will report locally-acquired autochthonous
chikungunya in 2026, as of 31 Dec 2026?" The new ecdc_chikungunya scraper now gives
a correct current anchor: 0 EU/EEA countries (the 2026 season hasn't started; ECDC's
seasonal report is empty until the first cases are entered). With that anchor the
forecast put 0.914 on the "0" bin.

But the resolution date is 31 Dec 2026, and EU/EEA chikungunya transmission is
seasonal (roughly Aug–Oct) — 2025 ended with 2 countries (France, Italy). So a
July "0" is the right current value but the wrong thing to extremize a full-year
forecast on. The pipeline had no way to know "it's pre-season; expect a few countries by
autumn." The anchor is correct; the horizon projection is what's missing.

This is not chikungunya-specific — it recurs wherever a current snapshot must be
projected to a future resolution date (early-window case counts, off-season baselines,
cumulative counts that will keep rising, etc.).

Proposed direction — per-pathogen "base facts" for the forecasting stage

Build a small, reusable pathogen base-facts context that the forecasting stage can
consume alongside the evidence anchor:

  • Built/fetched once (offline/curated or a one-time build step), not per-run.
  • Defaults to nothing — an empty/None context is a no-op, so it's safe to land
    incrementally and only fill in pathogens as we go.
  • Carries forecasting-relevant priors about the pathogen, e.g.:
    • seasonality windows (when transmission peaks/troughs in a given region),
    • historical annual ranges / base rates (e.g. "EU/EEA autochthonous chikungunya
      countries per year: 0–3 recent"),
    • typical trajectory shape (monotone-cumulative vs seasonal-resetting; growing vs flat),
    • status flags relevant to binary questions (elimination status, standing PHEICs),
    • transmissibility / severity notes where they inform priors.

The forecasting stage would then condition the anchor on the horizon: a pre-season 0
with an Aug–Oct season and a 0–3 base rate should widen, not collapse to 0.

Why this is bigger — but higher general upside

It's deliberately not a q19 patch. It's a knowledge layer that improves
horizon-projection across the whole question set (every question resolving at a future
date benefits), and it gives the forecaster the domain context a human analyst would bring.
Larger scope — a schema, a sourcing/curation path, and per-pathogen content — but reusable
and general, versus one-off seasonal hacks per question.

Cautions / constraints

  • As-of safety: base facts must be time-invariant priors (or explicitly as-of-safe)
    so historical-replay backtests don't leak post-cutoff knowledge. Seasonality/base-rate
    priors are fine; "current status" fields need cutoff handling.
  • No-op default must stay truly no-op (empty context ⇒ identical behaviour to today).
  • Curation cost is real; start with the handful of pathogens where horizon-projection
    clearly bites (seasonal arboviruses: chikungunya, dengue, Oropouche, West Nile).

References

  • Finding + q19 before/after: data/investigations/bfg-clientside-feed-tactic-2026-07-05.md
  • Scraper that surfaced it: bioscancast/stages/extraction/custom_scrapers/ecdc_chikungunya.py

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpost-benchmarkRevisit after first end-to-end benchmark run

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions