Skip to content

chore: sync main — CM duplicate-ISO guard (#290) - #294

Merged
Polichinel merged 2 commits into
mainfrom
development
Sep 17, 2026
Merged

Polichinel merged 2 commits into
mainfrom
development

Conversation

@Polichinel

Copy link
Copy Markdown
Contributor

Brings #293 to main: the C-227 guard in build_mapping_dataframe (two country_ids under one ISO code → loud refusal), the RED→GREEN test against the real bundle, the fixture e2e tests moved off the 10-code label double, register C-227. Diff is exactly the reviewed commit.

🤖 Generated with Claude Code

https://claude.ai/code/session_01N7YBtiS2kSVj27spMKDYfh

Polichinel and others added 2 commits September 17, 2026 11:28
…de (#290)

The bundled metadata carries dead/live country pairs sharing an ISO code
(Sudan 59/245, Serbia 230/233, … — 11 groups, 9 of which join the
shapefile). If a forecast frame carries both members, the isoab→ADM0_A3
merge yields two rows per polygon and `pivot_table(aggfunc="first")` plus
the hover-props `drop_duplicates` silently pick one: reproduced — with
[59, 245] the map drew the DEAD Sudan's value and the hover reported 59.
Ascending country_id makes the dead id win in 4 of the 9 joinable pairs;
the pick is arbitrary in all nine.

Guard at the single CM chokepoint (build_mapping_dataframe, after the
geometry check, before the frame is stored): >1 distinct country_id per
ADM0_A3 → logger.error + ValueError naming each collided code and its ids
(register C-227; ADR-008). Raise, not warn: a forecast frame's entity set
is fixed at its origin, so it never legitimately carries both. Per CODE,
not per (code, month): real transitions put both ids in the same month
anyway (Sudan 59+245 at 379), and the hover props key on code alone.
Detection only — resolution belongs to the producer (pipeline-core
ADR-064). PGM raster/image paths untouched (unreachable at CM).

RED→GREEN in tests/test_mapping_characterization.py::TestDuplicateIsoIsLoud
against the REAL bundle (both 59 and 245 resolve to SDN there); control:
245 alone renders one row.

The guard's first catch was our own test double: the 191-country fixture
e2e tests labelled the map via `mock_isoab_for_index`, which cycles 10 ISO
codes positionally — ~19 country_ids per code, a collision real data never
has. Those tests now use the real bundled metadata (offline since C-22;
zero collisions on the fixture); the double carries a docstring warning.

Latent today (every real forecast fixture carries one member per pair);
elevate C-227 to Tier 1 on the first observed dead-over-live draw.
Register: C-227 registered + resolved, Cluster F; 91 concerns
(68 resolved, 23 open).

Closes #290

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01N7YBtiS2kSVj27spMKDYfh
…loud

fix(mapping): refuse a CM frame with two country_ids under one ISO code (#290)
@Polichinel
Polichinel merged commit e37e2d7 into main Sep 17, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant