Repository navigation
Fix Idaho health insurance premium subtraction - #10023
Merged
Merged
Conversation
MaxGhenis
marked this pull request as ready for review
October 10, 2026 09:35
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #10023 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 4 6 +2
Lines 76 111 +35
Branches 2 3 +1
=========================================
+ Hits 76 111 +35
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This was referenced Oct 10, 2026
MaxGhenis
added a commit
that referenced
this pull request
Oct 10, 2026
Contributor
Author
|
US + core hub merge audit, us#10023 at
|
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.
Before this PR, Idaho omitted the subtraction for health insurance premiums paid by the taxpayer. This PR adds it using existing payer-attributed person-level premium facts. Payments by the tax unit's head and spouse qualify, including their payments covering dependents; their pretax premiums and federal self-employed health deductions are excluded.
Round 5 removes the process-wide replacement of Core's
Holder.delete_arrays.policyengine_us/tools/period_branch.pyand its shared branch tests are restored exactly to currentmainate92f4c6b95458105134b4d88349f10a853dc8b50. No Core class or method is changed. The existing read-only, period/branch-awarehas_input_for_periodcheck now lives intools/general.pyand is called only by the two Idaho formulas. The supplied-medical-expense formula and both round-4 YAML regressions are unchanged.Round 6 applies the hub's settled disjoint premium-input contract: the premium inputs contain payments made outside pretax payroll deductions, and
pre_tax_health_insurance_premiumsis a separate input that never enters the Idaho subtraction or claimant medical worksheet. The formulas retain the self-employed above-the-line deduction and dependent-payment exclusions. Four existing YAML cases (five pretax input occurrences) and the property test now use that contract; a fifth, vectorized household regression verifies identical Idaho outputs with $0 or $2,000 of separately supplied pretax premiums. A strict xfail records the known federal-first deletion limitation without changing Core orperiod_branch.py. PolicyBench cells 007 and 053 remain unchanged.Round 7 verifies that Idaho Code 63-3022P and the 2025 Form 39R line 18 instructions and worksheet allow voluntarily enrolled Medicare Part B and Part D premiums paid by the taxpayer or spouse. Income-related adjustments are part of those premiums, so their eligibility follows the same rule; see 20 CFR 418.1125 and SSA Handbook 2505. The existing model derives out-of-pocket Part B premiums for enrolled people when no premium inputs are supplied, and main already includes those amounts in the federal Schedule A medical base. The senior-couple integration case now explicitly asserts the $4,440 subtraction: 2 × $185 × 12, below the $200,000 × 7.5% = $15,000 medical floor, leaving $200,000 − $60,000 − $6,000 − $4,440 = $129,560 taxable income. A subtraction-file regression covers the same enrolled couple without premium inputs. Round 7 also establishes by empirical bisection that Core 3.32.27 is the first fixed version for the deleted-input provenance limitation, matching the changelog and Core #561. The strict xfail now applies only below 3.32.27. Normal full-file validation gives 2 passed and 1 xfailed on Core 3.32.26, and 3 passed on Core 3.32.29. The dependency floor and lock remain unchanged. All 65 Idaho YAML files are being run individually in fresh foreground CLI processes, one at a time. The first three files have passed: integration (7 cases), premium subtraction (23 cases), and Idaho income tax before refundable credits (4 cases), for 34 passed, 0 failed. The PolicyBench file confirms unchanged cells 007 ($655.54) and 053 ($2,180.28). The local run of the other 62 Idaho files was cut off by the build job's time limit; CI's state shard at this head covers the whole folder and passes.
The retained supplied-expense regression has 2025 AGI of $30,000, $3,000 premiums, supplied
itemized_medical_expensesof $6,000 and supplied Idaho itemized deductions of $20,000. The $3,750 federal medical deduction exhausts premium overlap: subtraction $0, taxable income $10,000. The other retained regression verifies that an authoritative supplied Schedule A subtotal already excludes Schedule 1 premiums and can include bills absent from the person inputs. Under the disjoint contract, $6,000 of premium inputs less the $1,000 Schedule 1 deduction plus $500 of those bills gives a supplied subtotal of $5,500. The $2,250 medical floor leaves a $3,250 federal and claimant deduction; $5,000 qualified premiums less that overlap preserves the $1,750 subtraction. The separate $2,000 pretax input does not enter either calculation.Idaho Code 63-3022P limits the subtraction to premiums paid by the taxpayer that have not otherwise been deducted or accounted for. 2025 Form 39R instructions and worksheet, PDF pages 48–49 allocate itemized medical deductions to health premiums first and preserve the subtraction when Idaho's standard deduction is elected. The 2025 Schedule A instructions limit medical expenses to bills the claimant paid and exclude pretax premiums and premiums already deducted on Schedule 1.
The declared
id_health_insurance_premiums_medical_deductionderives the claimant's worksheet deduction from qualified filer premiums plus filer-paidother_medical_expenses, less the medical floor. It excludes dependent-paid expenses before applying the floor and caps derived results by the nonnegative federal medical deduction. Bothid_itemizesandid_health_insurance_premiums_subtractionconsume this value. A federalmedical_expense_deductionoritemized_medical_expensessubtotal explicitly supplied for the requested tax year represents the claimant's actual Schedule A amount and is honored even when underlying person inputs are omitted. A read-only input check distinguishes visible source inputs from calculated values using Core provenance. On policyengine-core < 3.32.27, deleted inputs recalculated before that check have the known limitation below. Inputs from another year or sibling branch cannot override the claimant calculation. An explicit Idaho medical-deduction override remains available for a different state-specific claim. Federal medical and itemized-deduction formulas are unchanged.When both the federal itemized subtotal and final total are derived,
id_itemized_deductionsalso replaces the shared federal medical component with this claimant deduction. Explicitly supplied federal itemized totals and subtotals remain authoritative. Supplied final totals receive the existing Idaho SALT adjustment; supplied subtotals first flow through the existing federal limitation and then the Idaho SALT adjustment. Neither is reconstructed medically from potentially incomplete component inputs. With the same 2025 payer facts and $20,000 of allowable interest deductions, the shared federal itemized total remains $21,250; Idaho's total is $20,750. The Idaho deduction plus premium subtraction is $23,000, leaving $7,000 taxable income. This prevents independently paid dependent costs from surviving in the state itemized total after premium overlap is corrected.For 2026, the replacement also adjusts the overall itemized reduction under P.L. 119-21 §70111 (IRC 68), using the existing federal limitation parameters and income calculation. Removing medical costs before applying the 2/37 reduction can change that reduction. The new high-income regression corrects a $70,500 federal subtotal to $70,000, yielding approximately $66,216.21622 of Idaho itemized deductions. The older Pease reduction is unaffected because medical deductions were excluded from its ceiling.
Choose the larger combined Idaho deduction plus premium subtraction, retaining the standard deduction on ties and requiring itemization for separate filers whose spouses itemize. Idaho Code 63-3022(j) and the Idaho Desk Audit Manual support this election. The provision predates 2021, so both existing subtraction-list periods include it.
PolicyBench cells
The regressions preserve every supplied household fact and assert these aggregate state tax totals, including the $10 permanent building fund tax. The Idaho income-tax components are $645.54 and $2,170.28. The audited independent verification gives the component deltas as $2,080 × 5.3% = $110.24 and $5,000 × 5.3% = $265.
Known limitation
This limitation affects policyengine-core versions below 3.32.27. Core 3.32.27 fixes input-record deletion and memory/disk provenance in Core #561, Keep the record of set_input values in step with storage. The PR continues to allow
policyengine-core>=3.32.8, withuv.lockpinned to 3.32.8; a separate floor bump to>=3.32.27would remove this limitation for all allowed installations.On older Core versions,
_user_input_keyscan remain after an input array is deleted. The exact regression has 2025 AGI $30,000, parent-paid premiums $3,000, dependent-paid premiums $500, standard deduction $15,750 and supplied Idaho itemized deductions $20,000: explicitly callset_inputand thendelete_arraysonmedical_expense_deduction. If the federal deduction is calculated before the Idaho helper, the recomputed $1,250 is misclassified as supplied. The subtraction is $1,750 instead of $2,250, and taxable income is $8,250 instead of $7,750. Calculating the Idaho helper first gives the correct result. The committed regression expects the correct $2,250 subtraction using only public simulation APIs. Itspytest.mark.xfail(condition=Version(version("policyengine-core")) < Version("3.32.27"), strict=True, reason=...)applies only on affected versions, usingimportlib.metadata.version("policyengine-core")andpackaging.version.Version; on fixed versions the test runs as an ordinary passing regression.The trigger remains explicit
set_inputfollowed bydelete_arrayson a suppliedmedical_expense_deduction,itemized_medical_expenses, or itemized input used by Idaho (itemized_taxable_income_deductionsortotal_itemized_taxable_income_deductions). Review r5's caller survey found no PolicyEngine-US path that performs that sequence: API household inputs are set once;Simulation.__init__deletes unrelated inputs; bulk branch loops skipinput_variables; New York branches delete only EITC or CTC variables; branch exit deletes calculated variables; anddrop_inherited_valueskeeps inputs. The PR adds no deletion callers.For affected older versions, deletion and recalculation can finish before the first input-helper call, leaving indistinguishable supplied and recomputed values. The helper remains read-only; this PR changes no Core or
period_branchbehavior. The Core release fix now supplies the missing provenance cleanup. Historical round-4/6 failure logs remain untracked evidence, including the $1,750 result on Core 3.32.15. No public issue was opened.Validation
Round 7, at
d3f56815167726b809be586b9510882852751565. Both changes are committed and pushed.make format(7,068 files unchanged), Ruff lint, source review, andgit diff --checkpassed. Core validation is complete. CI at this head passes all 28 checks, includingFull Suite - Baseline (states-shard-3), the job that runs the Idaho folder and that failed on its integration file at the previous head.The empirical Core version bisect ran only
test_deleted_medical_input_recalculated_federal_firstwithpytest --runxfail, using the PR worktree and specifically pinned Core versions in a scratch venv. Each invocation was a fresh foreground process, one at a time. The raw completed version matrix is:--runxfailThe four diagnostic failures reproduce
[1750.0]versus the expected[2250]; they demonstrate the older-Core limitation and are not ordinary regression-suite failures. The adjacent 3.32.26 failure and 3.32.27 pass establish 3.32.27 as the first fixed version, matching Core #561 and the 3.32.27 changelog. Read-only inspection of the published 3.32.8 wheel confirms the same stale registry behavior at the allowed floor. The dependency floor anduv.lockremain unchanged.The full
policyengine_us/tests/core/test_id_health_insurance_premiums.pyfile then ran normally, without--runxfail, on the last affected release and the CI release. Both processes exited 0, verifying a strict xfail on 3.32.26 and an ordinary passing regression on 3.32.29:Long startup and collection delays coincided with high local macOS/Python 3.13.9 host load. The full-file commands used approximately 44.35 s and 38.03 s of combined child user/system CPU time respectively; these wall-time measurements do not establish Linux CI resource impact. An earlier 3.32.25 diagnostic attempt exited with signal 11 before collection; its log is retained, and a fresh retry without the optional traceback timer produced the normal older-Core assertion failure shown above. That attempt and the earlier interrupted startup diagnostic are excluded from the completed version matrix.
Idaho YAML files run locally: the three files below, individually, in fresh foreground CLI processes, one at a time: 34 passed, 0 failed, 0 xfailed, 0 skipped, 0 errors, with exit code 0 for every command. The local run of the other 62 Idaho files was cut off by the build job's six-hour limit under high host load. CI's state shard at this head covers the whole folder and passes.
policyengine_us/tests/policy/baseline/gov/states/id/tax/income/integration.yamlhub-evidence/idaho-yaml/01-integration.logpolicyengine_us/tests/policy/baseline/gov/states/id/tax/income/subtractions/id_health_insurance_premiums_subtraction.yamlhub-evidence/idaho-yaml/02-id_health_insurance_premiums_subtraction.logpolicyengine_us/tests/policy/baseline/gov/states/id/tax/income/id_income_tax_before_refundable_credits.yamlhub-evidence/idaho-yaml/03-id_income_tax_before_refundable_credits.logThe four passing
id_income_tax_before_refundable_credits.yamlcases include the unchanged PolicyBench aggregate state-tax assertions: cell 007 $655.54 and cell 053 $2,180.28, including the $10 permanent building fund tax. The corresponding Idaho income-tax components remain $645.54 and $2,170.28. Each file reports onePytestAssertRewriteWarningfor the already importedanyiomodule; no test failed. The historical round-6 counts below remain historical. No microsimulation, folder invocation, full suite, or partner test is included in this round.Historical round-6 validation
Final-source round-6 validation at
6657e9331136cc7602684f02ff2f43547270f577: 42 passed, 1 strict xfailed, 0 skipped. Every PR-changed test file ran individually, one at a time in the foreground, with Python 3.13.9 and policyengine-core 3.32.15. No folder run, full suite or microsimulation was run.policyengine_us/tests/core/test_id_health_insurance_premiums.pypolicyengine_us/tests/policy/baseline/gov/states/id/tax/income/subtractions/id_health_insurance_premiums_subtraction.yamlpolicyengine_us/tests/policy/baseline/gov/states/id/tax/income/id_deductions.yamlpolicyengine_us/tests/policy/baseline/gov/states/id/tax/income/id_itemized_deductions.yamlpolicyengine_us/tests/policy/baseline/gov/states/id/tax/income/id_income_tax_before_refundable_credits.yamlThese pytest times exclude interpreter startup before pytest begins and are not full command wall times or Linux CI group measurements.
The earlier untracked round-4 deletion regression reproduced the known limitation: 4 failed, 4 passed, 2 deselected. All four federal-first cases failed with a recomputed $1,250 claimant deduction instead of $750; all four helper-first cases passed. This covers US and Core simulations, and simulation and holder deletion. Round 6 tracks the deterministic federal-first sequence with the committed strict xfail. An isolated diagnostic run with
--runxfailintentionally failed at[1750.0] != [2250], confirming the exact defect independently of test order; its log remains untracked evidence and is excluded from the 42 passing cases. The earlier reproduction is also excluded from the current validation counts.Round-6 Ruff formatting and lint on the changed files and
git diff --checkpassed. The main restoration from round 5 remains untouched, and no Core orperiod_branchmethod is changed. No partner tests were edited or run.The property test independently enumerates the standard and itemized routes across 20 generated vector batches plus two explicit batches. It checks head/spouse/dependent payment scope, invariance to separately supplied pretax premiums, ALD exclusions, nonnegative and bounded subtraction, the largest combined deduction and subtraction, mandatory itemization, standard on ties, and independent tax units. The year/branch regression checks supplied claims for the requested year, sibling isolation, inherited branch inputs and deletion before federal recalculation. YAML covers the derived claimant medical floor, supplied aggregates, state deduction election and the 2026 limitation.
The Python addition tracks Core deletion provenance and calculation order, which YAML cannot exercise. The property file remains in the existing Rest/core CI group and the YAML files remain in the baseline states shards.
Local macOS/Python 3.13.9 full-command wall time, including model setup, was 32.90 s for the original two-test file and 36.51 s for the three-test round-6 file (including the strict xfail), a 3.61 s increase in these runs. Pytest reported 28.27 s and 7.71 s respectively. These single local runs do not establish a reduction in resource cost. Peak local RSS is unavailable because the sandbox rejected
/usr/bin/time -l'ssysctl kern.clockratecall after the baseline tests passed;/usr/bin/time -pcompleted for round 6.The existing successful main CI run 37931391733, Rest job, head
0d934958068c7036074007a3684add97723be245on Linux/Python 3.14.8, records the Rest/core subgroup at 11:16.36 and peak RSS 6,757,164 KiB in artifact11620880923,rest-python-core-resources.txt. Those are baseline group measurements; updated Linux CI impact remains pending.Dependencies, CI configuration, federal formulas and partner contract files are unchanged. Refreshed Linux CI group measurements and microsimulation impact remain pending with the hub. Changelog:
changelog.d/hub-pb-id-premiums-1009.fixed.md.Methodology
The hub applies Max's 2026-10-07 rule, "in general we should make inputs as leaf-nodey as possible." This settles the contract for this PR:
pre_tax_health_insurance_premiumsand the premium inputs (health_insurance_premiumsor the applicable decomposed premium inputs) are disjoint leaves. The premium inputs contain payments made outside pretax payroll deductions. Total premiums paid is the sum of those non-pretax payments and the separate pretax input; no pretax component is carved out of the premium inputs. Max may overrule the hub's application of his input rule.Federal and Idaho now read the premium inputs the same way. The existing federal medical deduction counts the premium inputs without subtracting the separate pretax input, and Idaho likewise starts its qualified-premium and claimant-medical calculations from those inputs as supplied. Pretax payroll premiums are excluded because they never enter those inputs. Idaho still removes premiums already deducted through the self-employed above-the-line deduction where required and excludes independent dependent payments from the claimant calculation.
The contract change has no microsimulation effect: the pinned default dataset,
populace-us-2024-spm-20260909at Hugging Face revision9a814a3b, has nopre_tax_health_insurance_premiumscolumn, and that variable has no formula. It is therefore zero for every record in those runs. The change affects callers who explicitly supply pretax premiums; shared variable documentation, federal formulas and SPM MOOP are outside this round's scope.The existing joint standard-versus-itemized optimization also remains: choose the larger combined deduction and premium subtraction, use standard on ties, and honor mandatory itemization. The statutory election, Form 39R standard-deduction exception, and Desk Audit Manual support that choice.
Limitations
The state correction assumes person-level medical amounts identify the payer. Payments by the head or spouse for a dependent belong with the payer; a dependent's independent payments do not enter the claimant's worksheet. When neither the medical deduction nor the expense subtotal is supplied, the claimant's underlying person-level medical costs must be complete. A supplied federal medical deduction or expense subtotal is authoritative and must represent the claimant's actual Schedule A amount for the requested tax year.
The shared federal medical and itemized aggregates retain their existing payer and exclusion limitations. The Idaho medical replacement corrects their effect on the derived state itemized total without changing federal calculations. Supplied federal itemized aggregates must represent the actual claimant return and the requested tax year. Those authoritative aggregate totals are preserved rather than reconstructed from potentially incomplete person-level inputs; the existing Idaho SALT adjustment still applies. The 2026 adjustment preserves the existing federal limitation's income calculation and parameters.
The inputs do not identify premiums paid from an already-deducted Idaho medical savings account. That remains a separate limitation. No partner contract files were edited or run locally. The prior read-only inventory of 144 partner YAML files found no Idaho scenarios or Idaho tax assertions.
axiom: Idaho Code 63-3022P TheAxiomFoundation/rulespec-us#1625 queued
The previously filed
pe-parityissue supplies corpus and module citations, verbatim law, required outputs, and companion tests independently calculated from the 2025 Form 39R instructions and worksheet. Encoding remains blocked until the Axiom hub pins a corpus release containing §63-3022P, which exists in the newer corpus but is absent from rulespec-us's current pin. Under Max's d1142 ruling, the Axiom engineering hub runs the signed encoder. The queue entry remains pending.Hub microsimulation impact (current head)
A real microsimulation on the default dataset, main at the merge base
c05b85ec1cagainst this PR's headd3f5681516, for 2025 and 2026. The runs went one at a time under the shared heavy-job lock. Sums are weighted.id_income_taxid_taxable_incomeid_deductionsstate_income_taxincome_taxhousehold_net_incomehousehold_benefitsComparison files are in
fixes/10023-impact/on the hub host.Hub microsimulation impact
Prior round, head
f44901ee32; the hub will refresh impact after this round.A real microsimulation on the default dataset, main at the merge base
c05b85ec1cagainst this PR's headf44901ee32, for 2025 and 2026. The runs went one at a time under the shared heavy-job lock. Sums are weighted.id_income_taxid_taxable_incomeid_deductionsstate_income_taxincome_taxhousehold_net_incomehousehold_benefitsComparison files are in
fixes/10023-impact/on the hub host.No microsimulation was run in this round; refreshed impact is pending with the hub.