Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/vt-premium-assistance-exact-fpl-ratio.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Decide Vermont Premium Assistance eligibility on the exact ratio of ACA MAGI to the prior-year poverty guideline instead of the truncated `aca_magi_fraction`, so incomes from 300.003% to 300.994% of the poverty line are no longer eligible (33 V.S.A. § 1812(a)(1): "less than or equal to 300 percent of federal poverty level").
Original file line number Diff line number Diff line change
Expand Up @@ -56,23 +56,21 @@
vt_premium_assistance: 585.00

# ---- Scenario 2: full federal derivation, exactly 300% FPL boundary ----
- name: Scenario 2, single Vermont enrollee at 47k derives exactly 300% FPL and stays eligible.
# Raw input: employment_income 47_000. Note the exact 300%/size-1 MAGI is 46_950
# (see vt_premium_assistance.yaml Case 4); 47_000 sits just above it but the
# model still rounds aca_magi_fraction to 3.00, so the inclusive ceiling holds.
# Derived: aca_magi = 47_000;
# aca_magi_fraction = 3.00 exactly (the 300% ceiling is inclusive -> eligible);
# fed_pct = 9.96% (start of the 300-400% flat bracket); slcsp = 15_588.
# Federal APTC = 15_588 - 47_000*0.0996 = 15_588 - 4_681.20 = 10_906.80.
# VPA: fed_pct 9.96% > 1.5% -> gap = 47_000*0.015 = 705.00.
# residual = 15_588 - 10_906.80 = 4_681.20 > gap -> VPA = 705.00.
- name: Scenario 2, single Vermont enrollee at exactly 300% FPL stays eligible.
# Raw input: employment_income 46_950 = 3 x $15,650 (2025 one-person FPG).
# Derived: aca_magi = 46_950; aca_magi_fraction = 3.00 exactly (the 300%
# ceiling is inclusive -> eligible); fed_pct = 9.96% (start of the 300-400%
# flat bracket); slcsp = 15_588.
# Federal APTC = 15_588 - 46_950*0.0996 = 15_588 - 4_676.22 = 10_911.78.
# VPA: fed_pct 9.96% > 1.5% -> gap = 46_950*0.015 = 704.25.
# residual = 15_588 - 10_911.78 = 4_676.22 > gap -> VPA = 704.25.
period: 2026
absolute_error_margin: 0.01
input:
people:
person1:
age: 40
employment_income: 47_000
employment_income: 46_950
tax_units:
tax_unit:
members: [person1]
Expand All @@ -81,14 +79,41 @@
members: [person1]
state_code: VT
output:
aca_magi: 47_000
aca_magi: 46_950
aca_magi_fraction: 3.00
is_aca_ptc_eligible: true
aca_required_contribution_percentage: 0.0996
slcsp: 15_588
aca_ptc: 10_906.80
aca_ptc: 10_911.78
vt_premium_assistance_eligible: true
vt_premium_assistance: 705.00
vt_premium_assistance: 704.25

- name: Scenario 2b, single Vermont enrollee at 47k (300.32% FPL) is above the ceiling.
# Raw input: employment_income 47_000, which is 300.32% of $15,650. Truncation
# makes aca_magi_fraction 3.00, but 33 V.S.A. 1812(a)(1) covers only income
# "less than or equal to 300 percent", so Vermont Premium Assistance is $0.
# The federal APTC is unaffected: 15_588 - 47_000*0.0996 = 10_906.80.
period: 2026
absolute_error_margin: 0.01
input:
people:
person1:
age: 40
employment_income: 47_000
tax_units:
tax_unit:
members: [person1]
households:
household:
members: [person1]
state_code: VT
output:
aca_magi: 47_000
aca_magi_fraction: 3.00
is_aca_ptc_eligible: true
aca_ptc: 10_906.80
vt_premium_assistance_eligible: false
vt_premium_assistance: 0

# ---- Scenario 3: injected, 250% FPL, gap-binding ----
- name: Scenario 3, 250% FPL injected inputs give a gap-binding VPA of income times 1.5%.
Expand Down Expand Up @@ -251,11 +276,11 @@
# ---- Scenario 8: multi-member household at 300% FPL, gap-binding ----
- name: Scenario 8, three-person Vermont household at 300% FPL gets a gap-binding VPA scaling with MAGI.
# A larger family reaches the 300% ceiling at a higher aca_magi, so the gap
# (income * 0.015) scales up. fed_pct at 300% FPL = 9.96% (start of the
# 300-400% flat bracket, derived from the injected aca_magi_fraction 3.00).
# income = 100_000 -> gap = 100_000 * 0.015 = 1_500.
# (income * 0.015) scales up. 300% of the 2025 three-person FPG ($26,650) is
# 79_950, so aca_magi_fraction = 3.00 and fed_pct = 9.96% (start of the
# 300-400% flat bracket). gap = 79_950 * 0.015 = 1_199.25.
# residual = slcsp - aca_ptc = 20_000 - 8_000 = 12_000 > gap ->
# VPA = min(1_500, 12_000) = 1_500 (gap binds). Only one member need be
# VPA = min(1_199.25, 12_000) = 1_199.25 (gap binds). Only one member need be
# APTC-eligible for the tax unit to qualify at the inclusive 300% ceiling.
period: 2026
absolute_error_margin: 0.01
Expand All @@ -273,22 +298,21 @@
tax_units:
tax_unit:
members: [person1, person2, person3]
aca_magi: 100_000
aca_magi_fraction: 3.00
aca_magi: 79_950
slcsp: 20_000
aca_ptc: 8_000
households:
household:
members: [person1, person2, person3]
state_code: VT
output:
aca_magi: 100_000
aca_magi: 79_950
aca_magi_fraction: 3.00
aca_required_contribution_percentage: 0.0996
slcsp: 20_000
aca_ptc: 8_000
vt_premium_assistance_eligible: true
vt_premium_assistance: 1_500
vt_premium_assistance: 1_199.25

# ---- Scenario 9: full federal derivation, exactly 180% FPL, gap-binding ----
- name: Scenario 9, single Vermont enrollee at 28.2k derives 180% FPL and gets a gap-binding VPA.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,9 +319,10 @@

- name: Case 13, three-person Vermont household at 300% FPL gets a gap scaling with the larger MAGI.
# A larger family reaches 300% FPL at a higher aca_magi, so the gap
# (income * 0.015) scales up accordingly. fed_pct at 300% FPL = 9.96% > 1.5%,
# income = 100_000 -> gap = 100_000 * 0.015 = 1_500. residual =
# 20_000 - 8_000 = 12_000 > gap, so VPA = 1_500 (gap binds). Eligibility holds
# (income * 0.015) scales up accordingly. 300% of the 2025 three-person FPG
# ($26,650) is 79_950; fed_pct at 300% FPL = 9.96% > 1.5%, so
# gap = 79_950 * 0.015 = 1_199.25. residual = 20_000 - 8_000 = 12_000 > gap,
# so VPA = 1_199.25 (gap binds). Eligibility holds
# at the inclusive 300% ceiling for a multi-member unit, and only one member
# need be APTC-eligible.
period: 2026
Expand All @@ -340,7 +341,7 @@
tax_units:
tax_unit:
members: [person1, person2, person3]
aca_magi: 100_000
aca_magi: 79_950
aca_magi_fraction: 3.00
slcsp: 20_000
aca_ptc: 8_000
Expand All @@ -349,7 +350,7 @@
members: [person1, person2, person3]
state_code: VT
output:
vt_premium_assistance: 1_500
vt_premium_assistance: 1_199.25

# ---- Negative MAGI clamp (REQ-12) ----

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# Unit tests for Vermont Premium Assistance eligibility (REQ-1, REQ-2, REQ-3,
# REQ-8). A tax unit is eligible when the program is in effect (2026+), at least
# one member is federal-ACA-PTC-eligible (is_aca_ptc_eligible), and ACA MAGI is
# at or below 300% of the federal poverty line (aca_magi_fraction <= 3.0).
# eligible = in_effect & any(is_aca_ptc_eligible) & (aca_magi_fraction <= 3.0)
# aca_magi_fraction is injected directly so the 300% boundary is exact and each
# expectation is hand-verifiable. There is no minimum-income floor.
# at or below 300% of the federal poverty line (33 V.S.A. 1812(a)(1): "less
# than or equal to 300 percent"), on the exact ratio of ACA MAGI to the
# prior-year guideline, not the truncated aca_magi_fraction:
# eligible = in_effect & any(is_aca_ptc_eligible) & (aca_magi / FPG <= 3.0)
# Supplied-income cases pin the prior-year guideline to $10,000 and set
# aca_magi to the target ratio, so each expectation is hand-verifiable.
# Income-derived cases use the actual 2025 one-person guideline, $15,650.
# There is no minimum-income floor.

- name: Case 1, 250% FPL APTC-eligible Vermont tax unit is eligible.
# in_effect (2026) true; member APTC-eligible; 2.50 <= 3.0 -> eligible.
Expand All @@ -17,7 +21,9 @@
tax_units:
tax_unit:
members: [person1]
aca_magi_fraction: 2.50
aca_magi: 25_000
tax_unit_fpg:
2025: 10_000
households:
household:
members: [person1]
Expand All @@ -36,7 +42,9 @@
tax_units:
tax_unit:
members: [person1]
aca_magi_fraction: 2.99
aca_magi: 29_900
tax_unit_fpg:
2025: 10_000
households:
household:
members: [person1]
Expand All @@ -55,7 +63,9 @@
tax_units:
tax_unit:
members: [person1]
aca_magi_fraction: 3.00
aca_magi: 30_000
tax_unit_fpg:
2025: 10_000
households:
household:
members: [person1]
Expand All @@ -74,7 +84,9 @@
tax_units:
tax_unit:
members: [person1]
aca_magi_fraction: 3.01
aca_magi: 30_100
tax_unit_fpg:
2025: 10_000
households:
household:
members: [person1]
Expand All @@ -93,7 +105,9 @@
tax_units:
tax_unit:
members: [person1]
aca_magi_fraction: 2.50
aca_magi: 25_000
tax_unit_fpg:
2025: 10_000
households:
household:
members: [person1]
Expand All @@ -115,7 +129,9 @@
tax_units:
tax_unit:
members: [person1, person2]
aca_magi_fraction: 2.50
aca_magi: 25_000
tax_unit_fpg:
2025: 10_000
households:
household:
members: [person1, person2]
Expand All @@ -134,7 +150,9 @@
tax_units:
tax_unit:
members: [person1]
aca_magi_fraction: 2.50
aca_magi: 25_000
tax_unit_fpg:
2025: 10_000
households:
household:
members: [person1]
Expand All @@ -153,7 +171,9 @@
tax_units:
tax_unit:
members: [person1]
aca_magi_fraction: 2.50
aca_magi: 25_000
tax_unit_fpg:
2024: 10_000
households:
household:
members: [person1]
Expand All @@ -172,7 +192,9 @@
tax_units:
tax_unit:
members: [person1]
aca_magi_fraction: 2.50
aca_magi: 25_000
tax_unit_fpg:
2026: 10_000
households:
household:
members: [person1]
Expand All @@ -181,7 +203,7 @@
vt_premium_assistance_eligible: true

