Base-builder imputation stages: CDCC adult-care leg + SE health ALD attribution (#451 items 1–2) - #500
Merged
Merged
Conversation
… health ALD (#451 items 1-2) Item 1: new adult_care_inputs stage (adult_care_post_clone) derives is_incapable_of_self_care from the measured ASEC PEDISDRS self-care item and assigns pre_subsidy_care_expenses via a seeded, weight-targeted, distribution-preserving draw from the measured ASEC childcare-expense class, restricted to tax units where IRC 21 can bind (21(b)(1)(B)/(C) prongs, 21(d) work test with 21(d)(2) spouse deeming). Source decision receipts (Census API dictionaries): neither ASEC 2024 nor SIPP 2023 measures in-household adult-care dollars (SIPP's TDPCAREAMT covers a former household member), so the dollar leg is a documented same-instrument proxy; the flag is directly measured. Item 2: new deterministic attribute_self_employed_health_premiums operation on the other_health_insurance_premiums release stage ships health_insurance_premiums + is_self_employed (the engine's 162(l) adds-chain computes the ALD; the SE-premium variable itself is formula-owned and cannot ship). A Medicare proxy (age 65+ | SSDI>0) keeps medical_expense_health_insurance_premiums numerically invariant. Measured on certified N (c3e378a-20260722T010408Z): $48.09B attributed, baseline ALD $31.24B vs the SOI 1.4 TY2023 fact $31.23B (ledger#105). Coverage manifest: four new required leaves + two neutralization probes (floors $1B / $40M against measured -$4.58B / -$193.3M on income_tax). No changes to build_us_fiscal_refresh_release.py (#491 in flight) or any calibration-loss machinery (#492 doctrine). Refs #451 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…round 1) Blocking finding: the new stages were wired in the builder but missing from the public plan and audit surfaces. Adds adult_care_inputs to US_DONORS/US_STAGE_NAMES, both stages' leaves to the L0/refit export required-person contract, the adult-care gate receipt to the monolithic summary and staged required_signals, and the four leaves to the runtime POST_REFERENCE_ECPS_REQUIRED_INPUTS mirror (manifest-currency drift). is_incapable_of_self_care leaves US_DOCUMENTED_ABSENT_INPUTS: the adult_care_inputs stage seeds it from measured ASEC PEDISDRS, which is the direct instrument item the register entry believed absent (minimal edit to build_us_fiscal_refresh_release.py; rebase after #491 lands). Should-fixes: the SE signal gate now fails closed on null/non-boolean flag values and nonfinite identity sources (astype(bool) silently read NaN as True; NaN income silently read as not-self-employed), with tests for both reproduced cases; the SIPP receipt is vintage-scoped (the 2018 panel's Child & Dependent Care module collected ECREPAYANYON/TDEPNDNTEXP but the 2023 PUF - the pinned donor vintage - does not release them); the five bare-input state/local consumers of health_insurance_premiums are enumerated in the shipped stage notes. Refs #451 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The shared npz keeps only household 20, so the new columns must stay nonconstant on that post-selection subset for the tightened export contract. Refs #451 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
MaxGhenis
force-pushed
the
cdcc-sehi-imputation-451
branch
from
July 22, 2026 15:45
bb56a6e to
406134b
Compare
… gates (sol round 2) Blocking fixes: the 21(d)(2) work test now computes exactly the engine's min_head_spouse_earned binding condition (deeming never rescues a unit whose only earner is the floor-eligible spouse; directional regression test), extended to the measured full-time-college-student floor; the SE attribution excludes measured employer-sponsored coverage (has_esi), the conservative proxy for the 162(l)(2)(B) subsidized-plan month exclusion (remeasured: $16.37B / 1,402 carriers / ALD $11.97B; the earlier $31.24B near-match of the SOI fact was compositionally lucky and included statutorily excluded months); the adult-care gate is now a real heal certificate (strict bool/numeric flag validation incl. pandas-3 str columns, PEDISDRS identity when present, carrier-must-qualify and one-carrier-per-unit structure checks, $250k plausibility ceiling). Should-fixes: seeded selection is invariant to person-row order (sorted unit ids, smallest-person-id placement, shuffle test); weighted-quantile pairing drops zero-weight donors and grids on the selected units' own cumulative weights; person_support_channel is a required pinned source instead of defaulting to all-ASEC; donor-universe notes state the measured SPM-grain approximation precisely; string flags fail both SE and adult gates; the builder failing-gate parametrization and frame-flow assertions cover adult_care; the taxpayer-alone test asserts the surviving unit receives the expense. 21(b)(1)(A) citation corrected. Probe floors and reasons regenerated from the post-fix rerun on the certified N frame: SE -$1.449B (floor $300M), CDCC adult care -$153.9M (floor $30M). Refs #451 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
Author
|
Cross-family review, round 2 (sol, read-only, judgment tier): 5 blocking, 7 should-fix, 1 nit on the round-1 state. Every finding verified against the engine/pinned sources before acting; all are fixed on this branch, with the measured receipts rerun afterward. Disposition:
CDCC adult-care numbers moved with the order-invariant selection: 137 carriers / $3.41B / probe −$153.9M (floor $30M). The PR body and shipped probe reasons carry the post-fix numbers; the earlier #451 receipts comment is corrected in a follow-up there. |
This was referenced Jul 22, 2026
MaxGhenis
added a commit
that referenced
this pull request
Jul 24, 2026
…ersedes #514) (#519) * Add JCT tax-expenditure targets for ALD components + CDCC Following Max's ask on 2026-07-23 to close RCC calibration gaps surfaced in the refundable-credit-conversion validation tab. Value-free target references only — anchor values resolve from the external PolicyEngine Ledger fact stream. Adds six JCT tax-expenditure references, each pointing to a PE-US above-the-line-deduction variable currently untargeted on the sparse Build O calibration surface: - self_employed_health_insurance_ald - health_savings_account_ald - student_loan_interest_ald - self_employed_pension_contribution_ald - traditional_ira_contributions - cdcc (child and dependent care credit) Motivation for each, from the shipped RCC validation table (2026 PE Build O vs JCX-45-25 anchors): - ALD toggle: PE $45B vs JCT $116B (-60.8%). Sum of five untargeted ALD components; letting the calibrator hit them individually should tighten the aggregate. - CDCC toggle: PE $4.3B vs JCT $1.7B (+152%). Build O's pre_subsidy_care_expenses landing pushed the base above JCT; a total-CDCC target lets the calibrator pull it back down. Ledger anchor facts needed (external, likely already in flight alongside #500/#451): - jct.tax_expenditures.cy2024.self_employed_health_insurance_deduction.revenue_loss - jct.tax_expenditures.cy2024.health_savings_account_deduction.revenue_loss - jct.tax_expenditures.cy2024.student_loan_interest_deduction.revenue_loss - jct.tax_expenditures.cy2024.self_employed_pension_contribution_deduction.revenue_loss - jct.tax_expenditures.cy2024.traditional_ira_deduction.revenue_loss - jct.tax_expenditures.cy2024.child_and_dependent_care_credit.revenue_loss Test surface: extends REFERENCE_JCT_TAX_EXPENDITURE_TARGETS in test_us_fiscal_targets.py so the declared-registry test picks up the new entries. Full fiscal-targets test suite (4 relevant tests) passes. Follow-ups (not in this PR): - HoH filing-status filer-count SOI target (HoH toggle scored $18.9B on dense f0af251 vs $9.5B on sparse Build O — sparse HoH thinner). - QBI SOI Table 1.4 target expansion (currently 1 target, -20% residual; toggle -30% vs JCT). - Auto-loan interest OBBBA target (JCX-22-25R $10.2B). * Add OBBBA auto-loan-interest JCT tax-expenditure target Extends the RCC target adds with the auto-loan interest deduction (OBBBA §70402), rounding out the four OBBBA-composition follow-ups called out in the shipped refundable-credit-conversion validation tab. Ledger anchor: jct.tax_expenditures.cy2024.auto_loan_interest_deduction.revenue_loss Neutralized PE-US variable: auto_loan_interest_deduction (tax_unit). Fits the same JCT tax-expenditure schema as the other entries. Whether 2024-law revenue-loss activates on non-2026-law build periods follows the same fence Max applied to jct.obbba_title_vii in #499 — if a target-parity fence is needed, add it via _FAMILY_EXCLUSIONS in tools/build_us_target_parity_manifest.py alongside the existing jct.obbba_title_vii exclusion. * Drop auto-loan reference per Max's #514 review OBBBA §70203's auto-loan interest deduction has no cy2024 tax-expenditure line — JCX-48-24 predates OBBBA and the provision is effective tyba 12/31/24, so a 2024 expenditure row is structurally zero. Anchor belongs in the jct.obbba_title_vii revenue-effect family (JCX-35-25) with the period fence and activation path established in #499, not as a cy2024 tax_expenditures entry. Leaves six ALD components + CDCC in this PR; auto-loan goes through the OBBBA-anchor pathway separately. * Re-point the CDCC anchor to the combined-concept id; add broad-fit notes Takeover edits per the #514 review thread (author out until Monday): the ledger#118 curation established JCT publishes the CDCC combined with the employer-care exclusion, so the reference now points at cdcc_and_employer_child_care_exclusion with the concept note; the Keogh/IRA rows carry net-exclusion broad-fit notes. Auto-loan was already dropped by the author per review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: David Trimmer <david@policyengine.org> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.
Base-builder imputation stages for the CDCC adult-care leg and the SE health ALD (#451 items 1–2)
Delivers the two Deliverable-2-class increments from #451 (input-coverage readiness quartet): both were structural zeros on every certified export — no adult/disabled-dependent care input existed at all, and the $339.6B bulk premium mass carried no self-employment attribution, so the §162(l) ALD computed exactly $0.
Item 1 —
adult_care_inputsbase-builder stage (CDCC adult-care leg)New checkpointed stage
adult_care_post_cloneintools/build_us_puf_support_base.py(afterchildcare_post_clone), producing two person inputs:is_incapable_of_self_care← measured ASECPEDISDRS== 1 ("difficulty dressing or bathing", the self-care difficulty item). This is the §21(b)(1)(B)/(C) qualifying-individual test and the §21(d)(2) deemed-earnings gate in PolicyEngine-US 1.764.6.pre_subsidy_care_expenses— the CDCC adult-care dollar leg (feedscare_expenses→cdcc_relevant_expenses).Source decision (ASEC vs SIPP), with receipts
Read from the Census API variable dictionaries this session (ASEC 2024: 1,051 variables; SIPP 2023: 5,202 variables):
PEDISDRS("Disability - Difficulty dressing or bathing") — already ingested by the eligibility stageESELFCARE(identical item, corroborates)HCHCARE_VAL"Annual amount paid for child care",SPM_CHILDCAREXPNS)TDPCAREAMTis "money paid for the care of a former HH member", which fails §21's same-principal-abode requirementDecision: ASEC, for both legs. The flag is directly measured. Because neither instrument measures in-household adult-care spending, the dollar leg is an explicitly documented same-instrument proxy: the measured ASEC work-related childcare expense distribution — the same §21 employment-related expense class, subject to the same §21(c) per-person cap — supplies (a) the paid-care usage rate (weighted share of positive-childcare SPM units among units with a child under the §21(d)(1)(A) age limit and positive earnings, measured ASEC channel) and (b) the positive level distribution (weighted quantiles). No dollar level or usage number is invented outside the measured donor distribution, and the proxy is declared in the stage manifest notes.
Statute-shaped support restriction
Expenses are assigned only where §21 can bind: units with a measured disabled qualifying individual (a dependent, or a married head/spouse — a taxpayer alone is never their own qualifying individual), passing the §21(d) earnings test computed exactly as the engine's
min_head_spouse_earnedbinds: both spouses earning, or a §21(d)(2) floor-eligible spouse (incapable of self-care, or the measured full-time college student) deemed while the other spouse actually earns — deeming never rescues a unit whose only earner is the floor-eligible spouse. Selection is a seeded, weight-targeted permutation prefix over sorted unit ids (invariant to person-row order) at the measured usage rate; levels are a distribution-preserving weighted-quantile draw (zero-weight donors excluded, grid from the selected units' own cumulative weights) placed on the qualifying person with the smallest id. Fully deterministic given the build seed and invariant to frame row order.Engine side-channels (enumerated, mechanism receipts read this session)
is_incapable_of_self_careis also read by SNAP/Medicaid work-requirement exemptions, TANF dependent-care deductions (MT/TX), CCAP (MN/LA), DC POWER, PR dependent test, and state CDCC analogs (MN/HI) — all move from all-False defaults toward the measured disability structure. Measured baseline deltas on the certified N frame are in the receipts below.Item 2 — self-employed premium attribution (SE health ALD)
self_employed_health_insurance_premiumsis formula-owned in the engine (anaddsaggregation gated bydefined_for = is_self_employed) and cannot ship as a column — the export adapter correctly refuses engine-computed names. The stage therefore ships the two pure inputs the engine intends, via a new deterministic final operationattribute_self_employed_health_premiumson the existingother_health_insurance_premiumsrelease stage (it must run after the PUF premium QRF, so the placement adds no new call intools/build_us_fiscal_refresh_release.py; that file carries exactly one minimal edit — see the register note below — and this branch will be rebased after PR #491 lands):health_insurance_premiums:= the finished reported non-Part-B premium, exactly where combined Schedule C income (self_employment_income_before_lsr+sstb_self_employment_income_before_lsr) is strictly positive, the person is outside the Medicare proxy (age 65+ or any Social Security disability income), and the person is outside measured employer-sponsored coverage (has_esi— the conservative, incomplete proxy for the §162(l)(2)(B) subsidized-employer-plan month exclusion; eligibility through a spouse's or dependent's employer is not measured and remains documented residual overbreadth); zero elsewhere. Attribution never invents premium mass.is_self_employed:= strictly-positive combined Schedule C income.The engine then computes the §162(l) ALD as
min(total_self_employment_income, premiums). The banked SOI Pub 1304 Table 1.4 TY2023 anchor (3,595,764 returns / $31.23B, ledger#105, in the v9.2 feed) binds through the existing measure maps once support exists — no calibration-loss machinery is touched (#492 doctrine: this is the support work).Why the Medicare proxy guard
medical_expense_health_insurance_premiumsuses the direct premium input when nonzero, elsenon_part_b + part_b·enrolled. Restricting attribution to people whose modeled Part B add-on is zero makes the direct input numerically equal to the decomposed value for every attributed person, so the statutory medical-expense concept (itemized medical, SNAP medical, SPM MOOP) is invariant — verified by an engine contract test. The excluded SE∩Medicare slice forgoes ALD mass conservatively; the calibration solve owns the level against the SOI fact.Bare-input side-channels (enumerated from the engine graph): MO qualified-premium subtraction, MI household resources, OH unreimbursed medical deduction, CA Orange County GA, MO CCS income test — all move from premiums-invisible toward the measured premium structure for the SE slice.
Probes (the keogh pattern) and coverage manifest
Two new
reform_coverage_probes(data, in the regeneratedrelease_input_coverage_manifest.json), each neutralizing the shipped dollar leaf at 2024 law withbudget_measure: income_tax,expected_sign: negative, floors set from the measured effects below. Four new required coverage leaves:pre_subsidy_care_expenses,is_incapable_of_self_care(red gate until the next base rebuild — the schedule_d precedent),health_insurance_premiums,is_self_employed(produced by any new release run).Measured receipts (certified N frame
c3e378a-20260722T010408Z, 166,321 persons / 57,240 households, release weights, build seed 0)All numbers are from the post-round-2 rerun (the mechanisms changed: §162(l)(2)(B) employer-coverage guard; order-invariant selection). Both stages run end-to-end on the certified frame; both signal gates pass with every round-2 certificate (flag identity, statute structure, plausibility ceiling, attribution identity) at zero violations; both probes execute through the real reform-coverage smoke machinery.
SE health attribution (with the §162(l)(2)(B)
has_esiguard):is_self_employed: 12,098 rows / 37.5M weighted (11.0% person share).self_employed_health_insurance_ald: $11.97B against the banked $31.23B SOI fact. Before the guard the raw ALD was $31.24B — a compositionally lucky match that included §162(l)(2)(B)-ineligible premium months (ESI-covered Schedule C people); the guarded surface is deliberately conservative, and the calibration solve owns closing the level against the banked fact over this support (no loss machinery touched, Loss shape: flat cap at 1.0 makes past-cap rows free dumping grounds (17 rows pushed out in Build N); bounded-tail experiment + past-cap census diagnostic #492).health_insurance_premiums, 2024 income_tax, baseline−reform): −$1.449B → floor set at $300M.CDCC adult care:
is_incapable_of_self_care: 2,067 measured PEDISDRS carriers / 5.998M weighted (1.76% person share — consistent with published self-care-difficulty prevalence).pre_subsidy_care_expenses: 137 carrier rows / 492k weighted, $3.41B donor-matched mass.Probe effect (neutralize
pre_subsidy_care_expenses, 2024 income_tax, baseline−reform): −$153.9M → floor set at $30M.Weighted ALD-carrier tax units: 3,539,030 vs SOI's 3,595,764 returns (−1.6%) — both the premium-carrier and ALD-carrier counts land within ~2% of the SOI return count.
Baseline drift vs certified N (both stages on, measured, not estimated):
The income-tax delta is dominated by the SE-ALD channel (−$1.449B); the CDCC lift combines the adult-care dollar leg with the §21(d)(2) deeming the measured flag enables on existing childcare expenses; the SNAP lift is the measured flag reaching the work-requirement exemptions the statute reads it in.
The income-tax drift is the SE-health ALD binding plus the CDCC growth; the SNAP/benefits drift is the measured disability flag reaching SNAP/Medicaid work-requirement exemptions (statute-correct on measured data; levels remain owned by the calibrated SNAP targets at the next solve).
Register consistency (the one edit to the #491-shared file)
The release builder's
US_DOCUMENTED_ABSENT_INPUTSregister carriedis_incapable_of_self_carewith the claim "No direct ASEC item" — refuted by the dictionary receipts (PEDISDRSis the direct item), and now contradictory with the required-coverage leaf (the register-consistency gate correctly refused the pair). The entry is removed and the register docstring records that theadult_care_inputsstage seeds the flag, mirroring theis_pregnantprecedent. This is the only change totools/build_us_fiscal_refresh_release.py; the branch will be rebased once PR #491 merges.Cross-family review
Two sol rounds (read-only, judgment tier), all findings fixed:
Round 1: plan/export/audit wiring completed (
US_DONORS/US_STAGE_NAMES, the L0/refit export contract, builder summary + stagedrequired_signals, runtime required-inputs mirror); SE gate hardened (null/non-boolean flags, nonfinite identity sources); SIPP receipt vintage-scoped (the 2018 panel's Child & Dependent Care module collectedECREPAYANYON/TDEPNDNTEXP; the 2023 PUF — the pinned donor vintage — does not release them); state consumers enumerated in the shipped notes.Round 2 (5 blocking, 7 should-fix, 1 nit — full report in the PR thread): the §21(d)(2) work test was directional-blind (a unit whose only earner is the incapacitated spouse wrongly passed — now computed exactly as the engine binds, with a regression test); student-spouse deeming added from the measured college indicator; seeded selection made invariant to person-row order (sorted unit ids, smallest-person-id placement, order-invariance test); the weighted-quantile pairing now excludes zero-weight donors and grids on the selected units' own cumulative weights; the donor channel column is required rather than defaulting to all-ASEC; the adult-care gate became a real heal certificate (strict flag validation, PEDISDRS identity when present, statute-structure checks — carrier must be a qualifying person, one carrier per unit — and a documented plausibility ceiling); the SE attribution gained the §162(l)(2)(B) employer-coverage guard (
has_esi); string-typed flags now fail both gates (pandas-3strdtype included); the builder failing-gate parametrization and invocation assertions now cover the adult-care stage; the §21(b)(1)(A) citation corrected. All measured receipts below are from a post-fix rerun.Tests
test_us_adult_care.py(new): manifest pins incl. the source-decision receipts, statute-structure binding, per-seed determinism, taxpayer-not-own-QI, fail-closed on missing sources and degenerate usage rate, gate rejections, heal path, live 1.764.6 CDCC chain (deeming, neutralization) contract.test_us_other_health_insurance.py(extended): deterministic attribution identity with both guards, Schedule-C-loss handling, fail-closed sources, gate identity/structural-zero rejections, legacy-surface rebuild-or-refuse, live 1.764.6 §162(l) chain incl. thedefined_forgate and the medical-expense invariance receipt, shipped-probe pins.adult_care_post_clone).Fixes nothing silently: a release whose export drops either channel now fails the coverage gate and the reform smoke.
Refs #451 (items 1–2).
🤖 Generated with Claude Code