Filed from views-pipeline-core after investigating views-pipeline-core#509. Handed to Simon; not acted on from the pipeline-core side.
What
views_reporting/mapping/mapping.py:491-496 merges the forecast frame onto the map geometry by isoab → ADM0_A3, then :586-591 does pivot_table(index=ADM0_A3, aggfunc="first"). The bundled country metadata (views_reporting/metadata/data/country.parquet) carries duplicate isoab for dead/live country pairs: Sudan (country_id 59 pre-2011 vs 245), Indonesia (208 vs 209), Serbia (230 vs 233), Tanzania (236 vs 242) — verified against the file; these are the only four collisions among the 22 dissolved ids in the CM panel.
If a forecast frame ever carries a row for a dead id alongside the live one, "first" picks whichever row comes first — and if row order follows country_id, the dead id sorts first in all four pairs, so the map would show the dead country's value over the living one. Inferred from the pivot, not rendered.
Why it can happen
views-r2darts2 ≥0.2.0 forecasts every entity ever seen, dead ones included (views-r2darts2#49). pipeline-core 3.3.0 now refuses such predictions at the model boundary (ADR-064), so the phantom rows should not reach you from a 3.3.0+ run — but the pivot's "any duplicate wins arbitrarily" is a hazard independent of that: any duplicate row per ISO code, from any source, is resolved silently.
The ask
Make a duplicate ISO code on the way into the pivot loud (refuse, or at least log which country_ids collided and which won), rather than aggfunc="first". Small; theirs to shape.
🤖 Generated with Claude Code — https://claude.ai/code/session_01KQmxyvNnB8AJGdgaSR5xKr
Filed from views-pipeline-core after investigating views-pipeline-core#509. Handed to Simon; not acted on from the pipeline-core side.
What
views_reporting/mapping/mapping.py:491-496merges the forecast frame onto the map geometry byisoab→ADM0_A3, then:586-591doespivot_table(index=ADM0_A3, aggfunc="first"). The bundled country metadata (views_reporting/metadata/data/country.parquet) carries duplicateisoabfor dead/live country pairs: Sudan (country_id 59 pre-2011 vs 245), Indonesia (208 vs 209), Serbia (230 vs 233), Tanzania (236 vs 242) — verified against the file; these are the only four collisions among the 22 dissolved ids in the CM panel.If a forecast frame ever carries a row for a dead id alongside the live one,
"first"picks whichever row comes first — and if row order followscountry_id, the dead id sorts first in all four pairs, so the map would show the dead country's value over the living one. Inferred from the pivot, not rendered.Why it can happen
views-r2darts2 ≥0.2.0 forecasts every entity ever seen, dead ones included (views-r2darts2#49). pipeline-core 3.3.0 now refuses such predictions at the model boundary (ADR-064), so the phantom rows should not reach you from a 3.3.0+ run — but the pivot's "any duplicate wins arbitrarily" is a hazard independent of that: any duplicate row per ISO code, from any source, is resolved silently.
The ask
Make a duplicate ISO code on the way into the pivot loud (refuse, or at least log which
country_ids collided and which won), rather thanaggfunc="first". Small; theirs to shape.🤖 Generated with Claude Code — https://claude.ai/code/session_01KQmxyvNnB8AJGdgaSR5xKr