Skip to content

Follow the statute for the NYC school tax rate reduction, IN supplemental homestead, VA 529 and WA senior/disabled property tax exemption - #10330

Open
MaxGhenis wants to merge 7 commits into
mainfrom
statute-bugs-nyc-in-va-wa
Open

MaxGhenis wants to merge 7 commits into
mainfrom
statute-bugs-nyc-in-va-wa

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #8947

What and why

Four verified model bugs from the statute-first backlog (statute governs, forms fill gaps; ruled 2026-10-19). Each section gives the source, the change, a witness, and the years.

1. NYC school tax credit rate reduction amount: statutory second-band bases (us-nyc-school-tax-credit-rate-reduction-base, 2017+)

  • Source. N.Y. Tax Law § 606(ggg)(4-b)(A)-(C), enacted by L.2017, ch. 59, Part C, § 2 (S.2009-C, PDF pages 8-9); § 7 applies it to tax years beginning on and after January 1, 2017 (PDF page 14). "Over $14,400 but not over $500,000: $25 plus 0.228% of excess over $14,400." The IT-201-I line 69a tables give the same values (2025, PDF page 21).
  • Before. Five marginal-rate scales (0.171% below the threshold, 0.228% above), so the second band started from the first band carried forward: 36.936 joint and surviving spouse, 24.624 head of household, 20.52 single and separate.
  • Change. The scales become rate_reduction/amount/{threshold,base} (by filing status) and {first_band_rate,excess_rate}, from 2017-01-01. The formula is 0.171% x T for T not over the threshold, else base + 0.228% x (T - threshold). Income equal to the threshold stays in the first band. Eligibility and the $500,000 limits are unchanged.
  • Witness. Head of household, 2017, city taxable income $20,000: $25 + 0.228% x 5,600 = $37.768 (main: $37.392). Joint 2025, $30,000: $56.152 (main $56.088). Single 2025, $20,000: $39.24 (main $38.76).
  • Tests. The 2022 upper-branch cases lose their $1 tolerances; new 2017 and 2025 cases cover every filing status, both sides of each threshold, negative income and a mixed vector. income_tax_elimination/integration.yaml re-enables the nyc_school_tax_credit and nyc_income_tax assertions that were commented out because of this bug. The differential invariant test's tolerance drops from 0.5 to 0.001. Tests that had pinned the old carry-in to 0.01 now use the statutory bases: nyc_school_tax_credit.yaml (single $441,000: 998.64 to 999.12; single $272,000: 613.32 to 613.80; joint $482,950: 1,088.81 to 1,088.878), the two NYC school tax credit reform files under contrib/local/nyc/stc/, and spm_unit_local_tax.yaml (single, $100,000 wages: NYC tax down $0.48).

2. Indiana supplemental homestead credit: qualification, homestead base, referendum exclusion (us-in-supplemental-homestead-proxies, 2026+)

  • Source. IC 6-1.1-20.6-7.7(b)-(d), added by SEA 1 (2025), SECTION 74 (enrolled act, PDF page 124). (b): a person who qualifies for the IC 6-1.1-12-37 homestead standard deduction (or is married at death to a deceased spouse who did) is entitled to the credit "against the person's property tax liability on the same homestead". (c): the lesser of 0.1 x that liability or $300. (d): taxes approved by referendum or local public question "shall not be considered". DLGF's June 18, 2025 FAQ, questions 26-30 and 33 (PDF pages 7-9), agrees and orders this credit after the Over 65 and Blind/Disabled credits.
  • Before. min(10% x all tax-unit real_estate_taxes, $300), with no qualification gate, no homestead-only base and no referendum exclusion.
  • Change. Three new tax-unit inputs: in_supplemental_homestead_credit_eligible (7.7(b) qualification), in_homestead_property_tax_liability (the homestead's liability after earlier credits and before this one) and in_homestead_referendum_property_tax. Credit = eligible x min(0.1 x max(liability - referendum, 0), $300).
  • Witness. 2026, real_estate_taxes $3,000, no homestead qualification: $0 (main: $300). Eligible, homestead liability $2,000, referendum $1,000: $100 (main: $200 on $2,000 of taxes).
  • Impact note. None of the three inputs is in the microdata yet, so this credit is zero in microsimulation until the data supplies them. The statute gives no basis for inferring qualification or the homestead liability from generic real-estate taxes.

3. Virginia Commonwealth Savers deduction: per-account cap and carryforward (us-va-529-deduction-owner-and-line, 2024+)

  • Source. Va. Code § 58.1-322.03(7)(a): "limited to $4,000 per prepaid tuition contract or college savings trust account"; the excess "may be carried forward and subtracted in future taxable years until ... fully deducted". (7)(b): an owner aged 70 or older deducts "the full amount ... less any amounts previously deducted". The 2024 Form 760 instructions, code 104 (PDF page 28) agree.
  • Before. Owner allocation and placement after VAGI were already fixed (Allocate Virginia's 529 deduction to the owner of record and deduct it after VAGI #9875). Under 70 the model pooled the cap as min(total contributions, $4,000 x beneficiary count). It had no carryforward.
  • Change. New Person inputs va_529_plan_deduction_capped_amount (sum over owned accounts of min($4,000, contributions + undeducted carryforward)) and va_529_plan_carryforward. When account-level amounts are not supplied, the capped amount defaults to min(contributions + carryforward, $4,000 x accounts): an even split across accounts, the largest deduction any split of the same totals allows. Under 70 the deduction is the capped amount; from 70 it is contributions plus carryforward. Owner and dependent masks are unchanged.
  • Witness. 2024, age 45, $7,000 and $1,000 to two accounts (capped amount $5,000): $5,000 (main: $8,000). $3,000 carried forward into one account, no new contribution: $3,000 (main: $0). Age 70, $1,000 plus $6,000 carried forward: $7,000.

4. Washington senior and disabled persons property tax exemption: statutory disability and veteran pathways (us-wa-pte-disability-proxy, 2008+)

  • Source. RCW 84.36.381(3)(a)(i): at least the age threshold, "or ... retired from regular gainful employment by reason of disability" (RCW 84.36.383(6) incorporates 42 U.S.C. 423(d)(1)(A)); unchanged since 2008 c 6 § 706 (PDF page 85). (3)(a)(ii): a veteran "entitled to and receiving compensation" from the VA at a total disability rating (2015 3rd sp.s. c 30, collection years 2016+), or a combined rating of 80% or more (2019 c 453 §§ 1, 9, PDF pages 3, 13; 2020+), lowered to 40% (2025 c 200 §§ 1, 3, PDF pages 3, 5; 2027+). WAC 458-16A-130 agrees. A 100% schedular evaluation is a total rating (38 CFR 3.340(a)(2)).
  • Before. age >= threshold | is_disabled: a working 45-year-old with is_disabled qualified, and a compensated 80% veteran without is_disabled did not.
  • Change. New Person inputs wa_pte_retired_due_to_disability, wa_pte_receives_va_disability_compensation, wa_pte_va_service_connected_rating and wa_pte_va_total_disability_rating; parameters veteran/combined_rating_threshold (none before 2020, 0.8 from 2020, 0.4 from 2027) and veteran/rating_requirement_in_effect (from 2016). Every VA pathway requires is_veteran. The wa_pte_categorical_eligible.py entry leaves the source-conflict ratchet's KNOWN_UNMARKED, since the "in practice" comment is gone.
  • Witness. 2024, age 45, is_disabled, not retired, $5,000 tax on a $500,000 home: not eligible, $0 (main: $3,600). Retired by reason of disability: $3,600. Compensated veteran rated 40%: not eligible in 2026, eligible in 2027.
  • Left as is (more than one defensible reading). For collection years before 2016 the veteran pathway was "one hundred percent service-connected disability as provided in 42 U.S.C. Sec. 423(d)(1)(A)". That can be read as a 100% VA rating, or as a wholly service-connected disability meeting the Social Security definition, with no VA rating required. The model keeps main's is_disabled for veterans in those years. The non-veteran disability-retirement rule is unambiguous from 2008 and applies to every year.
  • Impact note. None of the four inputs is in the microdata, so in microsimulation only the age pathway remains until the data supplies them.

Invariants

  • NYC: amount >= 0; amount = 0.171% x T at T <= threshold; continuous except for the statutory step at the threshold (base - 0.171% x threshold = $0.064 joint, $0.376 HoH, $0.48 single); matches the § 606(ggg)(4-b) tables for every filing status (differential test, tolerance 0.001).
  • IN: 0 <= credit <= min($300, 0.1 x homestead liability); zero when not qualified or outside Indiana.
  • VA: deduction >= 0; under 70, deduction = capped amount <= contributions + carryforward when the default applies; from 70, deduction = contributions + carryforward; dependents get 0 (existing test_va_529_invariants.py).
  • WA: eligibility is monotone in each pathway input; is_disabled alone never qualifies a non-veteran.

Test plan

  • YAML tests from the statute and agency examples, written failing first. The "main" witness values above were computed on main ce9377ee80 before the fix.
  • Run here, one file per process, at 29778a23d8 or with identical model code:
    • wa_pte_categorical_eligible.yaml: 21 passed
    • nyc_school_tax_credit_rate_reduction_amount.yaml: 16 passed
    • va_529_plan_deduction.yaml: 16 passed
    • in_supplemental_homestead_credit.yaml: 11 passed
    • spm_unit_local_tax.yaml: 4 passed (case 1 updated from the run's float32 outputs)
    • income_tax_elimination/integration.yaml: 6 passed
    • in_blind_disabled_property_tax_credit_in_aggregate.yaml: 2 passed
    • tests/code_health/test_source_conflicts.py: 102 passed, 1 failed. The failure is test_conflict_sounding_comments_do_not_grow, which flags FL and SD LIHEAP files this branch does not touch, so it also fails on main. None of this PR's files is flagged, so removing the WA KNOWN_UNMARKED entry is consistent.
  • Not run here (host load 90-190; each process took 8-35 min). Edited: nyc_school_tax_credit.yaml, contrib/local/nyc/stc/adjust_income_limit_by_filing_status_and_eligibility_by_children.yaml and ..._joint_override.yaml, household/state_property_tax_credits/in_supplemental_homestead_credit_in_aggregate.yaml, the WA integration.yaml, wa_pte_eligible.yaml and wa_senior_disabled_property_tax_exemption.yaml, and test_nyc_school_tax_credit_income_test_invariants.py. Unedited but affected: nyc_school_tax_credit_rate_reduction_amount_eligible.yaml, VA plan_529/integration.yaml and tests/core/test_va_529_invariants.py. CI covers these.
  • Source-conflict register: not applicable. No statute-form conflict is resolved here.
  • ruff format / ruff check on changed files.
  • Changelog fragment in changelog.d/.
  • No microsimulation was run here; the hub runs the impact.

Proposed follow-up (not in this PR)

  • WA age threshold before 2020. age_threshold.yaml uses 62 before 2020, but the 2008 and 2015 texts of RCW 84.36.381(3)(a) already say sixty-one.

axiom: pending: hub files parity

🤖 Generated with Claude Code

MaxGhenis and others added 7 commits October 20, 2026 20:07
… reduction amount

Tax Law § 606(ggg)(4-b)(A)-(C), as enacted by L.2017, ch. 59, Part C, § 2
for tax years from 2017, gives the amount over each threshold as a fixed
base ($37 joint and surviving spouse, $25 head of household, $21 single
and separate) plus 0.228% of the excess, not the first band carried
forward at 0.171%. Fixes #8947.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…estead

IC 6-1.1-20.6-7.7(b)-(d) (SEA 1 2025, SECTION 74) gives the credit only to
a person who qualifies for the IC 6-1.1-12-37 homestead standard deduction
(or that person's surviving spouse), computes it on the liability of that
homestead, and leaves out referendum-approved taxes. Generic
real_estate_taxes establish none of these, so qualification, the homestead
liability and its referendum component become tax-unit inputs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…forward excess

Va. Code § 58.1-322.03(7)(a) limits the deduction to $4,000 per contract or
account and carries forward the excess until fully deducted; (7)(b) lets an
owner aged 70 or older deduct the full amount less amounts previously
deducted. Add va_529_plan_deduction_capped_amount (account-level result,
defaulting to an even split across accounts) and va_529_plan_carryforward.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…led property tax exemption

RCW 84.36.381(3)(a) admits a claimant under the age threshold only if
retired from regular gainful employment by reason of disability, or as a
veteran entitled to and receiving VA compensation at a total disability
rating or, from collection year 2020, a combined rating of 80% (40% from
2027). Before 2016 the veteran text can be read more than one way, so
generic disability is kept for veterans in those years.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nyc_school_tax_credit.yaml and the NYC school tax credit reform tests
asserted the first band carried forward at 0.171% (20.52 single, 36.936
joint) to 0.01; they now use the § 606(ggg)(4-b) bases of $21 and $37.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… base

A single filer with $100,000 of wages has city taxable income of $92,000,
so the rate reduction amount is $21 + 0.228% x 80,000 = $203.40, $0.48
more than before; NYC tax, SPM taxes and SPM net income move by $0.48.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@DTrim99

DTrim99 commented Oct 21, 2026

Copy link
Copy Markdown
Collaborator

PR Review: Follow the statute for the NYC school tax rate reduction, IN supplemental homestead, VA 529 and WA senior/disabled property tax exemption

PR #10330 (author: MaxGhenis), head 29778a23d8. This is a first review. The PR makes four model changes:

  • NYC school tax credit, rate reduction amount (2017+). The five marginal-rate scales become rate_reduction/amount/{threshold,base} by filing status plus first_band_rate and excess_rate. Above the threshold, the amount is now the statute's fixed base ($37 / $25 / $21) plus 0.228% of the excess, instead of the first band carried forward at 0.171%.
  • Indiana supplemental homestead credit (2026+). Three new tax-unit inputs: homestead deduction qualification, the homestead's liability after earlier credits, and its referendum taxes. The credit is now eligible × min(10% × max(liability − referendum, 0), $300), instead of 10% of all real_estate_taxes.
  • Virginia Commonwealth Savers deduction. Two new Person inputs: a per-account capped amount and an undeducted carryforward. Under 70 the deduction is the capped amount; from 70 it is contributions plus carryforward.
  • Washington senior/disabled property tax exemption (2008+). is_disabled no longer qualifies anyone by itself. The disability pathway needs the new wa_pte_retired_due_to_disability input. The veteran pathway needs is_veteran, receipt of VA compensation and a qualifying rating, dated by two new parameters. Before 2016, veterans keep is_disabled.
  • Tests and housekeeping. 15 YAML files and one Python test change. The WA file leaves the ratchet's KNOWN_UNMARKED, and there is a fixed changelog fragment.

The PR has no comments or reviews yet. It touches no partner test file.

Path prefixes:

  • IN/ = policyengine_us/variables/gov/states/in/tax/property/supplemental_homestead_credit/
  • VA/ = policyengine_us/variables/gov/states/va/tax/income/deductions/plan_529/
  • WA/ = policyengine_us/variables/gov/states/wa/dor/property_tax_exemption/senior_disabled/
  • WAT/ = policyengine_us/tests/policy/baseline/gov/states/wa/dor/property_tax_exemption/senior_disabled/

Sources read for this review (all fetched 2026-10-21):

Summary

What is right. All four changes follow the governing statute in the years the PR claims. None of them is a statute-versus-form conflict: in each case the agency's form or guidance agrees with the statute, and the old model matched neither.

  • 1. NYC (2017+): statute and forms agree on fixed bases.
    • The statute. § 606(ggg)(4-b), as amended by L.2017, ch. 59, Part C, § 2 (file pages 8-9):
      • (A) joint and surviving spouse: "Over $21,600 but not over $500,000: $37 plus 0.228% of excess over $21,600";
      • (B) head of household: "Over $14,400 but not over $500,000: $25 plus 0.228% of excess over $14,400";
      • (C) single and separate: "Over $12,000 but not over $500,000: $21 plus 0.228% of excess over $12,000".
    • Years. (4): "For taxable years beginning after two thousand sixteen, the credit shall equal the 'fixed' amount ... plus the 'rate reduction' amount". § 7: "shall apply to taxable years beginning on and after January 1, 2017" (file page 14). The current § 606 text is unchanged.
    • The forms. IT-201-I 2025 (file page 21) prints "$ 37 plus 0.228% of the excess over $21,600", "$ 21 plus 0.228% of the excess over $12,000" and "$ 25 plus 0.228% of the excess over $14,400". The 2017 (file page 30) and 2018 (file page 31) tables are identical, with ".228%".
    • No conflict. The old test comments ("The $37 amount is rounded in the instructions") were wrong: the bases are in the statute itself. The jump at each threshold ($0.064 joint, $0.376 head of household, $0.48 single) is statutory.
  • 2. Indiana (2026+): statute and DLGF agree.
    • The credit. IC 6-1.1-20.6-7.7 (SECTION 74, file page 124):
      • (a) "applies for property taxes first due and payable in calendar years beginning after December 31, 2025";
      • (b) a person who "qualifies for a standard deduction from the assessed value of the person's homestead under IC 6-1.1-12-37 (or is married at the time of death to a deceased spouse who qualifies ...) is also entitled to receive a supplemental homestead credit ... against the person's property tax liability on the same homestead";
      • (c) "the lesser of: (1) ... the property tax liability first due and payable on the homestead property for the calendar year; multiplied by ... one-tenth (0.1); or (2) three hundred dollars ($300)";
      • (d) "Property taxes imposed after being approved by the voters in a referendum or local public question shall not be considered".
    • The order of credits is statutory. IC 6-1.1-20.6-3(3), as amended by SECTION 73 (file pages 123-124), defines the liability for section 7.7 as "determined after application of all credits and deductions under this article or IC 6-3.6, including the credit granted by section 7 or 7.5 of this chapter, but not including the credits granted under section 7.7 or 8.5". So the over-65 and blind/disabled credits come first.
    • DLGF agrees. Question 27: "The credit should be calculated based on the tax liability attributable to the homestead property that is receiving the Homestead Deduction." Question 29: it "would be calculated after the application of the new Over 65 and Blind/Disabled Credits." The question 33 table lists them as steps 5 and 6.
    • Not the deduction. The brief for this review framed this item as the IC 6-1.1-12-37.5 supplemental homestead deduction. The PR touches only the 7.7 credit; DLGF question 26 stresses that they are different. PE-US doesn't model the 37.5 deduction.
  • 3. Virginia: statute and instructions agree on the cap and carryforward.
    • (7)(a): "the amount deducted on any individual income tax return in any taxable year shall be limited to $ 4,000 per prepaid tuition contract or college savings trust account ... If the purchase price or annual contribution to a college savings trust account exceeds $ 4,000, the remainder may be carried forward and subtracted in future taxable years until the purchase price or college savings trust contribution has been fully deducted". The transferee "shall succeed to the transferor's tax attributes ..., including ... carryover".
    • (7)(b): an owner who "has attained age 70 shall not be subject to the limitation ... Such taxpayer shall be allowed a deduction for the full amount paid for the contract or contributed to a college savings trust account, less any amounts previously deducted."
    • The instructions (2024 and 2025, code 104): "enter the lesser of $4,000 or the amount contributed during the taxable year to each Commonwealth Savers account ... If you contributed more than $4,000 per account during the taxable year, you may carry forward any undeducted amounts until the contribution has been fully deducted."
    • The age-70 sentence differs slightly (Suggestion G2), but it is silent rather than contrary, and the statute controls.
    • Keep claimable filers' own exemptions under the HI and VA dependent-exemption repeal #10271 doesn't interact. It changes only the HI/VA dependent-exemption repeal reform and its tests. The 529 deduction still masks to head and spouse, and the two PRs share no file or variable.
  • 4. Washington: statute, session laws and WAC agree.
    • 2008 text (2008 c 6 § 706, file page 85), RCW 84.36.381(3): "(a) sixty-one years of age or older on December 31st of the year in which the exemption claim is filed, or must have been, at the time of filing, retired from regular gainful employment by reason of disability, or (b) a veteran of the armed forces of the United States with one hundred percent service-connected disability as provided in 42 U.S.C. Sec. 423 (d)(1)(A) as amended prior to January 1, 2005."
    • 2015 (3rd sp.s. c 30 § 2): "(ii) A veteran ... entitled to and receiving compensation from the United States department of veterans affairs at a total disability rating for a service-connected disability". § 4: "This act applies to taxes levied for collection in 2016 and thereafter."
    • 2019 (c 453 § 1, file page 3): "(A) A combined service-connected evaluation rating of eighty percent or higher; or (B) A total disability rating for a service-connected disability without regard to evaluation percent." § 9 (file page 13): "applies for taxes levied for collection in 2020 and thereafter."
    • 2025 (c 200 § 1, file page 3): "A combined service-connected evaluation rating of ((80)) 40 percent or higher". § 3 (file page 5): "applies to taxes levied for collection in 2027 and thereafter."
    • Disability. RCW 84.36.383(6): "'Disability' has the same meaning as provided in 42 U.S.C. Sec. 423(d)(1)(A)". WAC 458-16A-130(2)(b): "retired from regular gainful employment and unable to engage in any substantial gainful activity by reason of any medically determinable physical or mental impairment".
    • WAC timing. WAC 458-16A-130(2)(c) already prints 40 percent. The amendment took effect 2/20/26, for claims filed in 2026 for 2027 collections, so it is consistent with § 3.
    • The parameters (.inf for 2016-2019, 0.8 from 2020, 0.4 from 2027; the rating requirement from 2016) match these dates, keyed by collection year.
  • Tests. I hand-checked 22 expectations, listed under Verified correct. CI passed every changed file on a tree that contains Count the FL and SD LIHEAP comments in the source-conflict ratchet baseline #10334.
  • Batch checks.

There are no critical findings and three should-address items:

There are also six suggestions: Virginia default and guard, Virginia age-70 wording, Indiana citation and pre-2026 gating, NYC follow-ups including an unrecorded $62.50/$63 conflict, the Washington age threshold, and the PR body.

Status.

Critical (must fix)

None.

Should address

S1. The Axiom line axiom: pending: hub files parity is not a valid form

  • Where: the last line of the PR body.
  • The rule (CLAUDE.md, "Axiom Parity"): a PR that adds, updates or fixes policy needs one of encoded-correct, <rulespec PR> encoded, <rulespec issue> queued or n/a: <reason>. pending is not one of them. We flagged the same form on Fix the 2021 CTC split and surviving-spouse phaseout threshold #10306, Fix pre-2018 AMT child exemption and income base #10308, Fix Arkansas tax indexing, Kentucky 2021 CDCC, and WV 529 coordination #10324 and Fix Montana disability exclusion repeal, elderly credit receipt timing and occupancy tests #10331.
  • Why n/a doesn't fit. All four provisions are statutory, and the PR changes results in 2017+ (NYC), 2026+ (IN), every modelled VA year, and 2008+ (WA).
  • What rulespec-us has (main cea8379e0b):
    • NYC. us-ny/policies/tax/it-201-instructions/nyc-school-tax-credit-rate-reduction.yaml, rule nyc_school_tax_credit_rate_reduction_amount, computes ..._second_band_base_amount + ..._excess_rate * max(0, nyc_taxable_income - ..._first_band_upper_bound) with bases 37, 21 and 25 and rates 0.00171 and 0.00228.
    • Virginia. us-va/statutes/58.1/58/1-322/03.yaml holds only college_savings_annual_deduction_limit = 4000 and college_savings_no_limit_age = 70.
    • Indiana and Washington. There is no module or issue for IC 6-1.1-20.6-7.7 or RCW 84.36.381.
  • Severity: should. An invalid Axiom line is a merge blocker, not a model error.
  • Fix: change the line to axiom: us-ny:policies/tax/it-201-instructions/nyc-school-tax-credit-rate-reduction#nyc_school_tax_credit_rate_reduction_amount encoded-correct; TheAxiomFoundation/rulespec-us#<ny> queued; TheAxiomFoundation/rulespec-us#1510 queued; TheAxiomFoundation/rulespec-us#<in> queued; TheAxiomFoundation/rulespec-us#<wa> queued. Alternatively, cite encoder PRs as encoded. Before relying on these:
    • <ny>. Extend What program participation can affect one's eligibility for the Affordable Connectivity Program? #1452, or file a new issue, for TY2017-2024 under § 606(ggg)(4-b), for example us-ny/statutes/TAX/606/ggg.yaml. Cite L.2017 ch. 59 Part C §§ 2 and 7. Companion cases from the statute's tables:
      • 2017 head of household, $20,000 → 37.768;
      • 2017 surviving spouse, $21,601 → 37.00228;
      • 2017 separate, $12,000 → 20.52;
      • 2017 joint, $21,600 → 36.936.
    • Allow data tests to work without a policyengine_us package being installed #1510. Comment with this PR's carryforward and per-account cases, which follow from (7)(a)-(b):
      • under 70, $7,000 and $1,000 to two accounts → 5,000, with 3,000 carried forward;
      • a $3,000 carryforward and no new contribution → 3,000;
      • age 70, $1,000 plus a $6,000 carryforward → 7,000.
    • <in>. A new issue modelled on Add AMT parameters for 2020-2023 #1467:
      • Target: for example us-in/statutes/6-1.1-20.6-7.7.yaml, citing 7.7(a)-(d) and § 3(3) verbatim (quoted above).
      • Required outputs: qualification, the homestead base net of referendum taxes, and the credit.
      • Companion cases:
        • liability 2,000 → 200; 3,000 → 300; 5,000 → 300;
        • not qualified → 0;
        • liability 2,000 with 1,000 of referendum tax → 100;
        • gross homestead tax 2,000 after the $150 over-65 and $125 blind/disabled credits → 1,725 → 172.50.
    • <wa>. A new issue:
      • Target: for example us-wa/statutes/84/84.36/84/36/381.yaml, with the 2008, 2015, 2019 and 2025 texts and their application sections.
      • Companion cases:
        • age 45, retired by reason of disability → eligible; generic disability and not retired → ineligible;
        • compensated 40% veteran → ineligible for 2026 and eligible for 2027;
        • 2024, 80% → eligible; 70% → ineligible;
        • 2019, 90% without a total rating → ineligible; with a total rating → eligible;
        • a total rating without receipt of compensation → ineligible.
      • Blocker: each new issue must name it.

S2. The new inputs default to "off", so the Indiana credit and Washington's disability and veteran pathways vanish unless a user sets them

  • Where:
    • IN/in_supplemental_homestead_credit_eligible.py and IN/in_homestead_property_tax_liability.py: inputs with no formula, defaulting to false and 0;
    • WA/wa_pte_retired_due_to_disability.py, WA/wa_pte_receives_va_disability_compensation.py, WA/wa_pte_va_service_connected_rating.py and WA/wa_pte_va_total_disability_rating.py: inputs defaulting to false and 0.
  • What changes for users who don't set them:
    • Indiana (2026+). A homeowner with real_estate_taxes gets $0. The PR's own Case 7 shows it: $3,000 of taxes gives 0, where main gave $300. Yet 7.7(e) says "A person is not required to file an application for the credit", and the county auditor applies it to every homestead with the IC 6-1.1-12-37 standard deduction.
    • Washington. A 45-year-old SSDI recipient who owns a home gets nothing unless wa_pte_retired_due_to_disability is set. So does a 100% service-connected veteran unless three new inputs are set. The household calculator and the microdata supply is_disabled, not these.
    • Microsimulation. The PR body says so: "this credit is zero in microsimulation until the data supplies them" and "only the age pathway remains".
  • The statute does give a basis for defaults:
    • Washington disability. RCW 84.36.383(6) adopts 42 U.S.C. 423(d)(1)(A), the Social Security disability definition. An SSDI award (social_security_disability > 0) is SSA's finding under that definition and requires inability to engage in substantial gainful activity, which is WAC 458-16A-130(2)(b)'s test.
    • Washington veterans. is_fully_disabled_service_connected_veteran already exists ("a fully disabled veteran who became so as a result of an injury during service"). It implies a total rating.
    • Indiana. The sibling credits in the same umbrella still use real_estate_taxes > 0 as the homestead proxy (in_over_65_property_tax_credit_eligible) and real_estate_taxes as the base. Section 3(3) fixes the order: liability after the over-65 and blind/disabled credits. The PR's aggregate tests compute exactly that by hand ($2,000 − $150 − $125 = $1,725).
  • Reach. Neither output feeds household net income. The Indiana credit is read only by taxsim_state_property_tax_credit (via state_property_tax_credits.yaml), and wa_senior_disabled_property_tax_exemption has no consumer. Both outputs are now zero or understated for most households that would qualify under the law.
  • Severity: should. Input defaults give wrong results under ordinary use where the model already has statute-grounded values (compare Fix Montana disability exclusion repeal, elderly credit receipt timing and occupancy tests #10331 S3).
  • Fix: keep the inputs as overrides, but give them formulas:
    • in_supplemental_homestead_credit_eligible: add(tax_unit, period, ["real_estate_taxes"]) > 0, the over-65 credit's homeowner proxy.
    • in_homestead_property_tax_liability: max_(real_estate_taxes − in_over_65_property_tax_credit − in_blind_disabled_property_tax_credit, 0), citing § 3(3).
    • wa_pte_retired_due_to_disability: social_security_disability > 0. Optionally add adult is_ssi_disabled without earnings above SGA, since SSI uses the same adult definition.
    • wa_pte_va_total_disability_rating: is_fully_disabled_service_connected_veteran.
    • Tests. The explicit-input cases still pass. Add one default case per state, and let the IN aggregate cases assert the derived 1,725 and 1,850.
    • Caveat. As on Fix Montana disability exclusion repeal, elderly credit receipt timing and occupancy tests #10331 S4, a value supplied for one unit gives other units the default array, not the formula. If that matters, split each override into its own input.

S3. Before 2016, Washington veterans still qualify on generic is_disabled, which both of the PR's readings reject

  • Where:
    • WA/wa_pte_categorical_eligible.py:43: earlier_veteran = person("is_disabled", period);
    • WAT/wa_pte_categorical_eligible.yaml:347, Case 20 (2015, age 45, is_disabled, is_veteran, not retired): expected true;
    • the PR body, "Left as is (more than one defensible reading)".
  • The 2008 text (file page 85): a veteran "with one hundred percent service-connected disability as provided in 42 U.S.C. Sec. 423 (d)(1)(A)".
  • The PR's two readings: "a 100% VA rating, or ... a wholly service-connected disability meeting the Social Security definition".
    • Both require service connection, and the first also needs a rating.
    • Generic disability isn't enough. is_disabled establishes neither: the PR itself says it covers non-service-connected and still-working cases.
  • The result. Case 20's veteran is under 61, is not retired by reason of disability (so (3)(a) fails), and has no service-connected disability on record (so (3)(b) fails). The model says eligible, and a new test now pins that.
  • A fitting input exists. is_fully_disabled_service_connected_veteran is common to both readings: 100% and service-connected. A person fully disabled in that sense also meets 423(d)(1)(A).
  • Severity: should. The reach is limited to veterans under 61, not retired by reason of disability, in collection years 2008-2015. But the deferral's stated reason doesn't support keeping is_disabled, and the PR adds a test that pins it.
  • Fix:
    • Use is_fully_disabled_service_connected_veteran for earlier_veteran.
    • Change Case 20 to expect false with is_disabled alone.
    • Add a 2015 case with the service-connected input → true.
    • Update the PR body's "Left as is" paragraph.

Suggestions

G1. Virginia: the default ignores carryforward-only accounts, and a supplied capped amount is not bounded

  • Where: VA/va_529_plan_deduction_capped_amount.py:34-35: min_(contributions + carryforward, p.cap * accounts), with accounts = count_529_contribution_beneficiaries.
  • The gap. That input is an int with no default (0), labelled "Number of beneficiaries to 529 college savings plan contributions". An owner with a carryforward and no contribution this year naturally has 0 beneficiaries of contributions, so the default gives min(3,000, 0) = 0.
    • The witness depends on it. The PR body's "$3,000 carried forward into one account, no new contribution: $3,000" holds only because the test supplies count 1 and the capped amount (va_529_plan_deduction.yaml:195).
  • No bound. Under 70, a supplied va_529_plan_deduction_capped_amount above contributions plus carryforward passes straight through (VA/va_529_plan_deduction_person.py:35).
  • Fix (optional):
    • In the default, count at least one account when the carryforward is positive, or document that accounts holding only a carryforward must be counted.
    • Bound the under-70 branch by contributions + carryforward.
    • Add a carryforward-only case with count 0.

G2. Virginia: the instructions' age-70 sentence covers only this year's contributions

  • The instructions (2024 and 2025, code 104, file page 28): "However, if you are age 70 or older on or before December 31 of the taxable year, you may deduct the entire amount contributed during the taxable year."
  • The statute (7)(b): "the full amount paid for the contract or contributed ..., less any amounts previously deducted", which includes an undeducted carryforward.
  • Which source controls. The statute does: it is explicit, and the instructions are silent on carryforward at 70 rather than contrary. The PR follows the statute (contributions plus carryforward).
  • The wording. The PR body and the YAML header say the instructions "agree" on (7)(b).
  • Fix (optional):
    • Say that the instructions are silent on the age-70 carryforward.
    • If you have evidence that Tax limits age-70 filers to the current year, add a candidates.yaml entry (follows: statute).

G3. Indiana: cite the statute for the order, and gate the credit before 2026

  • The citation. IN/in_homestead_property_tax_liability.py cites DLGF questions 27, 29 and 33 for "after the credits applied before the supplemental homestead credit". IC 6-1.1-20.6-3(3), as amended by SECTION 73 (file pages 123-124, quoted under Summary), is the statutory source. Add it.
  • The pre-2026 credit. 7.7(a) starts the credit with taxes first due in 2026, and the new formula comment says so. But rate.yaml and cap.yaml extrapolate back, so the standalone variable is nonzero in 2025 when the inputs are supplied. Only the umbrella list excludes it (the aggregate file's 2025 case says so). This predates the PR.
  • Fix (optional): add an in-effect gate, or zero values before 2026.

G4. NYC follow-ups

  • (a) Pre-2017 extrapolation. The new parameters start 2017-01-01 and extrapolate back. § 606(ggg)(4) starts the rate reduction amount "for taxable years beginning after two thousand sixteen"; for 2016, (3) gave only a flat $125 / $62.50. This predates the PR, because the old scales also extrapolated back. Consider a zero before 2017.
  • (b) Removed parameter paths. The PR deletes five parameter paths (rate_reduction/amount/{single,joint,separate,head_of_household,surviving_spouse}). Saved policies that edit them would break. Say so in the PR body or changelog.
  • (c) An unrecorded conflict in the same credit.
    • The statute: § 606(ggg)(4-a)(B) sets the fixed amount for unmarried, head-of-household and separate filers at "sixty-two dollars and fifty cents".
    • The form and the model: fixed/amount.yaml uses the IT-201-I's $63, and its own comment says "IT-201-I Table 1 rounds the statutory $62.50 ... to $63".
    • The record. This statute-versus-form conflict is in neither candidates.yaml nor the register.
    • Why mention it here. It is outside this diff, but it is the mirror of item 1: there the PR rejects a form rounding in favour of the statute.
    • Fix: record it as a candidate, or fix it in a follow-up.

G5. Washington age threshold

  • The text. The PR body notes that age_threshold.yaml uses 62 before 2020 although the 2008 and 2015 texts say sixty-one.
  • The timing. The test is "on December 31st of the year in which the exemption claim is filed", and the exemption applies to taxes "due and payable in the year following the year in which a claim is filed". So in a collection-year period, which is how the new veteran parameters are keyed, a claimant is 62 by the end of the collection year.
  • Fix (optional): file the follow-up, and settle the period convention in it, since the 2020+ value of 61 may then be the one that's off.

G6. PR body

  • Stale test plan. It lists files "Not run here ... CI covers these". CI has now run all of them (see CI status).
  • Bill names. The reference titles call the 2019 and 2025 bills "SSB 5160" and "HB 1106". The session laws are ESSB 5160 and EHB 1106.
  • Fix (optional): update both, and fix the Axiom line (S1).

Verified correct

  • Hand-checks (22 expectations).
    • NYC:
      1. 2017 head of household, $20,000: 25 + 0.00228 × 5,600 = 37.768.
      2. 2025 joint, $30,000: 37 + 0.00228 × 8,400 = 56.152.
      3. nyc_school_tax_credit.yaml, single $441,000: 21 + 0.00228 × 429,000 = 999.12.
      4. 2017 separate at $12,000: "not over", so 0.00171 × 12,000 = 20.52. Joint at $21,600: 36.936.
      5. Mixed vector: 0.00171 × 10,000 = 17.1; 25 + 0.00228 = 25.00228; 37 + 0.00228 × 78,400 = 215.752.
      6. spm_unit_local_tax.yaml Case 1:
        • Taxable income. 100,000 − 8,000 = 92,000.
        • Amount. 21 + 0.00228 × 80,000 = 203.40, up $0.48.
        • NYC tax. 3,175.1702 − 0.48 = 3,174.6902.
        • SPM net income. It is the float32 output (62,902.109 against 62,902.113 by hand).
      7. Contrib Case 5, joint $263,950: 37 + 0.00228 × 242,350 = 589.558, plus 125 = 714.558.
      8. Elimination-credit Cases 1 and 3:
        • Case 1: 63 + 25 + 0.00228 × 8,400 = 107.152.
        • Case 3: 125 + 37 + 0.00228 × 18,896 = 205.08288, so nyc_income_tax = 1,375.71552 − 192.25944 − 205.08288 = 978.3732.
    • Indiana (2026):
      9. Case 9: min(0.1 × (2,000 − 1,000), 300) = 100.
      10. Case 10: max(1,000 − 1,200, 0) = 0, so 0.
      11. Case 6, joint, liability 4,000: min(400, 300) = 300.
      12. Blind/disabled aggregate:
      - Liability. 2,000 − 150 − 125 = 1,725.
      - Credit. 172.50.
      - Umbrella. 150 + 125 + 172.50 = 447.50.
      13. Over-65 aggregate: 0.1 × 1,850 = 185; umbrella 335.
    • Virginia (2024):
      14. Uneven accounts, capped amount supplied (5,000): 5,000; main gave min(8,000, 8,000) = 8,000.
      15. Default with a $2,000 carryforward and one account: min(3,000 + 2,000, 4,000) = 4,000.
      16. Age 70: 1,000 + 6,000 = 7,000, with the supplied cap ignored.
      17. Spouses: [7,000, 500 + 2,500 = 3,000], so 10,000. Dependent owner: [0, 0].
    • Washington:
      18. Case 8 (2024): generic disability and not retired, so ineligible and 0. Main gave 1,500 + 300,000 × 0.007 = 3,600.
      19. Case 9: 5,000 × 0.30 + max(60,000, 300,000) × (3,500 / 500,000) = 3,600.
      20. Integration Case 2 (King County lookup): 4,800 × 0.30 = 1,440; 300,000 × 0.00672 = 2,016; total 3,456.
      21. Case 10: 0.4 < 0.8 in 2026, so false; 0.4 ≥ 0.4 in 2027, so true. Cases 16-18 (2019): 0.9 against .inf without a total rating → false; rating 1 → total → true; total flag → true.
      22. Case 21 vector:
      - 61 ≥ 61 → true;
      - generic disability only → false (is_veteran is veterans_benefits > 0, which is 0);
      - retired → true;
      - compensated veteran at 0.8 → true.
  • References.
    • NYC. S.2009-C file pages 8-9 hold the (4-b) tables and file page 14 holds § 7, so the title "#page 8-9,14" follows CLAUDE.md. IT-201-I 2017 p. 30, 2018 p. 31 and 2025 p. 21 show line 69a.
    • Washington. The 2008 session law p. 85 shows (3). 2019 c 453 file pages 3 and 13 show § 1(3)(a)(ii) and § 9. 2025 c 200 file pages 3 and 5 show "((80)) 40" and § 3.
    • Indiana. SEA 1 p. 124 shows 7.7, and the DLGF FAQ pp. 7-9 show questions 26-33. The variable tuples carry # PDF pages 7-9 comments.
    • Virginia. File page 28 shows code 104.
  • Code.
    • NYC. p.threshold[filing_status] and p.base[filing_status] cover all five statuses. max_(nyc_taxable_income, 0) handles negative income. where(taxable_income > threshold, ...) keeps the threshold itself in the lower band, which is the statute's "not over". The $500,000 limits stay in the unchanged eligibility variable.
    • Washington. where on the scalar rating_requirement_in_effect broadcasts. The .inf threshold makes rating >= threshold false for 2016-2019. rating >= 1 implements 38 CFR 3.340(a)(2).
    • Vectorization. Everything is vectorized, and the mixed NYC and WA cases exercise it.
  • Callers at the head.
    • No orphaned paths. No code reads the deleted NYC scales; the two NYC STC reforms read the variable, not the parameters.
    • in_supplemental_homestead_credit is read only through state_property_tax_credits.yaml (2026 block).
    • wa_pte_categorical_eligible is read only by wa_pte_eligible.
    • va_529_plan_deduction_person is unchanged downstream.
  • Batch lessons:
  • Changelog. changelog.d/statute-bugs-nyc-in-va-wa.fixed.md is a top-level fragment, and fixed is the right type.

Axiom line assessment

Invalid: axiom: pending: hub files parity (S1).

  • Recommended form: axiom: us-ny:policies/tax/it-201-instructions/nyc-school-tax-credit-rate-reduction#nyc_school_tax_credit_rate_reduction_amount encoded-correct; TheAxiomFoundation/rulespec-us#<ny> queued; TheAxiomFoundation/rulespec-us#1510 queued; TheAxiomFoundation/rulespec-us#<in> queued; TheAxiomFoundation/rulespec-us#<wa> queued.
  • Not n/a. These are statutory provisions with changed results in claimed years.

CI status

27 pass, 3 skipping, 0 pending, 0 failed. I re-checked gh pr checks 10330 at the end of this review, and the head is still 29778a23d8.

  • The green run. Run 39617825642 (pull_request, created 2026-10-21 14:33 UTC) tested merge commit 78ef47c3, which merges the head into fec98b87c8 (Count the FL and SD LIHEAP comments in the source-conflict ratchet baseline #10334).
  • Where the changed tests ran:
    • Rest-a: the NYC files (nyc_school_tax_credit_rate_reduction_amount.yaml 16 cases, nyc_school_tax_credit.yaml, the elimination integration.yaml 6, and ..._eligible.yaml).
    • States-shard-1: the Indiana unit file (11) and both aggregate files.
    • States-shard-2: the Washington files (categorical 21, integration 14, eligible, exemption 18).
    • States-shard-4: the Virginia files (va_529_plan_deduction.yaml 16, integration.yaml 3).
    • Household: spm_unit_local_tax.yaml.
    • Contrib other-shard-1: both NYC STC reform files.
    • Rest (Python + variables): the NYC invariant tests and test_va_529_invariants.py.
    • Full suites. Microsimulation and Household API Partners passed.
  • Locally: I ran no tests or model probes. CI is green at the current head. The expectations and the S2/S3/G1 traces were checked by hand from the code, parameters and sources. The ratchet regex was applied statically.

Branch status

0 critical, 3 should and 6 suggestions are open at this head.

Verdict: REQUEST_CHANGES

@DTrim99 DTrim99 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All four changes follow the governing statute in the claimed years (NYC 606(ggg)(4-b), IN 6-1.1-20.6-7.7, VA 58.1-322.03(7), WA 84.36.381(3)(a)), and 22 expectations hand-check. Three should-address items: (1) the 'pending: hub files parity' axiom line is invalid; (2) the new IN and WA inputs default to off, so the IN credit is $0 and the WA disability and veteran pathways close for every household (microsim included) unless they're set, so derive the defaults; (3) pre-2016 WA veterans still qualify on generic is_disabled. Six suggestions. Full report in the comment above.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NYC school tax credit rate reduction should preserve rounded second-band base amounts

2 participants