Skip to content

Decision needed: GAUL country coding — Kosovo/disputed territories + who owns the GAUL↔VIEWS crosswalk #123

Open

Description

@Polichinel

Ask

We need someone working on this repo to do a deep dive and land a decision (not necessarily code yet) on two connected questions about country coding in the platform's GAUL era:

  1. How should disputed / non-VIEWS territories be coded — Kosovo first among them? GAUL 2024 (FAO's coding) folds Kosovo into Serbia, so any consumer that colours or labels cells by gaul0_code/iso3_code will render Kosovo territory as "Serbia". Is that the platform's intended presentation? If not, what is — a declared override table, a platform-owned coding layer on top of GAUL, something else?
  2. Who owns the GAUL↔VIEWS-country crosswalk long-term? Today there is no bridge between GAUL codes and VIEWS country_id anywhere in the factory; views-reporting has built a makeshift, script-only one for its own needs (details below). If a general solution belongs anywhere, it is probably in the data layer, not in a reporting repo.

Full context (from views-reporting's global-PGM work, 2026-07-20/21)

The first real global PGM ensemble report (views-reporting epic views-platform/views-reporting#230) surfaced this: the models now consume the datafactory (global, 64,818 land cells, country identity = gaul0_code), while viewser's pg_metadata queryset is still Africa+ME-bounded (verified 2026-07-20: 13,110 cells × 852 months; the pgm loa has no global rows). The factory's own grid_to_country_month adapter groups by gaul0_code — GAUL is the factory-era country identity, and no GAUL↔VIEWS crosswalk exists in the factory.

To label global maps, views-reporting built an explicitly interim crosswalk (decision recorded on views-platform/views-reporting#231, PR views-platform/views-reporting#238, risk register entry C-211): GAUL iso3_code → VIEWS isoab → country_id, built from the harvested data/raw/gaul_admin/ parquets (gaul0_code, gaul0_name, iso3_code; full 259,200-cell grid).

Measured facts from that crosswalk (all reproducible from the harvest + VIEWS country table):

  • 66,205 of 259,200 grid cells resolve to a VIEWS country; coverage of the 64,818-cell forecast land region is 99.5%.
  • Grid-wide, 29,373 GAUL-coded land cells have no VIEWS country: Antarctica (ATA) 25,444, Greenland (GRL) 3,038, then the disputed set — Western Sahara (ESH) 101, Jammu & Kashmir (xJK) 75, Arunachal Pradesh (xAP) 23, Aksai Chin (xAC) 11, Hala'ib (xHT) 8, Abyei (xAB), Ilemi (xIT), and assorted small territories. (GAUL's x-prefixed codes mark disputed areas.)
  • Kosovo concretely: GAUL has no Kosovo unit at gaul0 level — its territory is coded SRB. The 10 Kosovo-region cells (gids 190482, 190483, 191201–191204, 191921–191924) therefore map to VIEWS Serbia (country_id 233). VIEWS's Kosovo entity (country_id 232, the platform's only null-isoab country) receives zero cells. This is silent by construction: the cells carry a valid code, so no "unmatched" accounting flags them.
  • ~157 Africa+ME border cells differ between GAUL 2024 and the old viewser assignment (e.g. GAUL puts the Aouzou strip in Chad, viewser had Libya; similar bands on Algeria/Morocco/Tunisia, Turkey/Syria, Somalia/Ethiopia borders).
  • VIEWS isoab is not unique over history (retired states share codes with successors: DEU, ETH, IDN, SAU, SDN, SRB, SUN, TZA, YEM, YUG, ZAF) — any ISO-keyed bridge must resolve duplicates to the currently-active entity; the reporting script does this by most-recent observation.

The makeshift solution in views-reporting (and the ask attached to it)

views-reporting/scripts/build_entity_metadata.py (functions read_gaul_cells, active_country_by_isoab, crosswalk_priogrid) freezes the crosswalk into a bundled parquet (priogrid_id → country_id) that reporting's renderers consume offline. It is a dev-time script, deliberately not shipped in the wheel — nobody can import it, and it is not intended as platform infrastructure. It exists solely so global forecast maps have country labels while the real decision is pending.

If a more general solution manifests here (a factory-owned crosswalk, a platform coding layer, a GAUL-with-overrides standard, anything) — please open an issue in views-platform/views-reporting so reporting can retire the makeshift script and re-source its bundle. The reporting side is architected so this is a build-script-only swap (runtime accessors depend only on the bundle schema), so switching costs are low once a decision lands.

What a resolution could look like (non-binding sketch, from the reporting-side investigation)

  • Kosovo/disputed policy: either (a) accept GAUL's coding as-is and declare it platform-wide, or (b) maintain a small, versioned override table (cell → platform country) applied on top of the harvest — ~10 cells for Kosovo; the x-coded disputed territories would need an explicit stance either way.
  • Crosswalk ownership: a small importable module (factory-side or a shared package) exposing GAUL↔VIEWS mapping with the duplicate-isoab resolution made explicit — so consumers (reporting, postprocessing, CM adapters) agree on cell→country instead of re-deriving it independently.

A cross-repo copy of this issue is being filed in the sibling repo (views-datafactory ↔ views-postprocessing) — coordinate as one decision, not two.

Filed from the views-reporting global-PGM epic; questions → Simon (@Polichinl) or the reporting repo's #231/#230 threads.

Activity

  1. Polichinel commented on Jul 20, 2026

    @Polichinel
    CollaboratorAuthor

    Sibling copy: views-platform/views-datafactory#341 — please coordinate as one decision.

  2. Polichinel commented on Aug 30, 2026

    @Polichinel
    CollaboratorAuthor

    Surfaced by a full inbound sweep: this decision is open in two repositories and owned in neither

    Triaged all 66 open issues across the org that name views-postprocessing (2026-08-26). The sweep was run to close an honesty gap — a /falsify audit had sampled eight of them and said so rather than claiming the sweep was clean.

    Almost everything came back clean. Nothing is blocked by this repository that was not already known. But this issue and views-datafactory#341 are the same decision, filed from both sides, and neither names an owner:

    this issue "Decision needed: GAUL country coding — Kosovo/disputed territories + who owns the GAUL↔VIEWS crosswalk" — open since 2026-07-20
    views-datafactory#341 "We need someone working on this repo to do a deep dive and land a decision" — open since 2026-07-20, one comment

    Both say a decision is needed. Neither says by whom. They have been in that state for 37 days.

    This is not a repository blocking another repository — it is worse. A block has an owner and a queue position. This has neither, so nothing surfaces it: no CI reddens, no trigger fires, no register entry ages. It was invisible until someone read all sixty-six issues by hand.

    Why it will not resolve on its own

    The second half — who owns the GAUL↔VIEWS crosswalk — is the reason. views-datafactory produces the GAUL assignment; this repository consumes it into a pinned lookup and delivers the nine-column contract to partners. Each side can reasonably read the other as the owner, and each has.

    The first half (Kosovo, and disputed territories generally) is a substantive coding decision with an external partner's rendering downstream — GAUL 2024 folds Kosovo into Serbia, so a consumer colouring by gaul0_code renders Kosovo territory as Serbia. That is not an engineering call.

    What would move it

    Not more analysis. A named owner on one of the two issues, and a decision that supersedes both. Flagging rather than assigning, because naming an owner across two repositories is exactly the kind of thing this repo's contributor rules put to the maintainer rather than settling in a comment.

    No action requested from views-datafactory on the strength of this note — the same text is not being posted there, since the useful move is one owner, not two more comments.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions