Repository navigation
S5 (#186) — the lookup declares its own version instead of the consumer inferring it - #201
Merged
Merged
Conversation
…f the consumer inferring it gaul_lookup.version() reconstructed the delivery's traceability stamp by traversing three levels of views-datafactory's ingestion-ledger shape (source_provenance -> land_gaul_region -> content_digest) inside a bare `except (ValueError, AttributeError): pass`, returning the string "unknown" when any level was absent or reshaped. A rename upstream would therefore have made every delivery untraceable, silently, in the one field C-15 exists to answer AFTER a suspect delivery. Nothing would have noticed: a provenance record was still written; it just stopped meaning anything. That is the declare-don't-infer violation ADR-003 forbids, at the consumer. The builder now composes the stamp — it is the only thing holding both the region and the producer's ledger — and writes it as one flat `lookup_version` key. The consumer reads that key and RAISES when it is absent, logging first (ADR-008). The json import and every exception handler are gone from the module. An untraceable build fails at BUILD, not at delivery. _provenance is best-effort by design; a missing ledger used to surface as a placeholder in production, and now surfaces where a human is present to fix it. Review caught the fix reintroducing its own defect class one level up. The first draft read `land_gaul_region or gaul_admin_area_majority`, and since _provenance does not take a region, land_gaul_region is present for EVERY build — so `--region all` would have been stamped `all@f74d3b2b`, the land_gaul region definition's digest, on a global artifact. Authoritative-looking and wrong, silently. Replaced by a declared `stamp_dataset(region)`: area-majority for `all`, `<region>_region` otherwise, and a region whose entry is absent is refused rather than substituted. Verified: all -> all@272cdb01, land_gaul -> land_gaul@f74d3b2b, africa_me_legacy -> refused. The committed artifact is rebuilt. Proven metadata-only: 64,742 rows, column order and dtypes unchanged, a content hash over every column's values IDENTICAL, and the stamp resolves to land_gaul@f74d3b2b — the same string the old traversal produced, so no delivered provenance changes meaning. tests/test_gaul_lookup_fidelity.py (now 26) still compares it value-for-value against the seven datafactory parquets. ADR-013 is untouched: contract_version 1.5, fixtures byte-identical, and the sidecar cannot inherit lookup metadata because build_sidecar constructs a fresh table. Also from review: the ledger is append-only and the LAST entry per dataset wins, which was harmless while provenance was decorative and is load-bearing now that the stamp raises — stated in _provenance rather than left in the loop. Digest length is declared so producer and consumer agree on what a valid stamp is. And the GaulLookupEnricher CIC still documented the "unknown" degrade this removes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…oduced its own defect The entry closes citing the tests, with the sidecar-stamping residual deferred behind a named trigger (the next ADR-013 version bump) rather than a vague later. Kept visible in the resolution: the first draft of the fix reintroduced C-60's own defect class — a silent fallback that would have stamped `--region all` with the land_gaul region's digest. The reflex that produced the concern reappeared while fixing the concern, and that is worth more to a future reader than a clean narrative. Cluster K now has one entry left: C-46. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #186. Closes register C-60. Part of epic #181.
The defect
gaul_lookup.version()produced the stamp that ties a delivered artifact to the lookup build that made it — C-15's traceability field, the thing you would need after a suspect delivery to answer "which lookup produced this?"It got that stamp by reaching three levels into views-datafactory's ingestion-ledger shape:
A rename upstream makes every delivery untraceable, silently. The provenance record is still written; it just stops meaning anything, and no gate can tell the difference.
The fix
The builder composes the stamp — it is the only thing holding both the region and the ledger — and writes one flat
lookup_versionkey. The consumer reads that key and raises. Thejsonimport and every exception handler are gone from the module; a test asserts that by AST rather than by word-matching.An untraceable build now fails at build time, where a human is present, instead of surfacing as a placeholder in production.
Review caught the fix reintroducing its own defect
The first draft read:
_provenancedoes not take a region, soland_gaul_regionis present for every build.--region allwould have been stampedall@f74d3b2b— the land_gaul region definition's digest, on a global artifact. Authoritative-looking, wrong, silent: C-60's own defect class, one level up.Replaced by a declared rule with no fallback:
Verified against the real ledger:
allall@272cdb01land_gaulland_gaul@f74d3b2bafrica_me_legacyThe rebuilt artifact — metadata-only, proven
land_gaul@f74d3b2bland_gaul@f74d3b2bThe stamp is the same string the old traversal produced, so no delivered provenance changes meaning.
The reproducible evidence is
pytest -q tests/test_gaul_lookup_fidelity.py— 26 tests comparing the artifact value-for-value against views-datafactory's seven source parquets, plus gid-set equality, key uniqueness, the coordinate formula, and the absence of nulls and-1sentinels. That is a stronger claim than a byte hash because it re-runs on every push.The wire is untouched
contract_versionstays 1.5;git diff origin/main -- tests/fixtures/is empty. Verified empirically before scoping the story:build_sidecarconstructs a freshpa.table(columns), so lookup parquet metadata cannot reach the wire — the sidecar's schema metadata is[].Other review findings
F2 —
docs/CICs/GaulLookupEnricher.mdstill documented the"unknown"degrade. Corrected to state the raise and nameLookupVersionError. Third story running where the CIC lagged; noted for S9 — it is in no story's default file list, so it is only updated when someone remembers.F3 — the ledger is append-only (14
gaul_admin_area_majorityentries, 2land_gaul_region) and the last per dataset wins. Harmless while provenance was decorative; load-bearing now that the stamp raises. Stated in_provenancerather than left implicit in the loop.F4 —
[:8]would have emittedland_gaul@abcdfrom a 4-char digest: accepted by the builder, rejected by the test. Digest length is now declared and enforced on both sides.F5 — dropped a comment implying parquet metadata key order is meaningful.
Verification
Register: 74 concerns, 20 open after C-60.
🤖 Generated with Claude Code