Skip to content

S5 — build_gaul_lookup.py: pyarrow-native build #90

Closed

Description

@Polichinel

Epic: #85 · S5 · [UNILATERAL — lowest priority]

Background

scripts/build_gaul_lookup.py builds the GAUL lookup parquet from views-datafactory's source parquets using pandas + pyarrow. It runs offline, outside the delivery path, so it touches nothing interconnected and has zero samples relevance. Pandas-free for completeness only.

Work

  • Make the builder pandas-free (pure pyarrow): the join/filter/dtype/sort steps currently done with pandas (build_gaul_lookup.py ~:71-166) reimplemented on arrow tables; keep the embedded provenance metadata that _read_version reads.

Acceptance criteria

  • The builder produces a lookup parquet identical to the current one from the same datafactory inputs (table contents + embedded provenance metadata).
  • No pandas import in the script.

Parity / validation

Build the lookup both ways from the same inputs; assert identical arrow table and identical provenance metadata. (Downstream tests/test_enrichment.py lookup-integrity assertions must still pass against the rebuilt file.)

Dependencies

Independent; lowest urgency. Keep in sync with S4 and gaul_schema.py (the 9-column contract + rename map).

Files

scripts/build_gaul_lookup.py.

Activity

  1. Polichinel commented on Aug 2, 2026

    @Polichinel
    CollaboratorAuthor

    Collision with epic #181's S5 (#186) — read before starting this.

    Both stories rewrite scripts/build_gaul_lookup.py, and #186 lands first.

    This issue's acceptance criterion is "produces a lookup parquet identical to the current one from the same datafactory inputs (table contents + embedded provenance metadata)". #186 deliberately changes the embedded metadata — it adds a flat declared lookup_version key so the provenance stamp can no longer silently degrade to the string "unknown" (register C-60), and rebuilds the committed artifact. Table contents stay identical; metadata does not.

    Also stale here: this issue says "keep the embedded provenance metadata that _read_version reads". _read_version moved out of enrichment.py to contract/gaul_lookup.version() in #152, and #186 rewrites it to read one declared key and raise when it is absent.

    Re-baseline this issue's parity target against the tree after #186 merges.

  2. Polichinel commented on Aug 2, 2026

    @Polichinel
    CollaboratorAuthor

    #186 has now merged (#201) — this issue's parity target needs re-baselining.

    The builder's embedded metadata changed as predicted: it now writes a flat, declared lookup_version key, and refuses a build whose ledger yields no digest for the region's declared stamp dataset (stamp_dataset(region) — area-majority for all, <region>_region otherwise, no fallback).

    So this issue's "produces a lookup parquet identical to the current one … + embedded provenance metadata" should now read: table contents identical, metadata including the lookup_version key the pandas-free builder must reproduce byte-for-byte.

    Also: _provenance now takes a required datasets keyword, and _read_version no longer exists anywhere — the reader is contract/gaul_lookup.version(), which reads one key and raises.

  3. added 4 commits that reference this issue on Aug 3, 2026
  4. Polichinel commented on Aug 4, 2026

    @Polichinel
    CollaboratorAuthor

    Done in #220 — the builder is arrow-native.

    Proven against the real producer rather than asserted. Rebuilt land_gaul from the views-datafactory checkout and compared to the committed artifact: 64,742 rows both sides, identical column order, identical schema types including dictionary<string> on the four name columns, all ten columns value-identical, and every declared metadata key byte-for-byte — adr, region, n_cells, n_dropped_incomplete, source_provenance, and lookup_version (land_gaul@f74d3b2b).

    That is this issue's re-baselined acceptance criterion exactly: contents identical, flat declared lookup_version reproduced byte-for-byte.

    One deliberate difference: no pandas schema-metadata blob. It described an index arrow does not have, the only consumer reads the file as arrow (contract.gaul_lookup.load), and reproducing it would have meant keeping pandas' metadata format in the one script this change removes pandas from.

    The committed artifact is not regenerated. The builder is what this issue asked for; rewriting a delivered artifact is a separate act with no delivery benefit.

    Two register entries moved with it: C-76 closed (the builder refuses a zero-row result — and the guard failed its own first mutation test, because on an empty table pa.array([True] * 0) infers NULL type and pc.and_ raised before the check could speak), and C-75 decided: retire GaulLookupEnricher — zero production callers, its build/verification justification spent, holding the package's last pandas reference, duplicating a shipping gather that four test files cover independently.

    That retirement is the next change, not this one — it touches ten files including a CIC and ADR-012, and mixing it with a builder rewrite is what epic #148's S5 refused to do.

    #85 and #93 stay open until it lands — their claim only becomes true when that module is gone.

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

    implementationCode implementation workstoryA single reviewable unit of an epic

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions