Skip to content

Epic: Migrate forecast reconciliation into views-postprocessing (frames-native, parity-proven) #31

Description

@Polichinel

Origin: executes #3 ("Broaden scope: accept reconciliation from views-reporting") and the views-reporting side views-platform/views-reporting#72 ("Reconciliation is not reporting — migrate to views-postprocessing").

Authored as a context-rich, solution-open brief. Approaches are proposals, not prescriptions.

Why

Forecast reconciliation makes PRIO-GRID-month (pgm) predictions sum to their country-month (cm) totals — a post-forecast operation called by ensemble managers before any reporting/evaluation/delivery. It lives in views-reporting by accident (extracted there alongside visualisation code). That repo's own roadmap, risk register (C-24: "torch leaves with it"), and frames-adoption plan all say it should move here, and it is cleanly separable (zero ties to reporting/plotting/Appwrite).

Moving it here gives it the right roof (post-processing, not reporting), removes views-reporting's torch dependency (reconciliation is its only consumer), and makes the dependency direction clean (pipeline-core → views-postprocessing).

Where we are

Slice 1 is done (PR #30): the leaf algorithm reconcile_proportional was ported to pure numpy and proven bit-for-bit against the untouched views-reporting torch oracle (tests/test_reconciliation_parity.py, max abs diff 0.0). C-37 records that this is the pragmatic per-draw method (FPP3 top-down forecast-proportions), to be upgraded to principled probabilistic reconciliation after the migration is wired.

This epic is everything after the leaf: orchestration, country↔grid grouping, end-to-end parity, the cross-repo repoint, and the phase-out.

Desired end state

Reconciliation runs end-to-end in views-postprocessing, frames-native, with no torch, no pandas, no viewser, no wandb in the path; its output is proven to reproduce the frozen views-reporting pipeline on a realistic fixture; pipeline-core's ensemble managers call it here; and the views-reporting copy (plus its torch dep) is removed.

Scope

✅ In: orchestration (ReconciliationModule equivalent), country↔grid grouping via views_frames.cross_level_align, frames-native validation, the end-to-end parity gate, the pipeline-core repoint, and the views-reporting phase-out.

❌ Out (future, not this epic):

  • Changing the algorithm. Migration is parity-preserving; the upgrade to principled probabilistic reconciliation (the IJF paper, C-37) is a separate follow-on epic, gated on this one completing.
  • Editing views-reporting before phase-out. It stays frozen as the parity oracle until the final story.
  • Reconciling the GAUL vs VIEWS country-id systems. For parity we inject the oracle's VIEWS country_id mapping; whether to later source it from our GAUL lookup (admin1_gaul0_code) is a separate decision (see the first story).

The one decision to retire first

The oracle groups grid cells by VIEWS country_id fetched from viewser (network; views_reporting/metadata/entity_metadata.py). Our GAUL lookup uses admin1_gaul0_code — a different id system. For parity we must group by the same VIEWS country_id, injected (the leaf never embeds geography — views-frames ADR-014). Story S0 captures the oracle fixture offline and records this decision.

Stories

Execution order (full checklist in the tracking issue #41):

  1. Capture the offline parity oracle + decide the country↔grid id system #32 — Capture offline parity oracle + decide country↔grid id system · planning needs-decision
  2. CM/PGM → PredictionFrame adapters #33 — CM/PGM → PredictionFrame adapters · implementation (after Capture the offline parity oracle + decide the country↔grid id system #32)
  3. Country↔grid grouping core via cross_level_align #34 — Country↔grid grouping core via cross_level_align · implementation (after CM/PGM → PredictionFrame adapters #33)
  4. Frames-native reconciliation validation guards #35 — Frames-native validation guards · implementation (after CM/PGM → PredictionFrame adapters #33)
  5. ReconciliationModule orchestration (numpy-native; drop wandb + multiprocessing) #36 — ReconciliationModule orchestration; drop wandb/multiprocessing · implementation (after Country↔grid grouping core via cross_level_align #34, Frames-native reconciliation validation guards #35)
  6. End-to-end reconciliation parity gate vs frozen views-reporting #37 — End-to-end parity gate · testing (after ReconciliationModule orchestration (numpy-native; drop wandb + multiprocessing) #36)
  7. CIC for ReconciliationModule + migration docs #38 — CIC + migration docs · documentation (after ReconciliationModule orchestration (numpy-native; drop wandb + multiprocessing) #36)
  8. Wiring: expose reconciliation API + pipeline-core ensemble repoint #39 — Wiring / pipeline-core repoint · implementation blocked (after End-to-end reconciliation parity gate vs frozen views-reporting #37)
  9. Phase out reconciliation in views-reporting (closes views-reporting#72) #40 — Phase out reconciliation in views-reporting (closes views-reporting#72) · implementation blocked (after Wiring: expose reconciliation API + pipeline-core ensemble repoint #39)

Epic acceptance criteria

  • A frames-native reconciliation module reproduces the frozen views-reporting pipeline on a realistic fixture (end-to-end parity), offline (CI needs no torch / views-reporting / viewser).
  • No torch, pandas, viewser, or wandb in the reconciliation path here.
  • A CIC documents the orchestration class (repo convention, ADR-006).
  • pipeline-core ensemble managers call reconciliation in views-postprocessing.
  • Reconciliation (and torch) are removed from views-reporting; views-reporting#72 closed.
  • C-37 (principled-upgrade) remains open and is handed to its follow-on epic.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    epicA large capability spanning multiple storiesreconciliationForecast reconciliation migration (views-reporting -> here)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions