Repository navigation
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…gets Net excess losses between co-resident spouses before SSI, MSP and Medicaid exclusions. Keep Connecticut and Minnesota own/deemed budgets consistent, prevent negative child/student exclusions, and isolate New Hampshire self-employment losses from wages. Add vectorized property and differential coverage. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Use Kentucky's own business-source floors and preserve Minnesota gross-income premium restoration without resurrecting losses. Add SD and WY source-presence regressions and complete direct reader coverage across 23 states, including loss-to-profit monotonicity. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
marked this pull request as ready for review
October 29, 2026 14:42
This branch has not been deployed
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.
Fixes #10531
What and why
A Texas senior aged 67 with $60,000 of Schedule C profit receives no SSI or MSP Part B coverage. On base
8b17892d2cba99a82961ea32fbaf9d69c6ba73d6, putting that profit in farm operations or partnership SECA earnings instead produces $11,928 SSI and $2,434.80 MSP Part B coverage. Both cases are now treated like Schedule C: SSI $0, MSP Part B coverage $0, and personal Part B premium $2,434.80.Add the disjoint
farm_operations_income(active Schedule F) andpartnership_self_employment_net_earnings(the K-1 Box 14 SECA component) once to SSI earned sources, and correct “unearned” to “earned” in the description. Do not add passive farm rent, allpartnership_income, ortotal_self_employment_income, which would duplicate or misclassify income. The tax-base formula applies its NESE adjustment to the partnership input, confirming that the input is pre-adjustment despite its name.The required loss-rule review also exposed existing errors. Keep signed individual earnings for own-income readers, but apply a spouse's excess business loss to the other spouse's earned SSI/MSP/optional-Medicaid budget, using the existing co-resident spouse identification. Prevent negative earned balances from increasing child allocations or creating negative student exclusions. CT and MN readers combine the same loss-adjusted own earnings with deemed earnings so the loss is deducted once. MN restores pretax premiums only after covering any otherwise unabsorbed business loss, preventing false positive gross income. NH uses its own raw self-employment list because its law forbids business losses offsetting wages. KY uses its own list and floors each modeled business source separately; its full spouse/parent methodology remains an existing limitation.
Governing text and the four questions
Invariants and intentional exceptions
ssi_earned_incomeunchanged; no added source is counted twice.Reader audit
Each row checks that program's own law; qualifying active farm/partnership earnings count as earned in all audited readers. Classification sharing does not assert that tax net profit captures every program-specific expense or averaging adjustment.
ssi_earned_income;ssi_earned_income_after_spousal_loss;ssi_marital_earned_incomessi_earned_income_deemed_from_ineligible_spouse,ssi_income_deemed_from_ineligible_spouse,is_ssi_spousal_deeming_appliesssi_earned_income.ssi_unearned_income_deemed_from_ineligible_parent,ssi_ineligible_child_allocationssi_earned_income.ssi_blind_or_disabled_working_student_exclusionssi_earned_income.ssi_engaged_in_sgamsp_countable_income(own earnings and spouse-deemed earnings)medicaid_optional_senior_or_disabled_income_deemed_from_ineligible_spouse,medicaid_optional_senior_or_disabled_unearned_income_deemed_from_ineligible_parentca_wdp_gross_earned_incomemn_msa_gross_income,mn_msa_net_income_eligible,mn_msa_personnh_ssp_countable_incomewi_cts_gross_earned_incomect_ssp_countable_income,ct_ssp_earned_income_disregard,ct_ssp_gross_incomessi_earned_income_after_spousal_loss; CT UPM 5025.15 has partial-year averaging exceptions, a preexisting annual-input limitation.co_state_supplement_countable_income,co_oap_own_countable_income,co_oap_deemed_incomeva_ag_countable_incomevt_aabd_ep_countable_income_ok_ssp_incomehelper:ok_ssp_countable_income,ok_ssp_own_countable_income;ok_ssp_spouse_child_allocationor_ssp_countable_incomenc_sa_countable_incomeoh_rss_countable_incomesd_ssp_caresd_ssp_independentwy_ssp_eligiblemd_paa_countable_incomeky_ssp_earned_income,ky_ssp_countable_incometx_ssi_state_supplement_eligiblemt_ssp,nv_oss,nj_ssp,vt_aabd_federalpa_sspny_sspri_sspNH's individual-level text clearly bars excess business costs from other income. This change retains the model's existing aggregation of business inputs and moves the self-employment floor ahead of wages; business-by-business versus aggregate-business treatment remains a hub statute-reading question. CT/MN own-and-deemed budgets now use the loss-adjusted helper consistently. Other state expense/partial-year conventions are existing input limitations, as the table states.
The static audit covers direct earned-source and earned-income readers, all direct consumers of the changed marital/deeming budgets, and their state function wrappers: 34 state outputs across 23 sampled states (including the new KY own-income helper). It excludes unbounded propagation through SSI as transfer income. The table distinguishes classification from program-specific expense/deeming rules.
Remaining hub readings/input questions: (1) conditional 92.35% tax-paid/filing evidence; (2) NH aggregate-business versus business-by-business losses; (3) KY section 8(3) spouse conservation versus section 8(6) combined-earnings ordering, plus its distinct parental methodology. KY own-source floors are corrected here, but retained SSI student/unearned/deemed inputs are an explicit approximation, not a claim of full state-methodology compliance. Raw business inputs also do not expose each business or state-disallowed depreciation.
Proposed separate follow-up (no issue created): Missouri SAB omits active partnership self-employment earnings from its earned source list.
Its own source list already contains farm income and is unaffected by the SSI-list change; the omission is independent. Review active partnership NESE against MO SAB Manual 0410.015.05, preserving passive investment treatment.
Open-PR overlap
Checked
git merge-tree --write-treeat branch HEAD6cb74d7c4ee2a566a30712673200a6aa371d3f69against the current GitHub heads below, refreshed 2026-10-29 13:19:24 UTC. Current main is1b52a6d7c08574c47aa87d762efc996f55a0ff58; this branch merges cleanly with it.Exit 1 below denotes a hypothetical merge conflict. Exact common/conflict files and semantic integration requirements follow; raw command logs remain untracked locally for the hub.
1b52a6d7c08574c47aa87d762efc996f55a0ff588b17892d2c6559b7c3358e935951799543890a6bbbef30d8f4ssi_earned_income_after_spousal_lossrouting and nonnegative child-earned contribution in the new monthly formulas. Keep CT/MN own/deemed earnings consistent, including MN gross-premium restoration. Preserve KY's separate positive-business source computation when adapting its monthly budget. Combine NH's add/add test cases and preserve its separate self-employment loss rule.a53311ad7b201b8f9aa7b37185fbde55b34b4382_ssi_spouses.pyalso affect both this PR's new SSI loss helper and MN gross-premium restoration, which import that shared spouse-index function, although there is no common spouse-helper-file edit.7291aa771386606c03e87ce736fd07007da6350amsp_countable_income.pyandmsp_countable_income.yaml; formula auto-mergesb5fb5cabb2227fab8e00d40a9fc3bb964768f0cd(merged)#10146 exact conflict files
policyengine_us/tests/policy/baseline/gov/hhs/medicare/savings_programs/income/msp_countable_income.yamlpolicyengine_us/tests/policy/baseline/gov/states/nh/dhhs/ssp/nh_ssp_countable_income.yaml(add/add)policyengine_us/variables/gov/hhs/medicaid/income/deemed/from_ineligible_spouse/medicaid_optional_senior_or_disabled_income_deemed_from_ineligible_spouse.pypolicyengine_us/variables/gov/hhs/medicare/savings_programs/income/msp_countable_income.pypolicyengine_us/variables/gov/ssa/ssi/eligibility/income/deemed/from_ineligible_spouse/ssi_earned_income_deemed_from_ineligible_spouse.pypolicyengine_us/variables/gov/ssa/ssi/eligibility/income/deemed/from_ineligible_spouse/ssi_income_deemed_from_ineligible_spouse.pypolicyengine_us/variables/gov/ssa/ssi/eligibility/income/deemed/ssi_ineligible_child_allocation.pypolicyengine_us/variables/gov/states/ct/dss/ssp/income/ct_ssp_countable_income.pypolicyengine_us/variables/gov/states/ct/dss/ssp/income/ct_ssp_earned_income_disregard.pypolicyengine_us/variables/gov/states/ky/dcbs/ssp/ky_ssp_countable_income.pypolicyengine_us/variables/gov/states/mn/dhs/msa/eligibility/mn_msa_net_income_eligible.pypolicyengine_us/variables/gov/states/mn/dhs/msa/mn_msa_person.py#10146 other common files, merging automatically
policyengine_us/tests/policy/baseline/gov/ssa/ssi/eligibility/income/deemed/ssi_ineligible_child_allocation.yamlpolicyengine_us/variables/gov/states/ct/dss/ssp/income/ct_ssp_gross_income.pypolicyengine_us/variables/gov/states/mn/dhs/msa/income/mn_msa_gross_income.pypolicyengine_us/variables/gov/states/nh/dhhs/ssp/nh_ssp_countable_income.pyOther exact conflict files
#10141:
policyengine_us/variables/gov/ssa/ssi/eligibility/income/deemed/from_ineligible_spouse/ssi_earned_income_deemed_from_ineligible_spouse.pypolicyengine_us/variables/gov/ssa/ssi/eligibility/income/marital/ssi_marital_earned_income.pyAutomatically merged common files for #10141:
policyengine_us/variables/gov/states/mn/dhs/msa/eligibility/mn_msa_net_income_eligible.pypolicyengine_us/variables/gov/states/mn/dhs/msa/mn_msa_person.py#10360:
policyengine_us/tests/policy/baseline/gov/hhs/medicare/savings_programs/income/msp_countable_income.yamlAutomatically merged common file for #10360:
policyengine_us/variables/gov/hhs/medicare/savings_programs/income/msp_countable_income.py#10483: none.
Validation
8b17892d2cba99a82961ea32fbaf9d69c6ba73d6with farm/partnership zero and nonnegative Schedule C/SSTB. Restored 15 exact base variable classes, rather than only reverting the source list.gov/ssa/ssi/income/ssi_earned_income.yamlgov/ssa/ssi/ssi.yamlgov/ssa/ssi/income/ssi_earned_income_after_spousal_loss.yamlgov/ssa/ssi/income/ssi_marital_earned_income.yamlgov/ssa/ssi/eligibility/income/deemed/ssi_ineligible_child_allocation.yamlgov/ssa/ssi/eligibility/income/ssi_blind_or_disabled_working_student_exclusion.yamlgov/hhs/medicare/savings_programs/income/msp_countable_income.yamlgov/states/nh/dhhs/ssp/nh_ssp_countable_income.yamlgov/states/ct/dss/ssp/income/ct_ssp_countable_income.yamlgov/states/mn/dhs/msa/mn_msa_person.yamlpartners/analytics_coverage/edge_cases/state/ks/tanf.yamlgov/states/sd/dss/ssp/sd_ssp_independent.yamlgov/states/wy/health/ssp/wy_ssp_eligible.yamlgov/states/ky/dcbs/ssp/ky_ssp_countable_income.yamlgov/states/mn/dhs/msa/income/mn_msa_gross_income.yaml[60000.0, 0.0, 60000.0]versus[60000, 60000, 60000][60000.0, 60000.0, 0.0]versus[60000, 60000, 60000][60000.0, 120000.0, 60000.0]versus[60000, 60000, 60000]The following signed-loss cases intentionally change even with farm/partnership zero. Each was run against the actual recorded base and the fixed policy; amounts are annual except MSP/NH/KY/MN monthly values.
spouse_business_loss_offsets_applicant_wagesmsp_countable_income@2026-01[457.5, 0.0][249.1666717529297, 0.0]spouse_business_loss_offsets_applicant_wagesssi@2026[6438.0, 0.0][8938.0, 0.0]spouse_business_loss_offsets_applicant_wagesssi_countable_income@2026[5490.0, 0.0][2990.0, 0.0]child_business_loss_cannot_reduce_unearned_incomessi_ineligible_child_allocation@2026[0.0, 8364.0][0.0, 5364.0]student_exclusion_cannot_be_negativessi_blind_or_disabled_working_student_exclusion@2026[-3000.0][0.0]new_hampshire_business_loss_cannot_offset_wagesnh_ssp_countable_income@2026-01[360.5][860.5]kentucky_business_loss_cannot_offset_wagesky_ssp_countable_income@2026-01[217.5][467.5]minnesota_gross_earnings_cannot_be_negativemn_msa_gross_income@2026-01[-66.66667175292969][0.0]New Python-file measurement: 153 seconds including startup; pytest reported 45.25s; process peak 2.404 GiB. These are local macOS measurements, not whole-group or Linux CI benchmarks. The base has no corresponding property file.
All tests ran as single-file foreground processes with the numeric thread caps, load gate <=100, and 4 GB/1800s process-group cap; each mutant used 2 GB/900s. No suites, folder runs, microsimulations, or partner-file edits.
make formatandgit diff --checkpassed. Evidence remains untracked.The new Python file uses vectorized cases and a shared read-only country model for source repartition, monotonicity, and exact cross-output comparisons that YAML cannot enumerate. It follows the existing core test selection; no runner changes. Whole-group before/after and Linux CI benchmarks are unavailable within this single-file validation scope; local measurements are reported above.
make format(ruff formatting and lint).impact: pending (hub)
axiom: n/a
The complete rulespec-us main tree has no 20 CFR 416.1110 encoding; no RuleSpec authored or encoder run.
🤖 Generated with Claude Code