Eurostat pilot calibration packages: BE, DE, FR - #168
Conversation
|
Rebased over the wave-3 and county merges (#185) and completed the production integration this PR was missing: the branch had fetched and hash-pinned real Eurostat API bytes for all four datasets, but the db/data manifests still wired the packages to the *_test_fixture.json sentinels, so fixture-labeled facts would have entered the bundle. Now flipped to production end to end: manifests select the real artifacts (real sha256/size, content-addressed R2, official dataset labels from the JSON-stat cubes themselves), the sentinel files are deleted, and the fixture-marker test is inverted into a production guard (manifest-selected artifact must be the real dataset file, hash-match its pin, carry ESTAT source, and contain no fixture markers). Added a publisher-value spot test: D2 taxes on production and imports, 2023, decoded independently from the raw cube - BE 72,825.5 / DE 428,710 / FR 446,580 MIO_EUR (x1,000,000 to eur facts). The two Eurostat fetch-manifest lifecycle branches are now strict digest checks, and the Eurostat fetch manifest moved to FETCH-MANIFEST-EUROSTAT.json (FETCH-MANIFEST.json is the county workflow from #185). Merged-bundle pins re-measured over the union; SOL-D2B scaffolding notes removed from the tree. 🤖 Generated with Claude Code |
6add75d to
f00c5a0
Compare
|
Second adversarial review round (gpt-5.6-sol, ultra) independently decoded all 108 cube positions - 107 exact, and its findings are now fixed:
Sol's round also independently confirmed: all artifact hashes/sizes match across fetch manifest, db manifests, packages, and R2 URIs; provenance classes defensible; rebase unions intact; bundle arithmetic exact. 🤖 Generated with Claude Code |
f00c5a0 to
b7f1b9e
Compare
|
Round-3 review confirmed all six prior findings resolved but blocked on the Decimal scaler's blast radius: full-Decimal scaling changed 32 non-Eurostat values across five packages (float(Decimal) can land on an adjacent double for non-integral results - e.g. a Welsh value shifted from 708199216.38 to 708199216.3799999). Rescoped the fix to the actual mutation class: Decimal now decides integrality only. When the true decimal product is a whole number the scaler emits the exact int; every non-integral product returns the pre-existing binary result bit-for-bit. Proven by a full five-package fact diff against the pre-change tree: the changed set collapses from 32 to exactly 4, each an integral publisher value that binary multiplication had emitted with float dust - two SLC recipient headcounts (1028438.0000000001 -> 1028438; 16335.999999999998 -> 16336), Welsh W06000005 council tax income (131972546.99999999 -> 131972547), and the Scottish carer support payment (520700000.00000006 -> 520700000). OBR is untouched. All four corrections are pinned as regressions in tests/test_scale_value.py alongside direct unit coverage of the scaler (exact-int case, bit-preservation of non-integral products, passthroughs, rejections). 🤖 Generated with Claude Code |
b7f1b9e to
2feebc7
Compare
|
Round-4 review found the regression coverage did not discriminate: the rejected all-Decimal scaler passed every new test (verified - my chosen "bit-preservation" cases all land on the same double under both implementations, and the four integral pins agree under both). Replaced with coverage that fails under the rejected implementation by construction, verified with a falsification loop (apply all-Decimal -> 2 tests fail; revert to scoped -> all pass):
🤖 Generated with Claude Code |
2feebc7 to
cb5ee03
Compare
First EUROMOD-country calibration facts through the provenance-classed pipeline: gov_10a_taxag tax revenue and spr_exp_func ESSPROS expenditure as administrative targets; ilc_li02 AROP and ilc_di01 income deciles ingested as survey_aggregate (EU-SILC), evaluation-only by class per the calibration doctrine — the journal convention applies (no "store"). Real API bytes fetched and hash-pinned (three offline-guessed queries corrected against live dataset structures: spr_exp_sum retired → spr_exp_func; SILC dimension names). Implemented by GPT-5.6 Sol, reviewed and integrated with live fetches by the surface owner.
🤖 Generated with Claude Code