From 072b8ff5b917a8d9071a686bd107f3a8155d2b5a Mon Sep 17 00:00:00 2001 From: David Trimmer Date: Fri, 13 Feb 2026 16:44:17 -0500 Subject: [PATCH 1/5] Add Kentucky HB 13 and HB 152 graduated income tax reforms Implements two Kentucky 2026 legislative session bills that propose graduated income tax rate structures with cliff designs: HB 13 (TY 2027+): - 3.5% on net income up to $250,000 - 6% on net income between $250,000 and $300,000 - Flat 6% on ALL net income if total exceeds $300,000 HB 152 (TY 2027+): - 4% on net income up to $100,000 - 5% on net income between $100,000 and $125,000 - 6% on net income between $125,000 and $150,000 - Flat 6% on ALL net income if total exceeds $150,000 Both bills use a "cliff" design where once income exceeds the top threshold, the higher rate applies to the ENTIRE income. Closes #7395 Co-Authored-By: Claude Opus 4.5 --- changelog_entry.yaml | 4 + .../gov/contrib/states/ky/hb13/brackets.yaml | 21 ++ .../states/ky/hb13/cliff_threshold.yaml | 12 ++ .../gov/contrib/states/ky/hb13/flat_rate.yaml | 12 ++ .../gov/contrib/states/ky/hb13/in_effect.yaml | 14 ++ .../gov/contrib/states/ky/hb152/brackets.yaml | 25 +++ .../states/ky/hb152/cliff_threshold.yaml | 12 ++ .../contrib/states/ky/hb152/flat_rate.yaml | 12 ++ .../contrib/states/ky/hb152/in_effect.yaml | 14 ++ policyengine_us/reforms/reforms.py | 7 + policyengine_us/reforms/states/ky/__init__.py | 4 + .../ky/graduated_income_tax/__init__.py | 4 + .../ky_graduated_income_tax_reform.py | 140 +++++++++++++ .../reforms/states/ky/hb13/ky_hb13.yaml | 154 ++++++++++++++ .../reforms/states/ky/hb152/ky_hb152.yaml | 197 ++++++++++++++++++ 15 files changed, 632 insertions(+) create mode 100644 policyengine_us/parameters/gov/contrib/states/ky/hb13/brackets.yaml create mode 100644 policyengine_us/parameters/gov/contrib/states/ky/hb13/cliff_threshold.yaml create mode 100644 policyengine_us/parameters/gov/contrib/states/ky/hb13/flat_rate.yaml create mode 100644 policyengine_us/parameters/gov/contrib/states/ky/hb13/in_effect.yaml create mode 100644 policyengine_us/parameters/gov/contrib/states/ky/hb152/brackets.yaml create mode 100644 policyengine_us/parameters/gov/contrib/states/ky/hb152/cliff_threshold.yaml create mode 100644 policyengine_us/parameters/gov/contrib/states/ky/hb152/flat_rate.yaml create mode 100644 policyengine_us/parameters/gov/contrib/states/ky/hb152/in_effect.yaml create mode 100644 policyengine_us/reforms/states/ky/__init__.py create mode 100644 policyengine_us/reforms/states/ky/graduated_income_tax/__init__.py create mode 100644 policyengine_us/reforms/states/ky/graduated_income_tax/ky_graduated_income_tax_reform.py create mode 100644 policyengine_us/tests/policy/reforms/states/ky/hb13/ky_hb13.yaml create mode 100644 policyengine_us/tests/policy/reforms/states/ky/hb152/ky_hb152.yaml diff --git a/changelog_entry.yaml b/changelog_entry.yaml index e69de29bb2d..ad01fd95614 100644 --- a/changelog_entry.yaml +++ b/changelog_entry.yaml @@ -0,0 +1,4 @@ +- bump: minor + changes: + added: + - Implements Kentucky HB 13 and HB 152 graduated income tax reforms (2026 session). Both bills propose replacing the current flat rate with graduated brackets and a "cliff" design where income exceeding the threshold is taxed at 6% on the entire amount. diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb13/brackets.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb13/brackets.yaml new file mode 100644 index 00000000000..263040a6879 --- /dev/null +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb13/brackets.yaml @@ -0,0 +1,21 @@ +description: Kentucky HB 13 graduated income tax brackets for income at or below the cliff threshold. + +metadata: + type: marginal_rate + threshold_unit: currency-USD + rate_unit: /1 + period: year + label: Kentucky HB 13 graduated income tax brackets + reference: + - title: Kentucky HB 13 (2026 Session) + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf + +brackets: + - threshold: + 2027-01-01: 0 + rate: + 2027-01-01: 0.035 + - threshold: + 2027-01-01: 250_000 + rate: + 2027-01-01: 0.06 diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb13/cliff_threshold.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb13/cliff_threshold.yaml new file mode 100644 index 00000000000..fbb2ec1a5ec --- /dev/null +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb13/cliff_threshold.yaml @@ -0,0 +1,12 @@ +description: Kentucky HB 13 cliff threshold. If net income exceeds this amount, the flat rate applies to the ENTIRE income (not just marginal). + +values: + 2027-01-01: 300_000 + +metadata: + unit: currency-USD + period: year + label: Kentucky HB 13 cliff threshold + reference: + - title: Kentucky HB 13 (2026 Session) + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb13/flat_rate.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb13/flat_rate.yaml new file mode 100644 index 00000000000..95edb338d67 --- /dev/null +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb13/flat_rate.yaml @@ -0,0 +1,12 @@ +description: Kentucky HB 13 flat rate applied to entire income when income exceeds the cliff threshold. + +values: + 2027-01-01: 0.06 + +metadata: + unit: /1 + period: year + label: Kentucky HB 13 flat rate for high earners + reference: + - title: Kentucky HB 13 (2026 Session) + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb13/in_effect.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb13/in_effect.yaml new file mode 100644 index 00000000000..5b6e7fb3573 --- /dev/null +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb13/in_effect.yaml @@ -0,0 +1,14 @@ +description: Whether Kentucky HB 13 graduated income tax reform is in effect. + +values: + 0000-01-01: false + +metadata: + unit: bool + label: Kentucky HB 13 graduated income tax reform in effect + period: year + reference: + - title: Kentucky HB 13 (2026 Session) + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf + - title: LegiScan - Kentucky HB 13 + href: https://legiscan.com/KY/bill/HB13/2026 diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb152/brackets.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb152/brackets.yaml new file mode 100644 index 00000000000..66efc770b20 --- /dev/null +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb152/brackets.yaml @@ -0,0 +1,25 @@ +description: Kentucky HB 152 graduated income tax brackets for income at or below the cliff threshold. + +metadata: + type: marginal_rate + threshold_unit: currency-USD + rate_unit: /1 + period: year + label: Kentucky HB 152 graduated income tax brackets + reference: + - title: Kentucky HB 152 (2026 Session) + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf + +brackets: + - threshold: + 2027-01-01: 0 + rate: + 2027-01-01: 0.04 + - threshold: + 2027-01-01: 100_000 + rate: + 2027-01-01: 0.05 + - threshold: + 2027-01-01: 125_000 + rate: + 2027-01-01: 0.06 diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb152/cliff_threshold.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb152/cliff_threshold.yaml new file mode 100644 index 00000000000..f067dbf6f67 --- /dev/null +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb152/cliff_threshold.yaml @@ -0,0 +1,12 @@ +description: Kentucky HB 152 cliff threshold. If net income exceeds this amount, the flat rate applies to the ENTIRE income (not just marginal). + +values: + 2027-01-01: 150_000 + +metadata: + unit: currency-USD + period: year + label: Kentucky HB 152 cliff threshold + reference: + - title: Kentucky HB 152 (2026 Session) + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb152/flat_rate.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb152/flat_rate.yaml new file mode 100644 index 00000000000..7ced94a24d6 --- /dev/null +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb152/flat_rate.yaml @@ -0,0 +1,12 @@ +description: Kentucky HB 152 flat rate applied to entire income when income exceeds the cliff threshold. + +values: + 2027-01-01: 0.06 + +metadata: + unit: /1 + period: year + label: Kentucky HB 152 flat rate for high earners + reference: + - title: Kentucky HB 152 (2026 Session) + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb152/in_effect.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb152/in_effect.yaml new file mode 100644 index 00000000000..ff38cf5c74a --- /dev/null +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb152/in_effect.yaml @@ -0,0 +1,14 @@ +description: Whether Kentucky HB 152 graduated income tax reform is in effect. + +values: + 0000-01-01: false + +metadata: + unit: bool + label: Kentucky HB 152 graduated income tax reform in effect + period: year + reference: + - title: Kentucky HB 152 (2026 Session) + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf + - title: LegiScan - Kentucky HB 152 + href: https://legiscan.com/KY/bill/HB152/2026 diff --git a/policyengine_us/reforms/reforms.py b/policyengine_us/reforms/reforms.py index 6af9cf18cc8..c8ad9a2b082 100644 --- a/policyengine_us/reforms/reforms.py +++ b/policyengine_us/reforms/reforms.py @@ -145,6 +145,9 @@ from .cdcc import ( create_cdcc_single_parent_work_requirement_reform, ) +from .states.ky.graduated_income_tax import ( + create_ky_graduated_income_tax_reform, +) from policyengine_core.reforms import Reform @@ -332,6 +335,9 @@ def create_structural_reforms_from_parameters(parameters, period): cdcc_single_parent_work_requirement = ( create_cdcc_single_parent_work_requirement_reform(parameters, period) ) + ky_graduated_income_tax = create_ky_graduated_income_tax_reform( + parameters, period + ) reforms = [ afa_reform, @@ -401,6 +407,7 @@ def create_structural_reforms_from_parameters(parameters, period): aca_ptc_simplified_bracket, aca_ptc_700_fpl_cliff, cdcc_single_parent_work_requirement, + ky_graduated_income_tax, ] reforms = tuple(filter(lambda x: x is not None, reforms)) diff --git a/policyengine_us/reforms/states/ky/__init__.py b/policyengine_us/reforms/states/ky/__init__.py new file mode 100644 index 00000000000..78ded887d71 --- /dev/null +++ b/policyengine_us/reforms/states/ky/__init__.py @@ -0,0 +1,4 @@ +from policyengine_us.reforms.states.ky.graduated_income_tax import ( + create_ky_graduated_income_tax_reform, + ky_graduated_income_tax, +) diff --git a/policyengine_us/reforms/states/ky/graduated_income_tax/__init__.py b/policyengine_us/reforms/states/ky/graduated_income_tax/__init__.py new file mode 100644 index 00000000000..a035175d9df --- /dev/null +++ b/policyengine_us/reforms/states/ky/graduated_income_tax/__init__.py @@ -0,0 +1,4 @@ +from policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform import ( + create_ky_graduated_income_tax_reform, + ky_graduated_income_tax, +) diff --git a/policyengine_us/reforms/states/ky/graduated_income_tax/ky_graduated_income_tax_reform.py b/policyengine_us/reforms/states/ky/graduated_income_tax/ky_graduated_income_tax_reform.py new file mode 100644 index 00000000000..dcfa353f5a0 --- /dev/null +++ b/policyengine_us/reforms/states/ky/graduated_income_tax/ky_graduated_income_tax_reform.py @@ -0,0 +1,140 @@ +from policyengine_us.model_api import * +from policyengine_core.periods import period as period_ + + +def create_ky_graduated_income_tax() -> Reform: + """ + Creates reform for Kentucky HB 13 and HB 152 graduated income tax. + + Both bills implement a "cliff" design where if income exceeds a threshold, + the flat rate applies to the ENTIRE income (not just marginal). + + HB 13 (TY 2027+): + - 3.5% on income up to $250,000 + - 6% on income $250,000-$300,000 + - Flat 6% on ALL income if exceeds $300,000 + + HB 152 (TY 2027+): + - 4% on income up to $100,000 + - 5% on income $100,000-$125,000 + - 6% on income $125,000-$150,000 + - Flat 6% on ALL income if exceeds $150,000 + """ + + def calculate_graduated_tax_with_cliff( + taxable_income, p_hb13, p_hb152, p_baseline + ): + """ + Calculate tax using graduated brackets with cliff design. + + If HB 13 is in effect and income > $300k: 6% on entire income + If HB 152 is in effect and income > $150k: 6% on entire income + Otherwise: use graduated brackets or baseline + """ + hb13_active = p_hb13.in_effect + hb152_active = p_hb152.in_effect + + # HB 13 calculation + hb13_above_cliff = taxable_income > p_hb13.cliff_threshold + hb13_graduated_tax = p_hb13.brackets.calc(taxable_income) + hb13_flat_tax = taxable_income * p_hb13.flat_rate + hb13_tax = where(hb13_above_cliff, hb13_flat_tax, hb13_graduated_tax) + + # HB 152 calculation + hb152_above_cliff = taxable_income > p_hb152.cliff_threshold + hb152_graduated_tax = p_hb152.brackets.calc(taxable_income) + hb152_flat_tax = taxable_income * p_hb152.flat_rate + hb152_tax = where( + hb152_above_cliff, hb152_flat_tax, hb152_graduated_tax + ) + + # Baseline calculation + baseline_tax = taxable_income * p_baseline.rate + + # Apply appropriate calculation based on which reform is active + # HB 13 takes precedence if both are somehow active + return where( + hb13_active, + hb13_tax, + where(hb152_active, hb152_tax, baseline_tax), + ) + + class ky_income_tax_before_non_refundable_credits_indiv(Variable): + value_type = float + entity = Person + label = "Kentucky income tax before non-refundable credits when married couples are filing separately" + unit = USD + definition_period = YEAR + defined_for = StateCode.KY + + def formula(person, period, parameters): + taxable_income = person("ky_taxable_income_indiv", period) + p_hb13 = parameters(period).gov.contrib.states.ky.hb13 + p_hb152 = parameters(period).gov.contrib.states.ky.hb152 + p_baseline = parameters(period).gov.states.ky.tax.income + + return calculate_graduated_tax_with_cliff( + taxable_income, p_hb13, p_hb152, p_baseline + ) + + class ky_income_tax_before_non_refundable_credits_joint(Variable): + value_type = float + entity = Person + label = "Kentucky income tax before non-refundable credits when married filing jointly" + unit = USD + definition_period = YEAR + defined_for = StateCode.KY + + def formula(person, period, parameters): + taxable_income = person("ky_taxable_income_joint", period) + p_hb13 = parameters(period).gov.contrib.states.ky.hb13 + p_hb152 = parameters(period).gov.contrib.states.ky.hb152 + p_baseline = parameters(period).gov.states.ky.tax.income + + return calculate_graduated_tax_with_cliff( + taxable_income, p_hb13, p_hb152, p_baseline + ) + + class reform(Reform): + def apply(self): + self.update_variable( + ky_income_tax_before_non_refundable_credits_indiv + ) + self.update_variable( + ky_income_tax_before_non_refundable_credits_joint + ) + + return reform + + +def create_ky_graduated_income_tax_reform( + parameters, period, bypass: bool = False +): + if bypass: + return create_ky_graduated_income_tax() + + p_hb13 = parameters.gov.contrib.states.ky.hb13 + p_hb152 = parameters.gov.contrib.states.ky.hb152 + + reform_active = False + current_period = period_(period) + + # Check if either reform will be active in the next 5 years + for i in range(5): + if ( + p_hb13(current_period).in_effect + or p_hb152(current_period).in_effect + ): + reform_active = True + break + current_period = current_period.offset(1, "year") + + if reform_active: + return create_ky_graduated_income_tax() + else: + return None + + +ky_graduated_income_tax = create_ky_graduated_income_tax_reform( + None, None, bypass=True +) diff --git a/policyengine_us/tests/policy/reforms/states/ky/hb13/ky_hb13.yaml b/policyengine_us/tests/policy/reforms/states/ky/hb13/ky_hb13.yaml new file mode 100644 index 00000000000..48285269c33 --- /dev/null +++ b/policyengine_us/tests/policy/reforms/states/ky/hb13/ky_hb13.yaml @@ -0,0 +1,154 @@ +# Test Kentucky HB 13 Graduated Income Tax Reform +# For 2027+: 3.5% up to $250k, 6% $250k-$300k, flat 6% on ALL income if >$300k + +- name: KY HB 13 - income below $250k threshold (single filing) + period: 2027 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb13.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 100_000 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + # 100000 * 0.035 = 3500 + ky_income_tax_before_non_refundable_credits_indiv: 3500 + +- name: KY HB 13 - income between $250k and $300k (graduated rates) + period: 2027 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb13.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 280_000 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + # 250000 * 0.035 + 30000 * 0.06 = 8750 + 1800 = 10550 + ky_income_tax_before_non_refundable_credits_indiv: 10550 + +- name: KY HB 13 - income at exactly $300k threshold (still graduated) + period: 2027 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb13.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 300_000 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + # 250000 * 0.035 + 50000 * 0.06 = 8750 + 3000 = 11750 + ky_income_tax_before_non_refundable_credits_indiv: 11750 + +- name: KY HB 13 - income above $300k (cliff - flat 6% on ENTIRE income) + period: 2027 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb13.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 300_001 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + # CLIFF: 300001 * 0.06 = 18000.06 + ky_income_tax_before_non_refundable_credits_indiv: 18000.06 + +- name: KY HB 13 - high income above cliff + period: 2027 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb13.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 500_000 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + # CLIFF: 500000 * 0.06 = 30000 + ky_income_tax_before_non_refundable_credits_indiv: 30000 + +- name: KY HB 13 - joint filing above cliff + period: 2027 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb13.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_joint: 400_000 + person2: + age: 43 + ky_taxable_income_joint: 0 + tax_units: + tax_unit: + members: [person1, person2] + filing_status: JOINT + households: + household: + members: [person1, person2] + state_code: KY + output: + # CLIFF: 400000 * 0.06 = 24000 (on person1 who has the income) + ky_income_tax_before_non_refundable_credits_joint: + - 24000 + - 0 + +- name: KY HB 13 - reform not in effect uses baseline + period: 2027 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb13.in_effect: false + people: + person1: + age: 45 + ky_taxable_income_indiv: 500_000 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + # Baseline 2027 rate: 3.5% -> 500000 * 0.035 = 17500 + ky_income_tax_before_non_refundable_credits_indiv: 17500 diff --git a/policyengine_us/tests/policy/reforms/states/ky/hb152/ky_hb152.yaml b/policyengine_us/tests/policy/reforms/states/ky/hb152/ky_hb152.yaml new file mode 100644 index 00000000000..84b04ed1e1e --- /dev/null +++ b/policyengine_us/tests/policy/reforms/states/ky/hb152/ky_hb152.yaml @@ -0,0 +1,197 @@ +# Test Kentucky HB 152 Graduated Income Tax Reform +# For 2027+: 4% up to $100k, 5% $100k-$125k, 6% $125k-$150k, +# flat 6% on ALL income if >$150k + +- name: KY HB 152 - income below $100k threshold + period: 2027 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb152.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 50_000 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + # 50000 * 0.04 = 2000 + ky_income_tax_before_non_refundable_credits_indiv: 2000 + +- name: KY HB 152 - income between $100k and $125k + period: 2027 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb152.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 110_000 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + # 100000 * 0.04 + 10000 * 0.05 = 4000 + 500 = 4500 + ky_income_tax_before_non_refundable_credits_indiv: 4500 + +- name: KY HB 152 - income between $125k and $150k + period: 2027 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb152.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 140_000 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + # 100000 * 0.04 + 25000 * 0.05 + 15000 * 0.06 = 4000 + 1250 + 900 = 6150 + ky_income_tax_before_non_refundable_credits_indiv: 6150 + +- name: KY HB 152 - income at exactly $150k threshold (still graduated) + period: 2027 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb152.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 150_000 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + # 100000 * 0.04 + 25000 * 0.05 + 25000 * 0.06 = 4000 + 1250 + 1500 = 6750 + ky_income_tax_before_non_refundable_credits_indiv: 6750 + +- name: KY HB 152 - income above $150k (cliff - flat 6% on ENTIRE income) + period: 2027 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb152.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 150_001 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + # CLIFF: 150001 * 0.06 = 9000.06 + ky_income_tax_before_non_refundable_credits_indiv: 9000.06 + +- name: KY HB 152 - high income above cliff + period: 2027 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb152.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 300_000 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + # CLIFF: 300000 * 0.06 = 18000 + ky_income_tax_before_non_refundable_credits_indiv: 18000 + +- name: KY HB 152 - joint filing above cliff + period: 2027 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb152.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_joint: 200_000 + person2: + age: 43 + ky_taxable_income_joint: 0 + tax_units: + tax_unit: + members: [person1, person2] + filing_status: JOINT + households: + household: + members: [person1, person2] + state_code: KY + output: + # CLIFF: 200000 * 0.06 = 12000 (on person1) + ky_income_tax_before_non_refundable_credits_joint: + - 12000 + - 0 + +- name: KY HB 152 - reform not in effect uses baseline + period: 2027 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb152.in_effect: false + people: + person1: + age: 45 + ky_taxable_income_indiv: 200_000 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + # Baseline 2027 rate: 3.5% -> 200000 * 0.035 = 7000 + ky_income_tax_before_non_refundable_credits_indiv: 7000 + +- name: KY HB 152 - cliff notch effect demonstration + period: 2027 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb152.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 149_999 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + # Just below cliff: 100000*0.04 + 25000*0.05 + 24999*0.06 = 4000+1250+1499.94 = 6749.94 + ky_income_tax_before_non_refundable_credits_indiv: 6749.94 From f3f949e39e0b7a9d39700071ab172a4ee5a7c3cb Mon Sep 17 00:00:00 2001 From: David Trimmer Date: Fri, 13 Feb 2026 17:07:23 -0500 Subject: [PATCH 2/5] Add page numbers and section references to KY bill references Updated all 8 parameter files to include: - PDF page anchors (#page=3) for direct navigation - Section references (Section 1, KRS 141.020(2)) - Clarified LegiScan as bill status tracking reference Co-Authored-By: Claude Opus 4.5 --- .../parameters/gov/contrib/states/ky/hb13/brackets.yaml | 4 ++-- .../gov/contrib/states/ky/hb13/cliff_threshold.yaml | 4 ++-- .../parameters/gov/contrib/states/ky/hb13/flat_rate.yaml | 4 ++-- .../parameters/gov/contrib/states/ky/hb13/in_effect.yaml | 6 +++--- .../parameters/gov/contrib/states/ky/hb152/brackets.yaml | 4 ++-- .../gov/contrib/states/ky/hb152/cliff_threshold.yaml | 4 ++-- .../parameters/gov/contrib/states/ky/hb152/flat_rate.yaml | 4 ++-- .../parameters/gov/contrib/states/ky/hb152/in_effect.yaml | 6 +++--- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb13/brackets.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb13/brackets.yaml index 263040a6879..65857be9fbe 100644 --- a/policyengine_us/parameters/gov/contrib/states/ky/hb13/brackets.yaml +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb13/brackets.yaml @@ -7,8 +7,8 @@ metadata: period: year label: Kentucky HB 13 graduated income tax brackets reference: - - title: Kentucky HB 13 (2026 Session) - href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf + - title: Kentucky HB 13 (2026 Session), Section 1, KRS 141.020(2) + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf#page=3 brackets: - threshold: diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb13/cliff_threshold.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb13/cliff_threshold.yaml index fbb2ec1a5ec..082b9ef9bfc 100644 --- a/policyengine_us/parameters/gov/contrib/states/ky/hb13/cliff_threshold.yaml +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb13/cliff_threshold.yaml @@ -8,5 +8,5 @@ metadata: period: year label: Kentucky HB 13 cliff threshold reference: - - title: Kentucky HB 13 (2026 Session) - href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf + - title: Kentucky HB 13 (2026 Session), Section 1, KRS 141.020(2) + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf#page=3 diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb13/flat_rate.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb13/flat_rate.yaml index 95edb338d67..e92206c7e4f 100644 --- a/policyengine_us/parameters/gov/contrib/states/ky/hb13/flat_rate.yaml +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb13/flat_rate.yaml @@ -8,5 +8,5 @@ metadata: period: year label: Kentucky HB 13 flat rate for high earners reference: - - title: Kentucky HB 13 (2026 Session) - href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf + - title: Kentucky HB 13 (2026 Session), Section 1, KRS 141.020(2) + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf#page=3 diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb13/in_effect.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb13/in_effect.yaml index 5b6e7fb3573..7c4ceb8a172 100644 --- a/policyengine_us/parameters/gov/contrib/states/ky/hb13/in_effect.yaml +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb13/in_effect.yaml @@ -8,7 +8,7 @@ metadata: label: Kentucky HB 13 graduated income tax reform in effect period: year reference: - - title: Kentucky HB 13 (2026 Session) - href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf - - title: LegiScan - Kentucky HB 13 + - title: Kentucky HB 13 (2026 Session), Section 1, KRS 141.020(2) + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf#page=3 + - title: LegiScan - Kentucky HB 13 (bill status) href: https://legiscan.com/KY/bill/HB13/2026 diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb152/brackets.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb152/brackets.yaml index 66efc770b20..a38efd9446e 100644 --- a/policyengine_us/parameters/gov/contrib/states/ky/hb152/brackets.yaml +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb152/brackets.yaml @@ -7,8 +7,8 @@ metadata: period: year label: Kentucky HB 152 graduated income tax brackets reference: - - title: Kentucky HB 152 (2026 Session) - href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf + - title: Kentucky HB 152 (2026 Session), Section 1, KRS 141.020(2) + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf#page=3 brackets: - threshold: diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb152/cliff_threshold.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb152/cliff_threshold.yaml index f067dbf6f67..7339fd09e0f 100644 --- a/policyengine_us/parameters/gov/contrib/states/ky/hb152/cliff_threshold.yaml +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb152/cliff_threshold.yaml @@ -8,5 +8,5 @@ metadata: period: year label: Kentucky HB 152 cliff threshold reference: - - title: Kentucky HB 152 (2026 Session) - href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf + - title: Kentucky HB 152 (2026 Session), Section 1, KRS 141.020(2) + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf#page=3 diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb152/flat_rate.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb152/flat_rate.yaml index 7ced94a24d6..6e4da4f8ea6 100644 --- a/policyengine_us/parameters/gov/contrib/states/ky/hb152/flat_rate.yaml +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb152/flat_rate.yaml @@ -8,5 +8,5 @@ metadata: period: year label: Kentucky HB 152 flat rate for high earners reference: - - title: Kentucky HB 152 (2026 Session) - href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf + - title: Kentucky HB 152 (2026 Session), Section 1, KRS 141.020(2) + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf#page=3 diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb152/in_effect.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb152/in_effect.yaml index ff38cf5c74a..cdd08050f9a 100644 --- a/policyengine_us/parameters/gov/contrib/states/ky/hb152/in_effect.yaml +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb152/in_effect.yaml @@ -8,7 +8,7 @@ metadata: label: Kentucky HB 152 graduated income tax reform in effect period: year reference: - - title: Kentucky HB 152 (2026 Session) - href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf - - title: LegiScan - Kentucky HB 152 + - title: Kentucky HB 152 (2026 Session), Section 1, KRS 141.020(2) + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf#page=3 + - title: LegiScan - Kentucky HB 152 (bill status) href: https://legiscan.com/KY/bill/HB152/2026 From 35794f0f5e550c69320a2e457d18020dcafbea17 Mon Sep 17 00:00:00 2001 From: PavelMakarchuk Date: Wed, 25 Feb 2026 18:52:41 -0500 Subject: [PATCH 3/5] Fix HB 152 cliff boundary, add error margins and edge case tests - Fix HB 152 cliff comparison from > to >= to match bill language ("$150,000 or more" triggers flat rate) - Update cliff_threshold.yaml description to reflect >= semantics - Add references to both reform variable classes - Add absolute_error_margin to all existing test cases - Add edge case tests: zero income, bracket boundaries, cliff notch, non-KY resident, joint graduated rates, both-reforms-active Co-Authored-By: Claude Opus 4.6 --- .../states/ky/hb152/cliff_threshold.yaml | 2 +- .../ky_graduated_income_tax_reform.py | 18 ++- .../reforms/states/ky/hb13/ky_hb13.yaml | 144 ++++++++++++++++++ .../reforms/states/ky/hb152/ky_hb152.yaml | 130 +++++++++++++++- 4 files changed, 284 insertions(+), 10 deletions(-) diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb152/cliff_threshold.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb152/cliff_threshold.yaml index 7339fd09e0f..a5c314dac34 100644 --- a/policyengine_us/parameters/gov/contrib/states/ky/hb152/cliff_threshold.yaml +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb152/cliff_threshold.yaml @@ -1,4 +1,4 @@ -description: Kentucky HB 152 cliff threshold. If net income exceeds this amount, the flat rate applies to the ENTIRE income (not just marginal). +description: Kentucky HB 152 cliff threshold. If net income is this amount or more, the flat rate applies to the ENTIRE income (not just marginal). values: 2027-01-01: 150_000 diff --git a/policyengine_us/reforms/states/ky/graduated_income_tax/ky_graduated_income_tax_reform.py b/policyengine_us/reforms/states/ky/graduated_income_tax/ky_graduated_income_tax_reform.py index dcfa353f5a0..0eac9a75acd 100644 --- a/policyengine_us/reforms/states/ky/graduated_income_tax/ky_graduated_income_tax_reform.py +++ b/policyengine_us/reforms/states/ky/graduated_income_tax/ky_graduated_income_tax_reform.py @@ -6,19 +6,19 @@ def create_ky_graduated_income_tax() -> Reform: """ Creates reform for Kentucky HB 13 and HB 152 graduated income tax. - Both bills implement a "cliff" design where if income exceeds a threshold, + Both bills implement a "cliff" design where above a threshold, the flat rate applies to the ENTIRE income (not just marginal). HB 13 (TY 2027+): - 3.5% on income up to $250,000 - 6% on income $250,000-$300,000 - - Flat 6% on ALL income if exceeds $300,000 + - Flat 6% on ALL income if income exceeds $300,000 (strict >) HB 152 (TY 2027+): - 4% on income up to $100,000 - 5% on income $100,000-$125,000 - 6% on income $125,000-$150,000 - - Flat 6% on ALL income if exceeds $150,000 + - Flat 6% on ALL income if income is $150,000 or more (>=) """ def calculate_graduated_tax_with_cliff( @@ -28,7 +28,7 @@ def calculate_graduated_tax_with_cliff( Calculate tax using graduated brackets with cliff design. If HB 13 is in effect and income > $300k: 6% on entire income - If HB 152 is in effect and income > $150k: 6% on entire income + If HB 152 is in effect and income >= $150k: 6% on entire income Otherwise: use graduated brackets or baseline """ hb13_active = p_hb13.in_effect @@ -41,7 +41,7 @@ def calculate_graduated_tax_with_cliff( hb13_tax = where(hb13_above_cliff, hb13_flat_tax, hb13_graduated_tax) # HB 152 calculation - hb152_above_cliff = taxable_income > p_hb152.cliff_threshold + hb152_above_cliff = taxable_income >= p_hb152.cliff_threshold hb152_graduated_tax = p_hb152.brackets.calc(taxable_income) hb152_flat_tax = taxable_income * p_hb152.flat_rate hb152_tax = where( @@ -66,6 +66,10 @@ class ky_income_tax_before_non_refundable_credits_indiv(Variable): unit = USD definition_period = YEAR defined_for = StateCode.KY + reference = [ + "https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf#page=3", + "https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf#page=3", + ] def formula(person, period, parameters): taxable_income = person("ky_taxable_income_indiv", period) @@ -84,6 +88,10 @@ class ky_income_tax_before_non_refundable_credits_joint(Variable): unit = USD definition_period = YEAR defined_for = StateCode.KY + reference = [ + "https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf#page=3", + "https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf#page=3", + ] def formula(person, period, parameters): taxable_income = person("ky_taxable_income_joint", period) diff --git a/policyengine_us/tests/policy/reforms/states/ky/hb13/ky_hb13.yaml b/policyengine_us/tests/policy/reforms/states/ky/hb13/ky_hb13.yaml index 48285269c33..434de5a3ea3 100644 --- a/policyengine_us/tests/policy/reforms/states/ky/hb13/ky_hb13.yaml +++ b/policyengine_us/tests/policy/reforms/states/ky/hb13/ky_hb13.yaml @@ -3,6 +3,7 @@ - name: KY HB 13 - income below $250k threshold (single filing) period: 2027 + absolute_error_margin: 0.01 reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax input: gov.contrib.states.ky.hb13.in_effect: true @@ -24,6 +25,7 @@ - name: KY HB 13 - income between $250k and $300k (graduated rates) period: 2027 + absolute_error_margin: 0.01 reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax input: gov.contrib.states.ky.hb13.in_effect: true @@ -45,6 +47,7 @@ - name: KY HB 13 - income at exactly $300k threshold (still graduated) period: 2027 + absolute_error_margin: 0.01 reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax input: gov.contrib.states.ky.hb13.in_effect: true @@ -66,6 +69,7 @@ - name: KY HB 13 - income above $300k (cliff - flat 6% on ENTIRE income) period: 2027 + absolute_error_margin: 0.01 reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax input: gov.contrib.states.ky.hb13.in_effect: true @@ -87,6 +91,7 @@ - name: KY HB 13 - high income above cliff period: 2027 + absolute_error_margin: 0.01 reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax input: gov.contrib.states.ky.hb13.in_effect: true @@ -108,6 +113,7 @@ - name: KY HB 13 - joint filing above cliff period: 2027 + absolute_error_margin: 0.01 reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax input: gov.contrib.states.ky.hb13.in_effect: true @@ -134,6 +140,7 @@ - name: KY HB 13 - reform not in effect uses baseline period: 2027 + absolute_error_margin: 0.01 reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax input: gov.contrib.states.ky.hb13.in_effect: false @@ -152,3 +159,140 @@ output: # Baseline 2027 rate: 3.5% -> 500000 * 0.035 = 17500 ky_income_tax_before_non_refundable_credits_indiv: 17500 + +- name: KY HB 13 - zero income + period: 2027 + absolute_error_margin: 0.01 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb13.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 0 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + ky_income_tax_before_non_refundable_credits_indiv: 0 + +- name: KY HB 13 - income at exactly $250k bracket boundary + period: 2027 + absolute_error_margin: 0.01 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb13.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 250_000 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + # 250000 * 0.035 = 8750 + ky_income_tax_before_non_refundable_credits_indiv: 8750 + +- name: KY HB 13 - cliff notch just below $300k + period: 2027 + absolute_error_margin: 0.01 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb13.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 299_999 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + # Just below cliff: 250000*0.035 + 49999*0.06 = 8750 + 2999.94 = 11749.94 + ky_income_tax_before_non_refundable_credits_indiv: 11749.94 + +- name: KY HB 13 - both reforms active (HB 13 takes precedence) + period: 2027 + absolute_error_margin: 0.01 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb13.in_effect: true + gov.contrib.states.ky.hb152.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 200_000 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + # HB 13 takes precedence: 200000 * 0.035 = 7000 + # (HB 152 would give: 100000*0.04 + 25000*0.05 + 25000*0.06 + 50000*0.06 = 4000+1250+1500+3000 = 9750) + ky_income_tax_before_non_refundable_credits_indiv: 7000 + +- name: KY HB 13 - non-KY resident gets zero + period: 2027 + absolute_error_margin: 0.01 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb13.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 500_000 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: CA + output: + ky_income_tax_before_non_refundable_credits_indiv: 0 + +- name: KY HB 13 - joint filing with graduated rates + period: 2027 + absolute_error_margin: 0.01 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb13.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_joint: 280_000 + person2: + age: 43 + ky_taxable_income_joint: 0 + tax_units: + tax_unit: + members: [person1, person2] + filing_status: JOINT + households: + household: + members: [person1, person2] + state_code: KY + output: + # 250000*0.035 + 30000*0.06 = 8750 + 1800 = 10550 + ky_income_tax_before_non_refundable_credits_joint: + - 10550 + - 0 diff --git a/policyengine_us/tests/policy/reforms/states/ky/hb152/ky_hb152.yaml b/policyengine_us/tests/policy/reforms/states/ky/hb152/ky_hb152.yaml index 84b04ed1e1e..25ca8634f21 100644 --- a/policyengine_us/tests/policy/reforms/states/ky/hb152/ky_hb152.yaml +++ b/policyengine_us/tests/policy/reforms/states/ky/hb152/ky_hb152.yaml @@ -1,9 +1,10 @@ # Test Kentucky HB 152 Graduated Income Tax Reform # For 2027+: 4% up to $100k, 5% $100k-$125k, 6% $125k-$150k, -# flat 6% on ALL income if >$150k +# flat 6% on ALL income if >= $150k - name: KY HB 152 - income below $100k threshold period: 2027 + absolute_error_margin: 0.01 reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax input: gov.contrib.states.ky.hb152.in_effect: true @@ -25,6 +26,7 @@ - name: KY HB 152 - income between $100k and $125k period: 2027 + absolute_error_margin: 0.01 reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax input: gov.contrib.states.ky.hb152.in_effect: true @@ -46,6 +48,7 @@ - name: KY HB 152 - income between $125k and $150k period: 2027 + absolute_error_margin: 0.01 reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax input: gov.contrib.states.ky.hb152.in_effect: true @@ -65,8 +68,9 @@ # 100000 * 0.04 + 25000 * 0.05 + 15000 * 0.06 = 4000 + 1250 + 900 = 6150 ky_income_tax_before_non_refundable_credits_indiv: 6150 -- name: KY HB 152 - income at exactly $150k threshold (still graduated) +- name: KY HB 152 - income at exactly $150k threshold (cliff - flat 6%) period: 2027 + absolute_error_margin: 0.01 reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax input: gov.contrib.states.ky.hb152.in_effect: true @@ -83,11 +87,12 @@ members: [person1] state_code: KY output: - # 100000 * 0.04 + 25000 * 0.05 + 25000 * 0.06 = 4000 + 1250 + 1500 = 6750 - ky_income_tax_before_non_refundable_credits_indiv: 6750 + # Bill says "$150,000 or more" triggers flat rate: 150000 * 0.06 = 9000 + ky_income_tax_before_non_refundable_credits_indiv: 9000 - name: KY HB 152 - income above $150k (cliff - flat 6% on ENTIRE income) period: 2027 + absolute_error_margin: 0.01 reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax input: gov.contrib.states.ky.hb152.in_effect: true @@ -109,6 +114,7 @@ - name: KY HB 152 - high income above cliff period: 2027 + absolute_error_margin: 0.01 reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax input: gov.contrib.states.ky.hb152.in_effect: true @@ -130,6 +136,7 @@ - name: KY HB 152 - joint filing above cliff period: 2027 + absolute_error_margin: 0.01 reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax input: gov.contrib.states.ky.hb152.in_effect: true @@ -156,6 +163,7 @@ - name: KY HB 152 - reform not in effect uses baseline period: 2027 + absolute_error_margin: 0.01 reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax input: gov.contrib.states.ky.hb152.in_effect: false @@ -177,6 +185,7 @@ - name: KY HB 152 - cliff notch effect demonstration period: 2027 + absolute_error_margin: 0.01 reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax input: gov.contrib.states.ky.hb152.in_effect: true @@ -195,3 +204,116 @@ output: # Just below cliff: 100000*0.04 + 25000*0.05 + 24999*0.06 = 4000+1250+1499.94 = 6749.94 ky_income_tax_before_non_refundable_credits_indiv: 6749.94 + +- name: KY HB 152 - zero income + period: 2027 + absolute_error_margin: 0.01 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb152.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 0 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + ky_income_tax_before_non_refundable_credits_indiv: 0 + +- name: KY HB 152 - income at exactly $100k bracket boundary + period: 2027 + absolute_error_margin: 0.01 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb152.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 100_000 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + # 100000 * 0.04 = 4000 + ky_income_tax_before_non_refundable_credits_indiv: 4000 + +- name: KY HB 152 - income at exactly $125k bracket boundary + period: 2027 + absolute_error_margin: 0.01 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb152.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 125_000 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + # 100000 * 0.04 + 25000 * 0.05 = 4000 + 1250 = 5250 + ky_income_tax_before_non_refundable_credits_indiv: 5250 + +- name: KY HB 152 - non-KY resident gets zero + period: 2027 + absolute_error_margin: 0.01 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb152.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 300_000 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: CA + output: + ky_income_tax_before_non_refundable_credits_indiv: 0 + +- name: KY HB 152 - joint filing with graduated rates + period: 2027 + absolute_error_margin: 0.01 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb152.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_joint: 140_000 + person2: + age: 43 + ky_taxable_income_joint: 0 + tax_units: + tax_unit: + members: [person1, person2] + filing_status: JOINT + households: + household: + members: [person1, person2] + state_code: KY + output: + # 100000*0.04 + 25000*0.05 + 15000*0.06 = 4000 + 1250 + 900 = 6150 + ky_income_tax_before_non_refundable_credits_joint: + - 6150 + - 0 From 00d56c4c197e86499e51bc9fed8471b5cd133ddd Mon Sep 17 00:00:00 2001 From: PavelMakarchuk Date: Thu, 26 Feb 2026 17:12:15 -0500 Subject: [PATCH 4/5] Fix review findings: changelog, references, page numbers, descriptions - Add changelog fragment for towncrier - Change reference from [] to () in reform variable classes - Fix #page=3 to #page=1 in all 8 parameter YAML files (rates on page 1) - Fix cliff_threshold descriptions to single sentences - Replace LegiScan URLs with official apps.legislature.ky.gov URLs - Trim docstrings to reference parameter files instead of hard-coded values Co-Authored-By: Claude Opus 4.6 --- ...y-hb13-hb152-graduated-income-tax.added.md | 1 + .../gov/contrib/states/ky/hb13/brackets.yaml | 2 +- .../states/ky/hb13/cliff_threshold.yaml | 4 +- .../gov/contrib/states/ky/hb13/flat_rate.yaml | 2 +- .../gov/contrib/states/ky/hb13/in_effect.yaml | 6 +-- .../gov/contrib/states/ky/hb152/brackets.yaml | 2 +- .../states/ky/hb152/cliff_threshold.yaml | 4 +- .../contrib/states/ky/hb152/flat_rate.yaml | 2 +- .../contrib/states/ky/hb152/in_effect.yaml | 6 +-- .../ky_graduated_income_tax_reform.py | 41 ++++++++----------- 10 files changed, 32 insertions(+), 38 deletions(-) create mode 100644 changelog.d/ky-hb13-hb152-graduated-income-tax.added.md diff --git a/changelog.d/ky-hb13-hb152-graduated-income-tax.added.md b/changelog.d/ky-hb13-hb152-graduated-income-tax.added.md new file mode 100644 index 00000000000..fb7303785c2 --- /dev/null +++ b/changelog.d/ky-hb13-hb152-graduated-income-tax.added.md @@ -0,0 +1 @@ +Added Kentucky HB 13 and HB 152 graduated income tax reforms with cliff design. diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb13/brackets.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb13/brackets.yaml index 65857be9fbe..063bc2876b2 100644 --- a/policyengine_us/parameters/gov/contrib/states/ky/hb13/brackets.yaml +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb13/brackets.yaml @@ -8,7 +8,7 @@ metadata: label: Kentucky HB 13 graduated income tax brackets reference: - title: Kentucky HB 13 (2026 Session), Section 1, KRS 141.020(2) - href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf#page=3 + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf#page=1 brackets: - threshold: diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb13/cliff_threshold.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb13/cliff_threshold.yaml index 082b9ef9bfc..42ab7c9252d 100644 --- a/policyengine_us/parameters/gov/contrib/states/ky/hb13/cliff_threshold.yaml +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb13/cliff_threshold.yaml @@ -1,4 +1,4 @@ -description: Kentucky HB 13 cliff threshold. If net income exceeds this amount, the flat rate applies to the ENTIRE income (not just marginal). +description: Kentucky House Bill 13 sets this as the income threshold above which the flat rate applies to the entire income. values: 2027-01-01: 300_000 @@ -9,4 +9,4 @@ metadata: label: Kentucky HB 13 cliff threshold reference: - title: Kentucky HB 13 (2026 Session), Section 1, KRS 141.020(2) - href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf#page=3 + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf#page=1 diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb13/flat_rate.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb13/flat_rate.yaml index e92206c7e4f..565d34adbf8 100644 --- a/policyengine_us/parameters/gov/contrib/states/ky/hb13/flat_rate.yaml +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb13/flat_rate.yaml @@ -9,4 +9,4 @@ metadata: label: Kentucky HB 13 flat rate for high earners reference: - title: Kentucky HB 13 (2026 Session), Section 1, KRS 141.020(2) - href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf#page=3 + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf#page=1 diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb13/in_effect.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb13/in_effect.yaml index 7c4ceb8a172..a611f80d1eb 100644 --- a/policyengine_us/parameters/gov/contrib/states/ky/hb13/in_effect.yaml +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb13/in_effect.yaml @@ -9,6 +9,6 @@ metadata: period: year reference: - title: Kentucky HB 13 (2026 Session), Section 1, KRS 141.020(2) - href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf#page=3 - - title: LegiScan - Kentucky HB 13 (bill status) - href: https://legiscan.com/KY/bill/HB13/2026 + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf#page=1 + - title: Kentucky Legislature - HB 13 (bill status) + href: https://apps.legislature.ky.gov/record/26RS/hb13.html diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb152/brackets.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb152/brackets.yaml index a38efd9446e..d9ec745e6c1 100644 --- a/policyengine_us/parameters/gov/contrib/states/ky/hb152/brackets.yaml +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb152/brackets.yaml @@ -8,7 +8,7 @@ metadata: label: Kentucky HB 152 graduated income tax brackets reference: - title: Kentucky HB 152 (2026 Session), Section 1, KRS 141.020(2) - href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf#page=3 + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf#page=1 brackets: - threshold: diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb152/cliff_threshold.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb152/cliff_threshold.yaml index a5c314dac34..f745143fbb0 100644 --- a/policyengine_us/parameters/gov/contrib/states/ky/hb152/cliff_threshold.yaml +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb152/cliff_threshold.yaml @@ -1,4 +1,4 @@ -description: Kentucky HB 152 cliff threshold. If net income is this amount or more, the flat rate applies to the ENTIRE income (not just marginal). +description: Kentucky House Bill 152 sets this as the income threshold at or above which the flat rate applies to the entire income. values: 2027-01-01: 150_000 @@ -9,4 +9,4 @@ metadata: label: Kentucky HB 152 cliff threshold reference: - title: Kentucky HB 152 (2026 Session), Section 1, KRS 141.020(2) - href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf#page=3 + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf#page=1 diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb152/flat_rate.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb152/flat_rate.yaml index 6e4da4f8ea6..c972cd3356b 100644 --- a/policyengine_us/parameters/gov/contrib/states/ky/hb152/flat_rate.yaml +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb152/flat_rate.yaml @@ -9,4 +9,4 @@ metadata: label: Kentucky HB 152 flat rate for high earners reference: - title: Kentucky HB 152 (2026 Session), Section 1, KRS 141.020(2) - href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf#page=3 + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf#page=1 diff --git a/policyengine_us/parameters/gov/contrib/states/ky/hb152/in_effect.yaml b/policyengine_us/parameters/gov/contrib/states/ky/hb152/in_effect.yaml index cdd08050f9a..fe86c43e10e 100644 --- a/policyengine_us/parameters/gov/contrib/states/ky/hb152/in_effect.yaml +++ b/policyengine_us/parameters/gov/contrib/states/ky/hb152/in_effect.yaml @@ -9,6 +9,6 @@ metadata: period: year reference: - title: Kentucky HB 152 (2026 Session), Section 1, KRS 141.020(2) - href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf#page=3 - - title: LegiScan - Kentucky HB 152 (bill status) - href: https://legiscan.com/KY/bill/HB152/2026 + href: https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf#page=1 + - title: Kentucky Legislature - HB 152 (bill status) + href: https://apps.legislature.ky.gov/record/26RS/hb152.html diff --git a/policyengine_us/reforms/states/ky/graduated_income_tax/ky_graduated_income_tax_reform.py b/policyengine_us/reforms/states/ky/graduated_income_tax/ky_graduated_income_tax_reform.py index 0eac9a75acd..5996b03bc57 100644 --- a/policyengine_us/reforms/states/ky/graduated_income_tax/ky_graduated_income_tax_reform.py +++ b/policyengine_us/reforms/states/ky/graduated_income_tax/ky_graduated_income_tax_reform.py @@ -6,19 +6,12 @@ def create_ky_graduated_income_tax() -> Reform: """ Creates reform for Kentucky HB 13 and HB 152 graduated income tax. - Both bills implement a "cliff" design where above a threshold, - the flat rate applies to the ENTIRE income (not just marginal). - - HB 13 (TY 2027+): - - 3.5% on income up to $250,000 - - 6% on income $250,000-$300,000 - - Flat 6% on ALL income if income exceeds $300,000 (strict >) - - HB 152 (TY 2027+): - - 4% on income up to $100,000 - - 5% on income $100,000-$125,000 - - 6% on income $125,000-$150,000 - - Flat 6% on ALL income if income is $150,000 or more (>=) + Both bills amend KRS 141.020(2) to implement graduated brackets + with a "cliff" design where above a threshold, the flat rate + applies to the ENTIRE income (not just marginal). + + See parameter files under gov/contrib/states/ky/hb13/ and hb152/ + for specific rates, thresholds, and effective dates. """ def calculate_graduated_tax_with_cliff( @@ -27,9 +20,9 @@ def calculate_graduated_tax_with_cliff( """ Calculate tax using graduated brackets with cliff design. - If HB 13 is in effect and income > $300k: 6% on entire income - If HB 152 is in effect and income >= $150k: 6% on entire income - Otherwise: use graduated brackets or baseline + HB 13 takes precedence if both are active. Each bill applies + its flat rate to the entire income when the cliff threshold + is exceeded; otherwise graduated brackets apply. """ hb13_active = p_hb13.in_effect hb152_active = p_hb152.in_effect @@ -66,10 +59,10 @@ class ky_income_tax_before_non_refundable_credits_indiv(Variable): unit = USD definition_period = YEAR defined_for = StateCode.KY - reference = [ - "https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf#page=3", - "https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf#page=3", - ] + reference = ( + "https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf#page=1", + "https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf#page=1", + ) def formula(person, period, parameters): taxable_income = person("ky_taxable_income_indiv", period) @@ -88,10 +81,10 @@ class ky_income_tax_before_non_refundable_credits_joint(Variable): unit = USD definition_period = YEAR defined_for = StateCode.KY - reference = [ - "https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf#page=3", - "https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf#page=3", - ] + reference = ( + "https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb13/orig_bill.pdf#page=1", + "https://apps.legislature.ky.gov/recorddocuments/bill/26RS/hb152/orig_bill.pdf#page=1", + ) def formula(person, period, parameters): taxable_income = person("ky_taxable_income_joint", period) From 88d93f8e38e4b259fd847acb8d619e10f4872588 Mon Sep 17 00:00:00 2001 From: PavelMakarchuk Date: Thu, 26 Feb 2026 17:41:38 -0500 Subject: [PATCH 5/5] Add test coverage: joint cliff boundary, end-to-end, filing optimization tests Move test files from tests/policy/reforms/ to tests/policy/contrib/ to match convention. Add joint filing cliff boundary tests, end-to-end integration tests through ky_income_tax, filing optimization tests, and both-reforms-active tests. Co-Authored-By: Claude Opus 4.6 --- .../states/ky/hb13/ky_hb13.yaml | 117 ++++++++++++++++++ .../states/ky/hb152/ky_hb152.yaml | 110 ++++++++++++++++ 2 files changed, 227 insertions(+) rename policyengine_us/tests/policy/{reforms => contrib}/states/ky/hb13/ky_hb13.yaml (71%) rename policyengine_us/tests/policy/{reforms => contrib}/states/ky/hb152/ky_hb152.yaml (73%) diff --git a/policyengine_us/tests/policy/reforms/states/ky/hb13/ky_hb13.yaml b/policyengine_us/tests/policy/contrib/states/ky/hb13/ky_hb13.yaml similarity index 71% rename from policyengine_us/tests/policy/reforms/states/ky/hb13/ky_hb13.yaml rename to policyengine_us/tests/policy/contrib/states/ky/hb13/ky_hb13.yaml index 434de5a3ea3..8c5b544db1b 100644 --- a/policyengine_us/tests/policy/reforms/states/ky/hb13/ky_hb13.yaml +++ b/policyengine_us/tests/policy/contrib/states/ky/hb13/ky_hb13.yaml @@ -296,3 +296,120 @@ ky_income_tax_before_non_refundable_credits_joint: - 10550 - 0 + +- name: KY HB 13 - joint filing at exactly $300k cliff (still graduated) + period: 2027 + absolute_error_margin: 0.01 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb13.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_joint: 300_000 + person2: + age: 43 + ky_taxable_income_joint: 0 + tax_units: + tax_unit: + members: [person1, person2] + filing_status: JOINT + households: + household: + members: [person1, person2] + state_code: KY + output: + # At $300k exactly, strict > means graduated rates apply + # 250000*0.035 + 50000*0.06 = 8750 + 3000 = 11750 + ky_income_tax_before_non_refundable_credits_joint: + - 11750 + - 0 + +- name: KY HB 13 - joint filing $1 above cliff (flat 6% on entire income) + period: 2027 + absolute_error_margin: 0.01 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb13.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_joint: 300_001 + person2: + age: 43 + ky_taxable_income_joint: 0 + tax_units: + tax_unit: + members: [person1, person2] + filing_status: JOINT + households: + household: + members: [person1, person2] + state_code: KY + output: + # CLIFF: 300001 * 0.06 = 18000.06 + ky_income_tax_before_non_refundable_credits_joint: + - 18000.06 + - 0 + +- name: KY HB 13 - end-to-end high earner through ky_income_tax + period: 2027 + absolute_error_margin: 1 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb13.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 500_000 + ky_taxable_income_joint: 500_000 + person2: + age: 43 + ky_taxable_income_indiv: 0 + ky_taxable_income_joint: 0 + tax_units: + tax_unit: + members: [person1, person2] + filing_status: JOINT + adjusted_gross_income: 500_000 + households: + household: + members: [person1, person2] + state_code: KY + output: + # CLIFF: 500000 * 0.06 = 30000 + ky_income_tax_before_non_refundable_credits_joint: + - 30000 + - 0 + # High earner: family size credit rate is 0%, so no credit reduction + # Verify reform flows through to final ky_income_tax + ky_income_tax: 30000 + +- name: KY HB 13 - filing optimization chooses separate filing + period: 2027 + absolute_error_margin: 0.01 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb13.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 280_000 + ky_taxable_income_joint: 300_000 + person2: + age: 43 + ky_taxable_income_indiv: 20_000 + ky_taxable_income_joint: 0 + tax_units: + tax_unit: + members: [person1, person2] + filing_status: JOINT + households: + household: + members: [person1, person2] + state_code: KY + output: + # Separate: p1=250k*3.5%+30k*6%=10550, p2=20k*3.5%=700, total=11250 + # Joint: p1=250k*3.5%+50k*6%=11750, p2=0, total=11750 + # ky_files_separately = (11250 < 11750) = True + ky_files_separately: true diff --git a/policyengine_us/tests/policy/reforms/states/ky/hb152/ky_hb152.yaml b/policyengine_us/tests/policy/contrib/states/ky/hb152/ky_hb152.yaml similarity index 73% rename from policyengine_us/tests/policy/reforms/states/ky/hb152/ky_hb152.yaml rename to policyengine_us/tests/policy/contrib/states/ky/hb152/ky_hb152.yaml index 25ca8634f21..7fb8909709a 100644 --- a/policyengine_us/tests/policy/reforms/states/ky/hb152/ky_hb152.yaml +++ b/policyengine_us/tests/policy/contrib/states/ky/hb152/ky_hb152.yaml @@ -317,3 +317,113 @@ ky_income_tax_before_non_refundable_credits_joint: - 6150 - 0 + +- name: KY HB 152 - joint filing $1 below cliff (graduated) + period: 2027 + absolute_error_margin: 0.01 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb152.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_joint: 149_999 + person2: + age: 43 + ky_taxable_income_joint: 0 + tax_units: + tax_unit: + members: [person1, person2] + filing_status: JOINT + households: + household: + members: [person1, person2] + state_code: KY + output: + # Just below cliff: 100000*0.04 + 25000*0.05 + 24999*0.06 = 4000+1250+1499.94 = 6749.94 + ky_income_tax_before_non_refundable_credits_joint: + - 6749.94 + - 0 + +- name: KY HB 152 - joint filing at exactly $150k cliff (flat 6%) + period: 2027 + absolute_error_margin: 0.01 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb152.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_joint: 150_000 + person2: + age: 43 + ky_taxable_income_joint: 0 + tax_units: + tax_unit: + members: [person1, person2] + filing_status: JOINT + households: + household: + members: [person1, person2] + state_code: KY + output: + # Bill says "$150,000 or more" triggers flat rate: 150000 * 0.06 = 9000 + ky_income_tax_before_non_refundable_credits_joint: + - 9000 + - 0 + +- name: KY HB 152 - end-to-end high earner through ky_income_tax + period: 2027 + absolute_error_margin: 1 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb152.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 300_000 + ky_taxable_income_joint: 300_000 + person2: + age: 43 + ky_taxable_income_indiv: 0 + ky_taxable_income_joint: 0 + tax_units: + tax_unit: + members: [person1, person2] + filing_status: JOINT + adjusted_gross_income: 300_000 + households: + household: + members: [person1, person2] + state_code: KY + output: + # CLIFF: 300000 * 0.06 = 18000 + ky_income_tax_before_non_refundable_credits_joint: + - 18000 + - 0 + # High earner: family size credit rate is 0%, so no credit reduction + # Verify reform flows through to final ky_income_tax + ky_income_tax: 18000 + +- name: KY HB 152 - both reforms active (HB 13 takes precedence) + period: 2027 + absolute_error_margin: 0.01 + reforms: policyengine_us.reforms.states.ky.graduated_income_tax.ky_graduated_income_tax_reform.ky_graduated_income_tax + input: + gov.contrib.states.ky.hb13.in_effect: true + gov.contrib.states.ky.hb152.in_effect: true + people: + person1: + age: 45 + ky_taxable_income_indiv: 200_000 + tax_units: + tax_unit: + members: [person1] + filing_status: SINGLE + households: + household: + members: [person1] + state_code: KY + output: + # HB 13 takes precedence: 200000 * 0.035 = 7000 + ky_income_tax_before_non_refundable_credits_indiv: 7000