- name: Case 10, 300.01% FPL just barely above the ceiling is ineligible.
# 3.0001 > 3.0 -> ineligible. Tightest just-above-ceiling case (REQ-2 boundary),
# 30_001 / 10_000 = 3.0001 > 3.0 -> ineligible. Tightest just-above-ceiling case (REQ-2 boundary),
# complementing the inclusive 3.00 eligible case and the coarser 3.01 case.
period: 2026
input:
Expand All @@ -192,10 +214,89 @@
tax_units:
tax_unit:
members: [person1]
aca_magi_fraction: 3.0001
aca_magi: 30_001
tax_unit_fpg:
2025: 10_000
households:
household:
members: [person1]
state_code: VT
output:
vt_premium_assistance_eligible: false

- name: Case 11, $46,950 (exactly 300% of the 2025 guideline) is eligible.
# 3 x $15,650 = $46,950; aca_magi_fraction 3.00.
period: 2026
input:
people:
person1:
age: 40
is_aca_ptc_eligible: true
tax_units:
tax_unit:
members: [person1]
aca_magi: 46_950
households:
household:
members: [person1]
state_code: VT
output:
aca_magi_fraction: 3.00
vt_premium_assistance_eligible: true

- name: Case 12, $46,950.47 (300.003%) is ineligible though truncated to 3.00.
period: 2026
input:
people:
person1:
age: 40
is_aca_ptc_eligible: true
tax_units:
tax_unit:
members: [person1]
aca_magi: 46_950.47
households:
household:
members: [person1]
state_code: VT
output:
aca_magi_fraction: 3.00
vt_premium_assistance_eligible: false

- name: Case 13, $47,105.56 (300.994%) is ineligible though truncated to 3.00.
period: 2026
input:
people:
person1:
age: 40
is_aca_ptc_eligible: true
tax_units:
tax_unit:
members: [person1]
aca_magi: 47_105.56
households:
household:
members: [person1]
state_code: VT
output:
aca_magi_fraction: 3.00
vt_premium_assistance_eligible: false

- name: Case 14, $46,949 (299.994%) is eligible.
period: 2026
input:
people:
person1:
age: 40
is_aca_ptc_eligible: true
tax_units:
tax_unit:
members: [person1]
aca_magi: 46_949
households:
household:
members: [person1]
state_code: VT
output:
aca_magi_fraction: 2.99
vt_premium_assistance_eligible: true
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ class vt_premium_assistance_eligible(Variable):
"premium tax credit (which embeds on-Marketplace enrollment, the "
"married-filing-separately exclusion, and the federal required-"
"contribution income test), and household income is at or below 300% of "
"the federal poverty line. Vermont imposes no minimum-income floor, so "
"the federal poverty line, measured as the exact ratio of ACA MAGI to "
"the prior-year guideline rather than the truncated aca_magi_fraction. "
"Vermont imposes no minimum-income floor, so "
"the low end is governed by the federal PTC gate, including its below-"
"poverty immigration exception, which Vermont inherits rather than "
"overrides."
Expand All @@ -28,6 +30,11 @@ def formula(tax_unit, period, parameters):
in_effect = p.in_effect
# At least one member must be eligible for the federal ACA PTC.
aptc_eligible = tax_unit.any(tax_unit.members("is_aca_ptc_eligible", period))
magi_fraction = tax_unit("aca_magi_fraction", period)
income_eligible = magi_fraction <= p.fpl_limit
# 33 V.S.A. 1812(a)(1) covers income "less than or equal to 300
# percent of federal poverty level". Test the exact ratio, not the
# truncated aca_magi_fraction: truncation maps 300.00%-300.99% to
# 3.00, which would admit incomes above 300%.
magi = max_(tax_unit("aca_magi", period), 0)
exact_magi_frac = magi / tax_unit("tax_unit_fpg", period.last_year)
income_eligible = exact_magi_frac <= p.fpl_limit
return in_effect & aptc_eligible & income_eligible