…oup health insurance
New source package bea-nipa-private-group-health-insurance reads series
B4923C from the Section 7 workbook BEA published with its 2026 annual
update on 30 September 2026 (Section7All_xls.xlsx, sha256 de1c34e3...), for
calendar years 2023 to 2025: $923,195M, $977,034M and $1,027,929M. The
flat file the other bea_nipa packages pin (fetched 11 May 2026) has
$1,002,920M for 2024.
The series is not an active-employee amount. BEA's State Personal Income
methodology (December 2025, paragraphs 3.18-3.19) says the national
estimates rest on survey data covering insurance purchased by employers for
their active and retired employees, and on Federal Employee Health Benefits
data for active and retired federal civilian employees. Each fact carries
those quotations and that reading as its concept evidence, so a consumer
cannot take the series for contributions for current employees only
(PolicyEngine/microcosm#454).
The package selects the year's own column (column_by_year) and guards the
table title, unit banner, publication date, line number, line label, series
code, both parent lines and footnote 3. A year without a declared column is
refused. The row agrees with the pinned flat file for every year from 1948
to 2023.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
Adds BEA NIPA Table 7.8 line 17, series B4923C, "Private group health insurance": employer contributions for private group health insurance, a supplement to wages and salaries. The package emits one fact per calendar year for 2023, 2024 and 2025.
The series is not an active-employee amount. BEA's State Personal Income and Employment: Concepts and Methods (December 2025), paragraphs 3.18 and 3.19, says the national estimates of employer contributions for group health insurance plans rest mainly on Medical Expenditure Panel Survey data covering insurance purchased by employers "for their active and retired employees" and self-insured plans, and, for "active and retired federal civilian employees", on Federal Employee Health Benefits data. Each fact carries those quotations, and the reading drawn from them marked as Chronicle's own, as its concept evidence (
concept_alignment.evidence_notesandevidence_url).How the series is tied to that text: BEA's series register lists B4923C, "Group health insurance", at
T61100D:32|T70800:17. The NIPA Handbook (chapter 10, Table 10.B, line 32) names the same MEPS and OPM sources and does not say whether retired employees are covered. Table E of the state methodology gives 1,011,360 for group health in 2024, which matches neither NIPA vintage here. The other Table E lines I checked (compensation, supplements, employer contributions for pension and insurance funds, group life, workers' compensation) are not in the pinned NIPA flat file at 2024 either, so the gap is not particular to group health. The files support retiree coverage as a category and no numerical equivalence.Consumer context: PolicyEngine/microcosm#454. An earlier draft of that work, and the first version of this PR's description, read B4923C as an active-worker series and planned to calibrate
employer_sponsored_insurance_premiumsto it. That reading was wrong, and no calibration target or feed re-pin follows from this PR. The fact is banked as a national-accounts cross-check, with the 2024 revision on the record. Facts are inert until a consumer re-pins its feed.Source
source_pagein the manifest).chronicle fetch-artifact: 944,273 bytes, SHA-256de1c34e37da9b8b8d765efc0611cc653102373fe522fe9218c7689067b29b7fd,Last-Modified: Wed, 30 Sep 2026 12:30:04 GMT.T70800-Areads "Data published September 30, 2026" and "[Millions of dollars]".ledger-rawwithchronicle publish-rawat the manifest's content-addressed key, read back and hash-verified. Mirrored tochronicle-rawat the same key, as the pinned BEA flat file is, and read back and hash-verified there too.The two pinned BEA files differ at 2024. The flat file the other
bea_nipapackages pin (fetched 11 May 2026) has B4923C at 1,002,920 for 2024; the workbook, published with BEA's 2026 annual update on 30 September 2026, has 977,034. BEA's Section 6 workbook of the same date carries the same series as Table 6.11D line 32, "Group health insurance", with the same three values (checked, not packaged).What changes
db/data/bea/nipa_private_group_health_insurance/: the workbook and its manifest.packages/bea/nipa_private_group_health_insurance/source_package.yaml: one record set,bea_nipa.cy{year}.private_group_health_insurance.xlsx_used_rangerestricted to sheetT70800-A(the workbook has 46 sheets),artifact_year: 2025.amount, withcolumn_by_yearCA/CB/CC and a header guard per year. Ids follow thebea_nipaconvention:bea_nipa.cy2024.private_group_health_insurance.b4923c.amount.person/employee/compensation_of_employees/model_output. Conceptbea_nipa.private_group_health_insurance, relationsource_label, authoritybea, with the coverage statement above as concept evidence.dimension_value_labelsdeclares B4923C as "Private group health insurance", the guarded line stub without its indentation and footnote marker.bea-nipa-private-group-health-insuranceis registered inSOURCE_PACKAGE_ALIASES. It is not added to the hard-target coverage contract (chronicle/targets/us_poverty.py), because no consumer targets it.No existing package, schema or contract changes.
Chronicle governance
ledger-source-ingestor. As in Add IRS SOI Historic Table 2 TY2023 state AGI-band facts #291, Add HMRC CGT Table 4 BADR and Investors’ Relief facts #288 and Add HMRC CGT Tables 7–9 source packages #273, the change also touchesdb/dataand the alias map, which the role file does not list.767c89e6(the package files are unchanged in the merge head08c229e9):chronicle validate-package bea-nipa-private-group-health-insurance --year {2023,2024,2025}: valid at each year.chronicle build-suite ... --year {2023,2024,2025}: valid at each year, with 1 fact, 3,483 source cells, lineage coverage 1.0 and 0 agent-acceptance errors.chronicle build-bundle --year 2023 --source bea-nipa-private-group-health-insurance: valid, with 1 fact, no warnings and no duplicate keys.openpyxlon the publisher file gives row 26 as line17,Private group health insurance\3\,B4923C, and 923195 / 977034 / 1027929 under the 2023 / 2024 / 2025 headers.aa943a9f, summarised in a comment:ledger-source-fidelity: PASS. It re-read the workbook withopenpyxland from the sheet XML, re-hashed it, and repeated the 76-year comparison with the flat file.ledger-contract: PASS. No schema or identity change.ledger-boundary: PASS. Source selection and unit normalisation only; the flat-file comparison is a test, and a supported coverage note is within remit, as in the CBO and CMS packages.767c89e6: one quotation's capitalisation, a test comment that attributed the scope inference to BEA, and wording that dated the older flat file more precisely than its files establish.aa943a9fto767c89e6delta returned approve for767c89e6as a whole, with all three verdicts PASS and no findings. Both are summarised in comments.Invariants (tested in
tests/test_chronicle_bea_private_group_health_insurance.py)record_set_spec_id.Tests
tests/test_chronicle_bea_private_group_health_insurance.py(28 tests).tests/test_chronicle_bundle.py: default-bundle pins moved by the one CY2023 fact the bundle year emits. Against main at244a1281: facts 1,002,783 to 1,002,784, packages 321 to 322,bea445 to 446, source tables 316 to 317,calendar_year:2023,country:0100000USandpersoneach +1. I derived the increments from the single-source bundle above and did not run the full default bundle locally.767c89e6against the earlier main (3dce46a6) and passed: bundle, surface and the aggregate check.08c229e9merges main and resolves each conflict as main's value plus one; CI is re-running the full bundle on it.tests/test_chronicle_artifact_year_restamp.py: the package joins the representative pinned packages built on real bytes.042d5ffd, same selectors and guards, before the concept evidence was added): 406 passed over the new file plustest_chronicle_source_package.py,test_chronicle_consumer.py,test_chronicle_suite.py,test_chronicle_artifact_year_restamp.py,test_chronicle_pe_source_plan.py,test_source_files.py,test_chronicle_offline_fetch.py,test_issue_261_dimension_labels.py,test_issue_265_non_uk_labels.py,test_ots_anchor.pyandtest_ots_anchor_workflow.py.767c89e6, and again at the merge head08c229e9: 131 passed over the new file plustest_source_package_alias_drift.py,test_us_poverty_target_coverage.py,test_chronicle_governance.py,test_chronicle_boundaries.py,test_chronicle_facts_only.py,test_chronicle_artifact_year_restamp.pyandtest_chronicle_concepts.py.ruff check chronicle policyengine_chronicle db scripts testspasses.🤖 Generated with Claude Code