The model applies the next tier's lower percentage to California's child and dependent care credit at AGI of $40,000, $70,000 and $100,000

Aperta Adatta ai principianti
#10,915 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 2 giorni

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
82/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
python
Ambito
backend

Direzione di ricerca

La ricerca errata si trova in ca_cdcc.py alla riga 17, dove p.rate.calc(agi) legge la scala a fasce in rate.yaml. Esegui lo script di riproduzione presente nell'issue per confrontare le aliquote con right=False e right=True ai tre AGI di riferimento. È completato quando gli AGI di $40,000, $70,000 e $100,000 ottengono l'aliquota della fascia inferiore e i test YAML fissano questi tre valori.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

The Legislature set California's percentage of the federal credit at 50% for adjusted gross income (AGI) of $40,000 or less, 43% over $40,000 through $70,000, and 34% over $70,000 through $100,000. The Franchise Tax Board applies these tiers to federal AGI. The model puts each endpoint in the next tier: it applies 43% at $40,000, 34% at $70,000 and 0% at $100,000. Only filers with federal AGI equal to one of those three amounts get the wrong percentage.

Example

For example, a head of household in California has one child aged 3, $5,000 of child care costs and wages as their only income in 2025. On the 2025 FTB 3506, the filer multiplies line 6, here the $3,000 one-child limit, by the federal decimal on line 7 to get line 8, then multiplies line 8 by California's decimal on line 9:

Federal AGI Line 8 Line 9 Credit on FTB 3506 Model's ca_cdcc
$40,000 $660 .50 $330 $283.80
$70,000 $600 .43 $258 $204.00
$100,000 $600 .34 $204 $0

At $39,999 and $40,001, the model applies the line 9 chart's 50% and 43%, so it misplaces only the endpoints. At $40,000, this filer owes no California tax after exemption credits either way. At $70,000 the model gives $239.19 of California income tax; with the $258 credit from FTB 3506 it would give $185.19, $54 less. At $100,000 it gives $2,156.29, and with the $204 credit it would give $1,952.29.

What California law says

In SB 86 (2011), section 2, the Legislature amended Revenue and Taxation Code section 17052.6. In subdivision (b)(2), it set 50% for AGI of "$40,000 or less", 43% "[o]ver $40,000 but not over $70,000" and 34% "[o]ver $70,000 but not over $100,000". The Franchise Tax Board prints the same chart for line 9 in its 2025 FTB 3506 instructions and lets a filer claim the credit with federal AGI of $100,000 or less.

Where it sits in the code

In ca_cdcc.py, line 17, the model calls p.rate.calc(agi) on the single-amount scale in rate.yaml, lines 2-21. With the default right=False in calc, the model puts an AGI equal to a threshold in the tier that starts there. See #10072 and #10177 for the same pattern in New Jersey's and West Virginia's tables.

Reproduce

At commit 935b24ff:

import numpy as np
from policyengine_us import CountryTaxBenefitSystem, Simulation

YEAR = 2025
for wages in [40_000, 70_000, 100_000]:
    sim = Simulation(situation={
        "people": {
            "parent": {"age": {YEAR: 35}, "employment_income": {YEAR: wages}},
            "child": {"age": {YEAR: 3}},
        },
        "tax_units": {"tax_unit": {
            "members": ["parent", "child"],
            "filing_status": {YEAR: "HEAD_OF_HOUSEHOLD"},
            "tax_unit_childcare_expenses": {YEAR: 5_000},
        }},
        "spm_units": {"spm_unit": {"members": ["parent", "child"]}},
        "families": {"family": {"members": ["parent", "child"]}},
        "marital_units": {
            "parent": {"members": ["parent"]},
            "child": {"members": ["child"]},
        },
        "households": {"household": {
            "members": ["parent", "child"],
            "state_code": {YEAR: "CA"},
        }},
    })
    print(wages)
    for variable in [
        "adjusted_gross_income",
        "ca_federal_cdcc",
        "ca_cdcc",
        "ca_income_tax",
    ]:
        print(f"  {variable}: {float(sim.calculate(variable, YEAR)[0]):,.2f}")

rate = CountryTaxBenefitSystem().parameters(f"{YEAR}-01-01").gov.states.ca.tax.income.credits.child_dependent_care.rate
agis = np.array([39_999.0, 40_000.0, 40_001.0, 70_000.0, 70_001.0, 100_000.0, 100_001.0, -5_000.0])
print("   AGI         ", agis.tolist())
print("   right=False ", rate.calc(agis).tolist())
print("   right=True  ", rate.calc(agis, right=True).tolist())

Output:

40000
  adjusted_gross_income: 40,000.00
  ca_federal_cdcc: 660.00
  ca_cdcc: 283.80
  ca_income_tax: 0.00
70000
  adjusted_gross_income: 70,000.00
  ca_federal_cdcc: 600.00
  ca_cdcc: 204.00
  ca_income_tax: 239.19
100000
  adjusted_gross_income: 100,000.00
  ca_federal_cdcc: 600.00
  ca_cdcc: 0.00
  ca_income_tax: 2,156.29
   AGI          [39999.0, 40000.0, 40001.0, 70000.0, 70001.0, 100000.0, 100001.0, -5000.0]
   right=False  [0.5, 0.43, 0.43, 0.34, 0.34, 0.0, 0.0, 0.5]
   right=True   [0.5, 0.5, 0.43, 0.43, 0.34, 0.34, 0.0, 0.5]

Possible fix

Call p.rate.calc(agi, right=True) on line 17. The first threshold sits at negative infinity, so the change moves only the three endpoints, and a YAML test at each of $40,000, $70,000 and $100,000 would pin them.

Lingua principale
Python
Stelle
171
Fork
220
Merge medio
4g 13h
PR unite (30g)
291

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di PolicyEngine/policyengine-us

Tutte le issue di PolicyEngine/policyengine-us

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.