From aa6154d5e8483519c35a6e64f937361a88493e13 Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Thu, 14 May 2026 15:09:01 -0400 Subject: [PATCH 1/7] Add Kentucky homestead property tax exemption --- changelog.d/8196.added.md | 1 + .../household/state_property_tax_credits.yaml | 20 ++++++ .../homestead_exemption/age_threshold.yaml | 10 +++ .../property/homestead_exemption/amount.yaml | 10 +++ .../ky_homestead_exemption.yaml | 33 +++++++++ .../ky_homestead_exemption_eligible.yaml | 67 +++++++++++++++++++ .../ky_homestead_property_tax_reduction.yaml | 53 +++++++++++++++ .../ky_homestead_exemption.py | 17 +++++ .../ky_homestead_exemption_eligible.py | 23 +++++++ .../ky_homestead_property_tax_reduction.py | 17 +++++ 10 files changed, 251 insertions(+) create mode 100644 changelog.d/8196.added.md create mode 100644 policyengine_us/parameters/gov/states/ky/tax/property/homestead_exemption/age_threshold.yaml create mode 100644 policyengine_us/parameters/gov/states/ky/tax/property/homestead_exemption/amount.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_property_tax_reduction.yaml create mode 100644 policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption.py create mode 100644 policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption_eligible.py create mode 100644 policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_property_tax_reduction.py diff --git a/changelog.d/8196.added.md b/changelog.d/8196.added.md new file mode 100644 index 00000000000..10717afdd69 --- /dev/null +++ b/changelog.d/8196.added.md @@ -0,0 +1 @@ +Added the Kentucky Homestead Exemption property tax reduction. diff --git a/policyengine_us/parameters/gov/states/household/state_property_tax_credits.yaml b/policyengine_us/parameters/gov/states/household/state_property_tax_credits.yaml index b5c719c31cf..8d9ddbe960e 100644 --- a/policyengine_us/parameters/gov/states/household/state_property_tax_credits.yaml +++ b/policyengine_us/parameters/gov/states/household/state_property_tax_credits.yaml @@ -114,6 +114,26 @@ values: - wi_homestead_credit - wi_property_tax_credit - wv_homestead_excess_property_tax_credit + 2025-01-01: + - az_property_tax_credit + - ct_property_tax_credit + - dc_ptc + - il_property_tax_credit + - ky_homestead_property_tax_reduction + - ma_senior_circuit_breaker + - me_property_tax_fairness_credit + - mi_homestead_property_tax_credit + - mo_property_tax_credit + - mt_elderly_homeowner_or_renter_credit + - mt_property_tax_rebate + - nj_property_tax_credit + - nm_property_tax_rebate + - ny_real_property_tax_credit + - ok_ptc + - ri_property_tax_credit + - wi_homestead_credit + - wi_property_tax_credit + - wv_homestead_excess_property_tax_credit metadata: unit: list diff --git a/policyengine_us/parameters/gov/states/ky/tax/property/homestead_exemption/age_threshold.yaml b/policyengine_us/parameters/gov/states/ky/tax/property/homestead_exemption/age_threshold.yaml new file mode 100644 index 00000000000..8af7896905c --- /dev/null +++ b/policyengine_us/parameters/gov/states/ky/tax/property/homestead_exemption/age_threshold.yaml @@ -0,0 +1,10 @@ +description: Kentucky limits age-based eligibility to filers at or above this age under the Homestead Exemption program. +values: + 2025-01-01: 65 +metadata: + unit: year + period: year + label: Kentucky homestead exemption age threshold + reference: + - title: Kentucky Department of Revenue | Homestead Exemption + href: https://revenue.ky.gov/Property/Residential-Farm-Commercial-Property/pages/homestead-exemption.aspx diff --git a/policyengine_us/parameters/gov/states/ky/tax/property/homestead_exemption/amount.yaml b/policyengine_us/parameters/gov/states/ky/tax/property/homestead_exemption/amount.yaml new file mode 100644 index 00000000000..7584fc186f8 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ky/tax/property/homestead_exemption/amount.yaml @@ -0,0 +1,10 @@ +description: Kentucky provides this amount as a homestead exemption under the Homestead Exemption program. +values: + 2025-01-01: 49_100 +metadata: + unit: currency-USD + period: year + label: Kentucky homestead exemption amount + reference: + - title: Kentucky Department of Revenue | Homestead Exemption + href: https://revenue.ky.gov/Property/Residential-Farm-Commercial-Property/pages/homestead-exemption.aspx diff --git a/policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption.yaml b/policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption.yaml new file mode 100644 index 00000000000..bd74fbaf809 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption.yaml @@ -0,0 +1,33 @@ +- name: Case 1, exemption is capped at the statutory amount. + period: 2025 + input: + people: + person1: + age: 65 + assessed_property_value: 200_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: KY + output: + ky_homestead_exemption: 49_100 + +- name: Case 2, exemption is limited to assessed property value. + period: 2025 + input: + people: + person1: + age: 65 + assessed_property_value: 40_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: KY + output: + ky_homestead_exemption: 40_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption_eligible.yaml new file mode 100644 index 00000000000..8b54b829b65 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption_eligible.yaml @@ -0,0 +1,67 @@ +- name: Case 1, senior homeowner is eligible. + period: 2025 + input: + people: + person1: + age: 65 + assessed_property_value: 200_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: KY + output: + ky_homestead_exemption_eligible: true + +- name: Case 2, disabled homeowner under age 65 is eligible. + period: 2025 + input: + people: + person1: + age: 40 + is_disabled: true + assessed_property_value: 200_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: KY + output: + ky_homestead_exemption_eligible: true + +- name: Case 3, non-senior homeowner without disability is ineligible. + period: 2025 + input: + people: + person1: + age: 64 + assessed_property_value: 200_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: KY + output: + ky_homestead_exemption_eligible: false + +- name: Case 4, senior without assessed property is ineligible. + period: 2025 + input: + people: + person1: + age: 65 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: KY + output: + ky_homestead_exemption_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_property_tax_reduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_property_tax_reduction.yaml new file mode 100644 index 00000000000..78b0e5b884a --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_property_tax_reduction.yaml @@ -0,0 +1,53 @@ +- name: Case 1, reduction equals the property tax on the exempt share of value. + period: 2025 + input: + people: + person1: + age: 65 + assessed_property_value: 200_000 + real_estate_taxes: 2_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: KY + output: + ky_homestead_property_tax_reduction: 491 + +- name: Case 2, reduction cannot exceed property taxes. + period: 2025 + input: + people: + person1: + age: 65 + assessed_property_value: 40_000 + real_estate_taxes: 800 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: KY + output: + ky_homestead_property_tax_reduction: 800 + +- name: Case 3, ineligible filer gets no reduction. + period: 2025 + input: + people: + person1: + age: 64 + assessed_property_value: 200_000 + real_estate_taxes: 2_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: KY + output: + ky_homestead_property_tax_reduction: 0 diff --git a/policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption.py b/policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption.py new file mode 100644 index 00000000000..eef76af862f --- /dev/null +++ b/policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption.py @@ -0,0 +1,17 @@ +from policyengine_us.model_api import * + + +class ky_homestead_exemption(Variable): + value_type = float + entity = TaxUnit + label = "Kentucky homestead exemption" + unit = USD + definition_period = YEAR + reference = "https://revenue.ky.gov/Property/Residential-Farm-Commercial-Property/pages/homestead-exemption.aspx" + defined_for = "ky_homestead_exemption_eligible" + + def formula(tax_unit, period, parameters): + return min_( + add(tax_unit, period, ["assessed_property_value"]), + parameters(period).gov.states.ky.tax.property.homestead_exemption.amount, + ) diff --git a/policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption_eligible.py b/policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption_eligible.py new file mode 100644 index 00000000000..b0abd6eebd2 --- /dev/null +++ b/policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption_eligible.py @@ -0,0 +1,23 @@ +from policyengine_us.model_api import * + + +class ky_homestead_exemption_eligible(Variable): + value_type = bool + entity = TaxUnit + label = "Eligible for the Kentucky Homestead Exemption" + definition_period = YEAR + reference = "https://revenue.ky.gov/Property/Residential-Farm-Commercial-Property/pages/homestead-exemption.aspx" + defined_for = StateCode.KY + + def formula(tax_unit, period, parameters): + p = parameters(period).gov.states.ky.tax.property.homestead_exemption + person = tax_unit.members + head_or_spouse = person("is_tax_unit_head_or_spouse", period) + age = person("age", period.this_year) + is_disabled = person("is_disabled", period) + owns_assessed_property = add(tax_unit, period, ["assessed_property_value"]) > 0 + + return ( + tax_unit.any(((age >= p.age_threshold) | is_disabled) & head_or_spouse) + & owns_assessed_property + ) diff --git a/policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_property_tax_reduction.py b/policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_property_tax_reduction.py new file mode 100644 index 00000000000..8393c24f0af --- /dev/null +++ b/policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_property_tax_reduction.py @@ -0,0 +1,17 @@ +from policyengine_us.model_api import * + + +class ky_homestead_property_tax_reduction(Variable): + value_type = float + entity = TaxUnit + label = "Kentucky homestead property tax reduction" + unit = USD + definition_period = YEAR + reference = "https://revenue.ky.gov/Property/Residential-Farm-Commercial-Property/pages/homestead-exemption.aspx" + defined_for = "ky_homestead_exemption_eligible" + + def formula(tax_unit, period, parameters): + assessed_value = add(tax_unit, period, ["assessed_property_value"]) + return add(tax_unit, period, ["real_estate_taxes"]) * ( + tax_unit("ky_homestead_exemption", period) / max_(assessed_value, 1) + ) From 81dbff9afbcc36c41c32e44c8aba6d3aedd09137 Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Thu, 14 May 2026 16:53:52 -0400 Subject: [PATCH 2/7] Rename changelog fragment for PR 8309 --- changelog.d/{8196.added.md => 8309.added.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelog.d/{8196.added.md => 8309.added.md} (100%) diff --git a/changelog.d/8196.added.md b/changelog.d/8309.added.md similarity index 100% rename from changelog.d/8196.added.md rename to changelog.d/8309.added.md From 30b1c179f91c481b50f14dad26d15beaa71d9547 Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Mon, 18 May 2026 16:46:25 -0400 Subject: [PATCH 3/7] Wire ky_homestead_property_tax_reduction into net income Add ky_homestead_property_tax_reduction to a new gov.states.ky.tax.income.credits.refundable list and wire ky_refundable_credits to it. The reduction now flows through household_refundable_state_tax_credits to household_net_income. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../gov/states/ky/tax/income/credits/refundable.yaml | 12 ++++++++++++ .../ky/tax/income/credits/ky_refundable_credits.py | 1 + 2 files changed, 13 insertions(+) create mode 100644 policyengine_us/parameters/gov/states/ky/tax/income/credits/refundable.yaml diff --git a/policyengine_us/parameters/gov/states/ky/tax/income/credits/refundable.yaml b/policyengine_us/parameters/gov/states/ky/tax/income/credits/refundable.yaml new file mode 100644 index 00000000000..c299ff5ada4 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ky/tax/income/credits/refundable.yaml @@ -0,0 +1,12 @@ +description: Kentucky provides these refundable income tax credits. +values: + 2025-01-01: + - ky_homestead_property_tax_reduction + +metadata: + unit: list + period: year + label: Kentucky refundable credits + reference: + - title: Kentucky Department of Revenue | Homestead Exemption + href: https://revenue.ky.gov/Property/Residential-Farm-Commercial-Property/pages/homestead-exemption.aspx diff --git a/policyengine_us/variables/gov/states/ky/tax/income/credits/ky_refundable_credits.py b/policyengine_us/variables/gov/states/ky/tax/income/credits/ky_refundable_credits.py index 67e2bd31fe4..2e5635f5aa7 100644 --- a/policyengine_us/variables/gov/states/ky/tax/income/credits/ky_refundable_credits.py +++ b/policyengine_us/variables/gov/states/ky/tax/income/credits/ky_refundable_credits.py @@ -8,3 +8,4 @@ class ky_refundable_credits(Variable): unit = USD definition_period = YEAR defined_for = StateCode.KY + adds = "gov.states.ky.tax.income.credits.refundable" From bd836db13d36a7943fb1c28c2305d68220e39bc8 Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Thu, 21 May 2026 16:11:02 -0400 Subject: [PATCH 4/7] Keep property tax relief household-only --- .../household/state_property_tax_credits.yaml | 153 +++--------------- .../ky/tax/income/credits/refundable.yaml | 12 -- .../income/credits/ky_refundable_credits.py | 1 - 3 files changed, 19 insertions(+), 147 deletions(-) delete mode 100644 policyengine_us/parameters/gov/states/ky/tax/income/credits/refundable.yaml diff --git a/policyengine_us/parameters/gov/states/household/state_property_tax_credits.yaml b/policyengine_us/parameters/gov/states/household/state_property_tax_credits.yaml index 8d9ddbe960e..6a9b8dfc6a4 100644 --- a/policyengine_us/parameters/gov/states/household/state_property_tax_credits.yaml +++ b/policyengine_us/parameters/gov/states/household/state_property_tax_credits.yaml @@ -1,139 +1,24 @@ description: All state property tax credits and circuit breaker programs. values: - # Year-gated: each credit appears from the year its - # parameters are first defined in PE-US. - 1977-01-01: - - ri_property_tax_credit - 1996-01-01: - - nj_property_tax_credit - - ri_property_tax_credit - 1997-01-01: - - mo_property_tax_credit - - nj_property_tax_credit - - ri_property_tax_credit - 2000-01-01: - - mo_property_tax_credit - - nj_property_tax_credit - - ny_real_property_tax_credit - - ri_property_tax_credit - - wi_property_tax_credit - 2001-01-01: - - ma_senior_circuit_breaker - - mo_property_tax_credit - - nj_property_tax_credit - - ny_real_property_tax_credit - - ri_property_tax_credit - - wi_property_tax_credit - 2008-01-01: - - ma_senior_circuit_breaker - - mo_property_tax_credit - - nj_property_tax_credit - - ny_real_property_tax_credit - - ri_property_tax_credit - - wi_property_tax_credit - - wv_homestead_excess_property_tax_credit - 2009-01-01: - - ma_senior_circuit_breaker - - mo_property_tax_credit - - mt_elderly_homeowner_or_renter_credit - - nj_property_tax_credit - - ny_real_property_tax_credit - - ri_property_tax_credit - - wi_property_tax_credit - - wv_homestead_excess_property_tax_credit - 2011-01-01: - - ct_property_tax_credit - - ma_senior_circuit_breaker - - mo_property_tax_credit - - mt_elderly_homeowner_or_renter_credit - - nj_property_tax_credit - - ny_real_property_tax_credit - - ri_property_tax_credit - - wi_homestead_credit - - wi_property_tax_credit - - wv_homestead_excess_property_tax_credit - 2014-01-01: - - ct_property_tax_credit - - ma_senior_circuit_breaker - - me_property_tax_fairness_credit - - mo_property_tax_credit - - mt_elderly_homeowner_or_renter_credit - - nj_property_tax_credit - - ny_real_property_tax_credit - - ri_property_tax_credit - - wi_homestead_credit - - wi_property_tax_credit - - wv_homestead_excess_property_tax_credit - 2016-01-01: - - ct_property_tax_credit - - ma_senior_circuit_breaker - - me_property_tax_fairness_credit - - mi_homestead_property_tax_credit - - mo_property_tax_credit - - mt_elderly_homeowner_or_renter_credit - - nj_property_tax_credit - - ny_real_property_tax_credit - - ri_property_tax_credit - - wi_homestead_credit - - wi_property_tax_credit - - wv_homestead_excess_property_tax_credit - 2021-01-01: - - az_property_tax_credit - - ct_property_tax_credit - - dc_ptc - - il_property_tax_credit - - ma_senior_circuit_breaker - - me_property_tax_fairness_credit - - mi_homestead_property_tax_credit - - mo_property_tax_credit - - mt_elderly_homeowner_or_renter_credit - - nj_property_tax_credit - - nm_property_tax_rebate - - ny_real_property_tax_credit - - ok_ptc - - ri_property_tax_credit - - wi_homestead_credit - - wi_property_tax_credit - - wv_homestead_excess_property_tax_credit - 2022-01-01: - - az_property_tax_credit - - ct_property_tax_credit - - dc_ptc - - il_property_tax_credit - - ma_senior_circuit_breaker - - me_property_tax_fairness_credit - - mi_homestead_property_tax_credit - - mo_property_tax_credit - - mt_elderly_homeowner_or_renter_credit - - mt_property_tax_rebate - - nj_property_tax_credit - - nm_property_tax_rebate - - ny_real_property_tax_credit - - ok_ptc - - ri_property_tax_credit - - wi_homestead_credit - - wi_property_tax_credit - - wv_homestead_excess_property_tax_credit - 2025-01-01: - - az_property_tax_credit - - ct_property_tax_credit - - dc_ptc - - il_property_tax_credit - - ky_homestead_property_tax_reduction - - ma_senior_circuit_breaker - - me_property_tax_fairness_credit - - mi_homestead_property_tax_credit - - mo_property_tax_credit - - mt_elderly_homeowner_or_renter_credit - - mt_property_tax_rebate - - nj_property_tax_credit - - nm_property_tax_rebate - - ny_real_property_tax_credit - - ok_ptc - - ri_property_tax_credit - - wi_homestead_credit - - wi_property_tax_credit - - wv_homestead_excess_property_tax_credit + 0000-01-01: + - az_property_tax_credit # Arizona Property Tax Credit + - ct_property_tax_credit # Connecticut Property Tax Credit + # Exclude ca_renter_credit as it is for renters, not homeowners. + - dc_ptc # DC Property Tax Credit + # Exclude hi_tax_credit_for_low_income_household_renters as it is for renters, not homeowners. + - ma_senior_circuit_breaker # Massachusetts Senior Circuit Breaker Credit + - me_property_tax_fairness_credit # Maine Property Tax Fairness Credit + - mi_homestead_property_tax_credit # Michigan homestead property tax credit + - mo_property_tax_credit # Missouri property tax credit + - mt_elderly_homeowner_or_renter_credit # Montana Elderly Homeowner/Renter Credit + - nj_property_tax_credit # New Jersey property tax credit + - nm_property_tax_rebate # New Mexico property tax rebate + - ny_real_property_tax_credit # New York real property tax credit + - ri_property_tax_credit # Rhode Island property tax credit + # Omit vt_renter_credit + - wi_homestead_credit # Wisconsin homestead credit + - wi_property_tax_credit # Wisconsin property tax credit + - wv_homestead_excess_property_tax_credit # West Virginia metadata: unit: list diff --git a/policyengine_us/parameters/gov/states/ky/tax/income/credits/refundable.yaml b/policyengine_us/parameters/gov/states/ky/tax/income/credits/refundable.yaml deleted file mode 100644 index c299ff5ada4..00000000000 --- a/policyengine_us/parameters/gov/states/ky/tax/income/credits/refundable.yaml +++ /dev/null @@ -1,12 +0,0 @@ -description: Kentucky provides these refundable income tax credits. -values: - 2025-01-01: - - ky_homestead_property_tax_reduction - -metadata: - unit: list - period: year - label: Kentucky refundable credits - reference: - - title: Kentucky Department of Revenue | Homestead Exemption - href: https://revenue.ky.gov/Property/Residential-Farm-Commercial-Property/pages/homestead-exemption.aspx diff --git a/policyengine_us/variables/gov/states/ky/tax/income/credits/ky_refundable_credits.py b/policyengine_us/variables/gov/states/ky/tax/income/credits/ky_refundable_credits.py index 2e5635f5aa7..67e2bd31fe4 100644 --- a/policyengine_us/variables/gov/states/ky/tax/income/credits/ky_refundable_credits.py +++ b/policyengine_us/variables/gov/states/ky/tax/income/credits/ky_refundable_credits.py @@ -8,4 +8,3 @@ class ky_refundable_credits(Variable): unit = USD definition_period = YEAR defined_for = StateCode.KY - adds = "gov.states.ky.tax.income.credits.refundable" From 2cc0656cda24ff751951b8d81e574866cff0c6e7 Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Thu, 21 May 2026 16:13:40 -0400 Subject: [PATCH 5/7] Restore property tax aggregate base --- .../household/state_property_tax_credits.yaml | 178 ++++++++++++++++-- 1 file changed, 159 insertions(+), 19 deletions(-) diff --git a/policyengine_us/parameters/gov/states/household/state_property_tax_credits.yaml b/policyengine_us/parameters/gov/states/household/state_property_tax_credits.yaml index 6a9b8dfc6a4..5fc7a8116bf 100644 --- a/policyengine_us/parameters/gov/states/household/state_property_tax_credits.yaml +++ b/policyengine_us/parameters/gov/states/household/state_property_tax_credits.yaml @@ -1,24 +1,164 @@ description: All state property tax credits and circuit breaker programs. values: - 0000-01-01: - - az_property_tax_credit # Arizona Property Tax Credit - - ct_property_tax_credit # Connecticut Property Tax Credit - # Exclude ca_renter_credit as it is for renters, not homeowners. - - dc_ptc # DC Property Tax Credit - # Exclude hi_tax_credit_for_low_income_household_renters as it is for renters, not homeowners. - - ma_senior_circuit_breaker # Massachusetts Senior Circuit Breaker Credit - - me_property_tax_fairness_credit # Maine Property Tax Fairness Credit - - mi_homestead_property_tax_credit # Michigan homestead property tax credit - - mo_property_tax_credit # Missouri property tax credit - - mt_elderly_homeowner_or_renter_credit # Montana Elderly Homeowner/Renter Credit - - nj_property_tax_credit # New Jersey property tax credit - - nm_property_tax_rebate # New Mexico property tax rebate - - ny_real_property_tax_credit # New York real property tax credit - - ri_property_tax_credit # Rhode Island property tax credit - # Omit vt_renter_credit - - wi_homestead_credit # Wisconsin homestead credit - - wi_property_tax_credit # Wisconsin property tax credit - - wv_homestead_excess_property_tax_credit # West Virginia + # Year-gated: each credit appears from the year its + # parameters are first defined in PE-US. + 1977-01-01: + - ri_property_tax_credit + 1996-01-01: + - nj_property_tax_credit + - ri_property_tax_credit + 1997-01-01: + - mo_property_tax_credit + - nj_property_tax_credit + - ri_property_tax_credit + 2000-01-01: + - mo_property_tax_credit + - nj_property_tax_credit + - ny_real_property_tax_credit + - ri_property_tax_credit + - wi_property_tax_credit + 2001-01-01: + - ma_senior_circuit_breaker + - mo_property_tax_credit + - nj_property_tax_credit + - ny_real_property_tax_credit + - ri_property_tax_credit + - wi_property_tax_credit + 2008-01-01: + - ma_senior_circuit_breaker + - mo_property_tax_credit + - nj_property_tax_credit + - ny_real_property_tax_credit + - ri_property_tax_credit + - wi_property_tax_credit + - wv_homestead_excess_property_tax_credit + 2009-01-01: + - ma_senior_circuit_breaker + - mo_property_tax_credit + - mt_elderly_homeowner_or_renter_credit + - nj_property_tax_credit + - ny_real_property_tax_credit + - ri_property_tax_credit + - wi_property_tax_credit + - wv_homestead_excess_property_tax_credit + 2011-01-01: + - ct_property_tax_credit + - ma_senior_circuit_breaker + - mo_property_tax_credit + - mt_elderly_homeowner_or_renter_credit + - nj_property_tax_credit + - ny_real_property_tax_credit + - ri_property_tax_credit + - wi_homestead_credit + - wi_property_tax_credit + - wv_homestead_excess_property_tax_credit + 2014-01-01: + - ct_property_tax_credit + - ma_senior_circuit_breaker + - me_property_tax_fairness_credit + - mo_property_tax_credit + - mt_elderly_homeowner_or_renter_credit + - nj_property_tax_credit + - ny_real_property_tax_credit + - ri_property_tax_credit + - wi_homestead_credit + - wi_property_tax_credit + - wv_homestead_excess_property_tax_credit + 2016-01-01: + - ct_property_tax_credit + - ma_senior_circuit_breaker + - me_property_tax_fairness_credit + - mi_homestead_property_tax_credit + - mo_property_tax_credit + - mt_elderly_homeowner_or_renter_credit + - nj_property_tax_credit + - ny_real_property_tax_credit + - ri_property_tax_credit + - wi_homestead_credit + - wi_property_tax_credit + - wv_homestead_excess_property_tax_credit + 2021-01-01: + - az_property_tax_credit + - ct_property_tax_credit + - dc_ptc + - il_property_tax_credit + - ma_senior_circuit_breaker + - me_property_tax_fairness_credit + - mi_homestead_property_tax_credit + - mo_property_tax_credit + - mt_elderly_homeowner_or_renter_credit + - nj_property_tax_credit + - nm_property_tax_rebate + - ny_real_property_tax_credit + - ok_ptc + - ri_property_tax_credit + - wi_homestead_credit + - wi_property_tax_credit + - wv_homestead_excess_property_tax_credit + 2022-01-01: + - az_property_tax_credit + - ct_property_tax_credit + - dc_ptc + - il_property_tax_credit + - ma_senior_circuit_breaker + - me_property_tax_fairness_credit + - mi_homestead_property_tax_credit + - mo_property_tax_credit + - mt_elderly_homeowner_or_renter_credit + - mt_property_tax_rebate + - nj_property_tax_credit + - nm_property_tax_rebate + - ny_real_property_tax_credit + - ok_ptc + - ri_property_tax_credit + - wi_homestead_credit + - wi_property_tax_credit + - wv_homestead_excess_property_tax_credit + 2024-01-01: + - az_property_tax_credit + - ct_property_tax_credit + - dc_ptc + - il_property_tax_credit + - ma_senior_circuit_breaker + - me_property_tax_fairness_credit + - mi_homestead_property_tax_credit + - mn_renters_credit + - mo_property_tax_credit + - mt_elderly_homeowner_or_renter_credit + - mt_property_tax_rebate + - nd_renters_refund + - nj_property_tax_credit + - nm_property_tax_rebate + - ny_real_property_tax_credit + - ok_ptc + - ri_property_tax_credit + - wi_homestead_credit + - wi_property_tax_credit + - wv_homestead_excess_property_tax_credit + 2025-01-01: + - az_property_tax_credit + - ct_property_tax_credit + - dc_ptc + - dc_senior_disabled_property_tax_relief + - il_property_tax_credit + - ma_senior_circuit_breaker + - me_property_tax_fairness_credit + - mi_homestead_property_tax_credit + - mn_renters_credit + - mo_property_tax_credit + - mt_elderly_homeowner_or_renter_credit + - mt_property_tax_rebate + - nd_renters_refund + - nj_property_tax_credit + - nm_property_tax_rebate + - ny_real_property_tax_credit + - ok_ptc + - pa_property_tax_or_rent_rebate + - ri_property_tax_credit + - ut_homeowner_renter_relief + - wi_homestead_credit + - wi_property_tax_credit + - wv_homestead_excess_property_tax_credit metadata: unit: list From 1cc08e60f71aac7ef38a867e7d9336f91090e05c Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Thu, 21 May 2026 16:17:30 -0400 Subject: [PATCH 6/7] Drop property tax aggregate diff --- .../household/state_property_tax_credits.yaml | 45 ------------------- 1 file changed, 45 deletions(-) diff --git a/policyengine_us/parameters/gov/states/household/state_property_tax_credits.yaml b/policyengine_us/parameters/gov/states/household/state_property_tax_credits.yaml index 5fc7a8116bf..b5c719c31cf 100644 --- a/policyengine_us/parameters/gov/states/household/state_property_tax_credits.yaml +++ b/policyengine_us/parameters/gov/states/household/state_property_tax_credits.yaml @@ -114,51 +114,6 @@ values: - wi_homestead_credit - wi_property_tax_credit - wv_homestead_excess_property_tax_credit - 2024-01-01: - - az_property_tax_credit - - ct_property_tax_credit - - dc_ptc - - il_property_tax_credit - - ma_senior_circuit_breaker - - me_property_tax_fairness_credit - - mi_homestead_property_tax_credit - - mn_renters_credit - - mo_property_tax_credit - - mt_elderly_homeowner_or_renter_credit - - mt_property_tax_rebate - - nd_renters_refund - - nj_property_tax_credit - - nm_property_tax_rebate - - ny_real_property_tax_credit - - ok_ptc - - ri_property_tax_credit - - wi_homestead_credit - - wi_property_tax_credit - - wv_homestead_excess_property_tax_credit - 2025-01-01: - - az_property_tax_credit - - ct_property_tax_credit - - dc_ptc - - dc_senior_disabled_property_tax_relief - - il_property_tax_credit - - ma_senior_circuit_breaker - - me_property_tax_fairness_credit - - mi_homestead_property_tax_credit - - mn_renters_credit - - mo_property_tax_credit - - mt_elderly_homeowner_or_renter_credit - - mt_property_tax_rebate - - nd_renters_refund - - nj_property_tax_credit - - nm_property_tax_rebate - - ny_real_property_tax_credit - - ok_ptc - - pa_property_tax_or_rent_rebate - - ri_property_tax_credit - - ut_homeowner_renter_relief - - wi_homestead_credit - - wi_property_tax_credit - - wv_homestead_excess_property_tax_credit metadata: unit: list From 45698643eeba083ad5d7804a42fb0512e942fba0 Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Tue, 2 Jun 2026 12:52:59 -0400 Subject: [PATCH 7/7] Fix Kentucky homestead exemption review issues --- .../property/homestead_exemption/amount.yaml | 30 +++++++++++++ .../ky_homestead_exemption.yaml | 44 +++++++++++++++++++ .../ky_homestead_exemption_eligible.yaml | 25 +++++++++++ .../ky_homestead_property_tax_reduction.yaml | 28 ++++++++++++ .../ky_homestead_exemption.py | 16 ++++++- .../ky_homestead_exemption_eligible.py | 11 +++-- .../ky_homestead_property_tax_reduction.py | 24 ++++++++-- 7 files changed, 169 insertions(+), 9 deletions(-) diff --git a/policyengine_us/parameters/gov/states/ky/tax/property/homestead_exemption/amount.yaml b/policyengine_us/parameters/gov/states/ky/tax/property/homestead_exemption/amount.yaml index 7584fc186f8..38b608fa670 100644 --- a/policyengine_us/parameters/gov/states/ky/tax/property/homestead_exemption/amount.yaml +++ b/policyengine_us/parameters/gov/states/ky/tax/property/homestead_exemption/amount.yaml @@ -1,5 +1,31 @@ description: Kentucky provides this amount as a homestead exemption under the Homestead Exemption program. values: + 1972-01-01: 6_500 + 1975-01-01: 7_700 + 1977-01-01: 8_900 + 1979-01-01: 10_200 + 1981-01-01: 12_900 + 1983-01-01: 15_000 + 1985-01-01: 16_100 + 1987-01-01: 17_100 + 1989-01-01: 18_400 + 1991-01-01: 20_300 + 1993-01-01: 21_800 + 1995-01-01: 23_100 + 1997-01-01: 24_400 + 1999-01-01: 25_400 + 2001-01-01: 26_800 + 2003-01-01: 28_000 + 2005-01-01: 29_400 + 2007-01-01: 31_400 + 2009-01-01: 33_700 + 2011-01-01: 34_000 + 2013-01-01: 36_000 + 2015-01-01: 36_900 + 2017-01-01: 37_600 + 2019-01-01: 39_300 + 2021-01-01: 40_500 + 2023-01-01: 46_350 2025-01-01: 49_100 metadata: unit: currency-USD @@ -8,3 +34,7 @@ metadata: reference: - title: Kentucky Department of Revenue | Homestead Exemption href: https://revenue.ky.gov/Property/Residential-Farm-Commercial-Property/pages/homestead-exemption.aspx + - title: Kentucky Department of Revenue | Homestead Exemption Historical Data + href: https://revenue.ky.gov/Property/Residential-Farm-Commercial-Property/Pages/HomesteadExemptionHistoricalData.aspx + - title: Kentucky Department of Revenue | DOR Sets 2025-2026 Homestead Exemption + href: https://revenue.ky.gov/News/Pages/DOR-Sets-2025-2026-Homestead-Exemption.aspx diff --git a/policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption.yaml b/policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption.yaml index bd74fbaf809..c9930f9778d 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption.yaml @@ -31,3 +31,47 @@ state_code: KY output: ky_homestead_exemption: 40_000 + +- name: Case 3, historical exemption amount applies in 2024. + absolute_error_margin: 0.01 + period: 2024 + input: + people: + person1: + age: 65 + assessed_property_value: 200_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: KY + output: + ky_homestead_exemption: 46_350 + +- name: Case 4, exemption only uses qualifying owner property. + absolute_error_margin: 0.01 + period: 2025 + input: + people: + person1: + age: 65 + is_tax_unit_head: true + is_tax_unit_spouse: false + assessed_property_value: 40_000 + person2: + age: 30 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + assessed_property_value: 100_000 + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: KY + output: + ky_homestead_exemption: 40_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption_eligible.yaml index 8b54b829b65..9692757cf40 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption_eligible.yaml @@ -65,3 +65,28 @@ state_code: KY output: ky_homestead_exemption_eligible: false + +- name: Case 5, senior head is ineligible when only a dependent owns property. + period: 2025 + input: + people: + person1: + age: 65 + is_tax_unit_head: true + is_tax_unit_spouse: false + assessed_property_value: 0 + person2: + age: 30 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + assessed_property_value: 200_000 + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: KY + output: + ky_homestead_exemption_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_property_tax_reduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_property_tax_reduction.yaml index 78b0e5b884a..aa15700fafa 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_property_tax_reduction.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ky/tax/property/homestead_exemption/ky_homestead_property_tax_reduction.yaml @@ -51,3 +51,31 @@ state_code: KY output: ky_homestead_property_tax_reduction: 0 + +- name: Case 4, reduction only uses qualifying owner property taxes. + absolute_error_margin: 0.01 + period: 2025 + input: + people: + person1: + age: 65 + is_tax_unit_head: true + is_tax_unit_spouse: false + assessed_property_value: 100_000 + real_estate_taxes: 2_000 + person2: + age: 30 + is_tax_unit_head: false + is_tax_unit_spouse: false + is_tax_unit_dependent: true + assessed_property_value: 200_000 + real_estate_taxes: 2_000 + tax_units: + tax_unit: + members: [person1, person2] + households: + household: + members: [person1, person2] + state_code: KY + output: + ky_homestead_property_tax_reduction: 982 diff --git a/policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption.py b/policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption.py index eef76af862f..368c504ba38 100644 --- a/policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption.py +++ b/policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption.py @@ -11,7 +11,19 @@ class ky_homestead_exemption(Variable): defined_for = "ky_homestead_exemption_eligible" def formula(tax_unit, period, parameters): + person = tax_unit.members + p = parameters(period).gov.states.ky.tax.property.homestead_exemption + head_or_spouse = person("is_tax_unit_head_or_spouse", period) + age = person("age", period.this_year) + is_disabled = person("is_disabled", period) + assessed_property_value = person("assessed_property_value", period) + qualifying_owner = ( + ((age >= p.age_threshold) | is_disabled) + & head_or_spouse + & (assessed_property_value > 0) + ) + return min_( - add(tax_unit, period, ["assessed_property_value"]), - parameters(period).gov.states.ky.tax.property.homestead_exemption.amount, + tax_unit.sum(where(qualifying_owner, assessed_property_value, 0)), + p.amount, ) diff --git a/policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption_eligible.py b/policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption_eligible.py index b0abd6eebd2..430ebbd37c5 100644 --- a/policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption_eligible.py +++ b/policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_exemption_eligible.py @@ -14,10 +14,13 @@ def formula(tax_unit, period, parameters): person = tax_unit.members head_or_spouse = person("is_tax_unit_head_or_spouse", period) age = person("age", period.this_year) + # Kentucky requires total disability and disability payments; this is the + # closest available person-level proxy. is_disabled = person("is_disabled", period) - owns_assessed_property = add(tax_unit, period, ["assessed_property_value"]) > 0 + assessed_property_value = person("assessed_property_value", period) - return ( - tax_unit.any(((age >= p.age_threshold) | is_disabled) & head_or_spouse) - & owns_assessed_property + return tax_unit.any( + ((age >= p.age_threshold) | is_disabled) + & head_or_spouse + & (assessed_property_value > 0) ) diff --git a/policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_property_tax_reduction.py b/policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_property_tax_reduction.py index 8393c24f0af..a9b3c992675 100644 --- a/policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_property_tax_reduction.py +++ b/policyengine_us/variables/gov/states/ky/tax/property/homestead_exemption/ky_homestead_property_tax_reduction.py @@ -11,7 +11,25 @@ class ky_homestead_property_tax_reduction(Variable): defined_for = "ky_homestead_exemption_eligible" def formula(tax_unit, period, parameters): - assessed_value = add(tax_unit, period, ["assessed_property_value"]) - return add(tax_unit, period, ["real_estate_taxes"]) * ( - tax_unit("ky_homestead_exemption", period) / max_(assessed_value, 1) + person = tax_unit.members + p = parameters(period).gov.states.ky.tax.property.homestead_exemption + head_or_spouse = person("is_tax_unit_head_or_spouse", period) + age = person("age", period.this_year) + is_disabled = person("is_disabled", period) + assessed_property_value = person("assessed_property_value", period) + qualifying_owner = ( + ((age >= p.age_threshold) | is_disabled) + & head_or_spouse + & (assessed_property_value > 0) + ) + qualifying_property_value = tax_unit.sum( + where(qualifying_owner, assessed_property_value, 0) + ) + qualifying_property_taxes = tax_unit.sum( + where(qualifying_owner, person("real_estate_taxes", period), 0) + ) + + return qualifying_property_taxes * ( + tax_unit("ky_homestead_exemption", period) + / max_(qualifying_property_value, 1) )