Repository navigation
UK occupation facts for chronicle#407: APS employment by SOC 2020 group (Nomis APS218) and ASHE Table 2 pay by two-digit SOC - #411
Conversation
Pin three Nomis API responses for APS218 (NM_218_1), people in employment by SOC 2020 group, sex and employment type for the UK, its countries and the English regions: April 2024 to March 2025, January to December 2025 and April 2025 to March 2026. Pin ONS's ASHE Table 2 zips for 2024 revised, 2025 revised and 2026 provisional; each will back four packages, one per workbook member. The manifests record the OGL evidence, and the Nomis ones the query and Nomis's revision metadata for the period. Nothing is in R2 yet: `chronicle publish-raw` uploads them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The register labelled soc2020_major_group=3 "Associate professional and technical occupations", the SOC 2010 name the ASHE pension tables print. ASHE Table 2 and Nomis APS218 print SOC 2020's "Associate professional occupations". The fifteen chronicle#407 packages word it that way against the pension tables' five, so the register takes it by its majority rule, and CHOSEN_LABELS records the choice. The five pension packages that declare the value now declare the register's label; their row headers and row labels keep ONS's text. No fact, key or count changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
For PolicyEngine/microcosm#1490's report-only occupation check. scripts/build_uk_occupation_packages.py writes fifteen packages from the pinned bytes, asserting the publisher's text cell by cell: - ons-aps218-occupation-*, 24,956 facts: Nomis APS218 people in employment by SOC 2020 major and sub-major group, sex and employment type (all, employees, self-employed), for the UK, its countries and the English regions. April 2024 to March 2025 is fiscal_year 2024, January to December 2025 calendar_year 2025, and April 2025 to March 2026 fiscal_year 2025. Each estimate has the half-width of its confidence interval where Nomis publishes one. Cells Nomis blanks (F, H) emit no fact. An estimate whose interval Nomis withholds (G, F) carries the interval's status in its lineage. The July-June and October-September windows, including the latest, have no Chronicle period type and are not ported. - ons-ashe-table2-*, 48,083 facts: ASHE Tables 2.1a and 2.7a, gross weekly and annual pay (jobs, median, mean and ten percentiles) by two-digit SOC 2020, sex and working pattern, UK, for 2024 revised, 2025 revised and 2026 provisional, with the CVs of Tables 2.1b and 2.7b. Cells marked 'x' emit no fact. Weekly pay takes the survey year, annual pay the tax year it covers. The 2025 revised Table 2.7a prints the police group (33) that the 19 December 2025 notice suppressed in 2025 provisional. Parity, asserted by the generator and the tests: - each major group's sub-major groups, the countries and the regions add to their totals within Nomis's rounding; - the major groups add to slightly less than the all-occupations total, since Nomis publishes no residual category; - each edition's full-time median weekly and annual pay matches its bulletin's headline. The label register lists the values the packages share. The merged-bundle pins move by the measured +73,039 facts. That test, like the consumer export, waits on `chronicle publish-raw` for the six artifacts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`chronicle publish-raw` uploaded the three Nomis APS218 responses and the three ASHE Table 2 zips to ledger-raw and wrote each manifest's storage.r2 block. `chronicle verify-raw` read every object back: key, SHA-256 and size match. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Review of c250f44. I checked the source pins against the live publishers, re-fetched a sample of Nomis cells and all three ASHE zips, read the generator's status handling and parity checks, the registration and pin changes, and how the facts line up with what PolicyEngine/microcosm#1512 will compare against. I found nothing blocking. One convention point and two small doc fixes are listed below. Should
Nit
Checked and fine
For the PolicyEngine/microcosm#1512 report-only check (not a change here):
CI at c250f44: Chronicle bundle, Chronicle surface and Chronicle checks all pass. The surface job runs Verdict: the sources are pinned and reproducible, and the sample matches the live publishers exactly. Only the concept point (Should 1) and the two nits remain. 🤖 Generated with Claude Code |
From the review of #411. An APS confidence interval and an ASHE coefficient of variation shared their estimate's concept, unit and aggregation, so a reader selecting by concept and dimensions could get both and sum them. Following the ACS margins of error, the APS intervals are now ons.aps_people_in_employment_confidence_interval_half_width, and each ASHE CV takes its estimate's concept with the suffix _coefficient_of_variation. The statistic dimension stays. A new test asserts that concept, aggregation, period, geography and every dimension but statistic select exactly one fact. The doc's R2 paragraph is replaced now that the six artifacts are uploaded, and the tests require the storage block and a valid consumer contract. The doc and the package headers also say that a record set's detail rows hold both SOC levels, so a reader selects one level and never sums across both. Fact, period, geography and table counts don't change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks, Vahid. All three points are in 6c995aa:
No fact, period, geography or table count moves. Your notes for PolicyEngine/microcosm#1512 are about the Microcosm check (people in work only, dropping estimates without an interval, the nine majors as the share denominator), so nothing changes here for them. 🤖 Generated with Claude Code |
…ex (#1490) The UK contract binds 52 more calibration targets from the ONS Annual Population Survey (Nomis APS218, January to December 2025, through PolicyEngine/chronicle#411): people in employment in each of the 26 SOC 2020 sub-major groups, for women and for men, at UK level (family ons_occupation, category ons.employment). María's ruling of 5 November 2026: with only the major groups bound, the sub-major draw left 16 of the 26 UK sub-major groups, and the mix of women and men inside many of them, outside the APS's confidence intervals on the calibrated frame. The sub-major groups by region are not bound: their intervals are wide, and in an offline cross-validation of the national solve, binding them did not improve the cells held out. Each target counts the people whose soc2020_sub_major_group is that group, whose gender is that sex and whose employment_status is full-time or part-time employed or self-employed, summed to households. Women and men together fix each sub-major group's UK total, which nests in its major group's regional rows, so the totals are not bound separately. Nomis rounds each cell to the nearest hundred, so each pair adds to the all-persons figure within 100. soc2020_sub_major_group joins the reviewed plain-column filters. The national references gain the 52 rows and nothing else moves: the national compile-parity receipt adds 52 ledger-only rows, every other entry unchanged, and the local surface cannot move. The changelog fragment now covers the major and the sub-major rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This PR adds the published occupation totals #407 asks for, for PolicyEngine/microcosm#1490's report-only occupation check: ONS's Annual Population Survey estimates of people in employment by SOC 2020 group, from Nomis, and ONS's ASHE Table 2 pay by two-digit SOC. It covers every ask but one: Nomis's July-to-June and October-to-September windows, including the latest (Jul 2025-Jun 2026), have no Chronicle period type (see Open points).
What it adds
Fifteen packages, 73,039 facts.
scripts/build_uk_occupation_packages.pywrites them from the pinned bytes and asserts the publisher's text cell by cell;--checkcompares instead of writing. Field contracts and caveats are indocs/data-sources/uk-occupation-facts.md.ons-aps218-occupation-{apr-2024-mar-2025,jan-dec-2025,apr-2025-mar-2026}(24,956).ons.aps_people_in_employment_confidence_interval_half_widthandstatistic: confidence_interval_half_width. Nomis doesn't state the interval's level, so the id names none.fiscal_year2024, the FRS 2024-25 year;calendar_year2025;fiscal_year2025;period_coverage, as the house-price packages store a year ending in March.ons-ashe-table2-{weekly,annual}-pay-gross[-cv]-{2024-revised,2025-revised,2026-provisional}(48,083)._coefficient_of_variation(for exampleons.ashe_gross_weekly_pay_coefficient_of_variation), the estimate's dimensions andstatistic: coefficient_of_variation.calendar_yearY, with the survey reference date the bulletins give (17 April 2024, 30 April 2025, 22 April 2026).tax_yearY-1.…without_p90).Reading the facts
statisticvalues, so selecting by concept and dimensions gives one fact.soc2020_major_grouporsoc2020_sub_major_groupand never sum across both.Labels
chronicle/dimension_values/canonical_labels.json:soc2020_group(the groupby axis, 36 values) andsoc2020_sub_major_group(26);employment_statusandworking_pattern(3 each);earnings_percentile(10);statisticvalues.soc2020_major_group3 changes from the SOC 2010 name the ASHE pension tables print to SOC 2020's "Associate professional occupations", which ASHE Table 2 and Nomis print. Fifteen packages word it that way against five, andCHOSEN_LABELSrecords the choice. The five pension packages' declarations follow the register; their facts and row headers don't change. That's its own commit.Licences
Nomis's copyright page puts ONS material under the OGL; the ASHE dataset page states the OGL v3.0. The manifests quote both.
Parity
Asserted by the generator and by
tests/test_source_uk_occupation_facts.py:Pins
fact_count/row_count1,662,950 → 1,735,989 (+73,039, all of them person facts from ONS).country:K02000001+49,991 andcountry:E92000001+1,902.Chronicle Governance
ledger-source-ingestor. Paths outside its list, as earlier source PRs declared:db/data/**and.gitattributes;chronicle/source_package.py,chronicle/bundle.py(registration) andchronicle/dimension_values/canonical_labels.json;scripts/build_uk_occupation_packages.py(new), andCHOSEN_LABELSinscripts/build_dimension_value_register.pywith its count intests/test_dimension_value_register.py;docs/**andchangelog.d/**.ledger-source-fidelity: pending.ledger-contract: not applicable; no schema, identity or consumer-contract change.ledger-boundary: pending.Tests
validate-packageon all fifteen: valid, with no warnings.build-suiteand agent acceptance on all fifteen: valid, with no errors or row-semantic errors. The only warning isconcept_alignment_validation_skipped, since Axiom isn't run.publish-rawuploaded the six artifacts, andverify-rawconfirms each object's key, sha256 and size.tests/test_source_uk_occupation_facts.py: 13 passed. It covers:statisticselect exactly one fact;ruff checkon every edited Python file.Review
Vahid's review of c250f44 is addressed in 6c995aa. The interval and CV facts now have concepts of their own (Should 1). The doc's R2 paragraph is replaced, and the tests require the R2 blocks and a valid consumer contract (nit 1). The doc and package headers say to select one SOC level (nit 2).
Open points
🤖 Generated with Claude Code