Skip to content

Fix CalEITC child counts for ITIN holders - #10322

Open
MaxGhenis wants to merge 2 commits into
mainfrom
statute-bugs-ca-caleitc-itin-children
Open

MaxGhenis wants to merge 2 commits into
mainfrom
statute-bugs-ca-caleitc-itin-children

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

WIP plan

  • Commit CalEITC regressions for ITIN qualifying children before changing the model.
  • Add a California-specific child count: preserve the federal count before 2020; from 2020 count otherwise qualifying children with an SSN or ITIN.
  • Use that count for all CalEITC schedule lookups. Keep the change confined to children's identification requirements so it combines with the separate-filer eligibility work in Fix EITC eligibility for married separate filers #10307.
  • Run affected California YAML files individually and the federal child-count regression. No microsimulation; impact is deferred to the hub.

us-ca-caleitc-itin-children

Source: AB 1876, Stats. 2020, ch. 87, §1, R&TC §17052(p) permits an ITIN or SSN beginning January 1, 2020. FTB 3514 (2020), Step 1 question 3 and Line 7 expressly applies the identification rule to qualifying children; 2024 instructions corroborate it.

Change: Adds ca_eitc_child_count and uses it throughout the California schedule calculation. From 2020, count is_eitc_qualifying_child & has_tin; before 2020, retain eitc_child_count. Existing schedule fixtures now supply the California count. Federal child counting, credit parameters, and ca_eitc_eligible.py remain outside this change. Reviewed the #10307 fixtures for compatibility; they need no changes.

Witness: In 2024, an otherwise eligible family with $1,000 earned income and federal AGI and one ITIN qualifying child has federal child count 0 and California child count 1. The continuous formula gives $1,000 × .34 × .85 = $289 instead of $1,000 × .0765 × .85 = $65.025, a $223.975 increase. These are model formula amounts; the agency tables use income bins.

Years: 2020 onward. Direct child-count tests cover the 2019/2020 transition. Dollar witnesses use 2024 because several existing California schedule parameters begin in 2021; historical schedule completion is outside this identification-only fix.

Existing input limitations: has_tin does not separately model expiration/revocation, acquisition timing, ATINs, or the instructions' deceased-newborn exception. No competing defensible statutory reading was found for the ITIN expansion.

Validation

make format (Ruff formatting and lint) and git diff --check passed.

87 cases passed across nine individual YAML files:

  • ca_eitc_child_count.yaml: 4 passed.
  • ca_eitc.yaml: 5 passed.
  • ca_eitc_integration.yaml: 21 passed.
  • ca_eitc_income_boundary.yaml: 8 passed.
  • ca_eitc_eligible.yaml: 8 passed.
  • ca_is_qualifying_child_for_caleitc.yaml: 5 passed.
  • ca_eitc_earned_income.yaml: 10 passed.
  • eitc_child_count.yaml: 8 passed.
  • ca_yctc.yaml: 18 passed.

This covers the complete affected California earned-income test folder, the federal child-count regression, and the downstream California young-child credit file. Each YAML file ran sequentially in a separate foreground process with all numerical thread caps set to 4. No microsimulation; the hub runs impact.

axiom: TheAxiomFoundation/rulespec-us#1861 queued. The statutory identification rule is unencoded; historical companions need corpus ingestion, and existing FTB form sources need a release re-pin before signed encoder dispatch.

@MaxGhenis
MaxGhenis marked this pull request as ready for review October 21, 2026 01:52
@MaxGhenis MaxGhenis closed this Oct 21, 2026
@MaxGhenis MaxGhenis reopened this Oct 21, 2026
@DTrim99

DTrim99 commented Oct 21, 2026

Copy link
Copy Markdown
Collaborator

PR Review: Fix CalEITC child counts for ITIN holders

PR #10322 (author: MaxGhenis), head 05f8b82073. This is a first review. The PR adds ca_eitc_child_count, which keeps the federal EITC child count before 2020. From 2020 it counts every otherwise qualifying child with an SSN or ITIN. ca_eitc now reads that count for every schedule lookup. Four existing CalEITC fixtures switch their input from eitc_child_count to ca_eitc_child_count, and the PR adds seven new cases and a changelog fragment. The PR has no comments or reviews yet. It touches no partner test file.

Path prefixes:

  • V/ = policyengine_us/variables/gov/states/ca/tax/income/credits/
  • T/ = policyengine_us/tests/policy/baseline/gov/states/ca/tax/income/credits/

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

Summary

What is right.

  • The law. §17052(p) applies "for each taxable year beginning on or after January 1, 2020". It modifies IRC 32(m), which sets the identification rule for both the filer (32(c)(1)(E)) and each qualifying child (32(c)(3)(D)), in two ways:
    • (p)(1) deletes the exclusion for benefits-only SSNs;
    • (p)(2) substitutes "federal individual taxpayer identification number or a social security number" for "social security number".
  • What FTB says. The 2020 and 2024 instructions (Line 7) say: "The child must have a valid SSN or ITIN". A valid SSN is one "issued by the Social Security Administration without regard to whether it was issued for employment or issued solely for the purpose of receiving federally funded benefits." The 2019 instructions say: "An Individual Taxpayer Identification Number (ITIN) or Adoption Taxpayer Identification Number (ATIN) cannot be used to claim EITC."
  • The count follows that law in every year.
    • Before 2020: the count is the federal eitc_child_count (Citizen or valid-EAD SSN).
    • From 2020: the count is is_eitc_qualifying_child & has_tin, which accepts any SSN or ITIN.
    • No federal gate. is_eitc_qualifying_child is the qualifying-child test before identification: the IRC 152(c) age, disability and relationship tests. So the PR applies California's identification rule exactly once and doesn't import the federal SSN gate from 2020.
  • The PR body's witness is right. In 2024, with one ITIN child and $1,000 of earnings, the credit is $1,000 × .34 × .85 = $289 instead of $65.025.
  • Tests. I hand-checked 17 expectations, plus traces for the ITIN-filer and YCTC cases. CI passed every affected file on the merge with main.
  • Batch checks. The PR passes the source-conflict ratchet. It has no state-gated parameter key and changes no income-source list.

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

  • S1. Invalid Axiom line. axiom: pending: hub files parity is not an allowed form. It's the same form we flagged on Correct Minnesota UI taxable wage bases for 2014-2026 #10319. rulespec-us doesn't encode §17052(p), and no open issue covers it.
  • S2. YCTC still applies no identification rule to its young child. ca_yctc reads ca_is_qualifying_child_for_caleitc, which has no SSN/ITIN test. So a child under 6 with neither number still earns the full YCTC ($1,154 in 2024). FTB says that child "cannot" count "in figuring the EITC or YCTC". This is pre-existing, but the PR now leaves two different definitions of a CalEITC qualifying child.

There are also four suggestions: the filer identification gate (pre-existing), a parameter for the 2020 switch, end-to-end tests, and housekeeping.

Status.

  • CI: 27 checks pass and 3 are skipped (the superseded 2026-10-20 run). None is pending or failed.
  • Branch: 2 commits ahead of main and 18 behind, and it merges cleanly.

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.
  • Why n/a doesn't fit: §17052(p) is statutory, and the PR changes CalEITC for every California family with an ITIN child, or a child whose SSN is not valid for work, from 2020 on.
  • Why encoded-correct isn't available:
    • rulespec-us main (5796861e58) has us-ca/statutes/rtc/17052.yaml. Its only ITIN rules are the two §17052(q) documentation judgments, so it has no §17052(p) modification of 32(m).
    • qualifying_child_count_category is a deferred_outputs entry, and the final credit is deferred too.
  • No existing issue covers (p).
  • Severity: should. An invalid Axiom line is a merge blocker, not a model error.
  • Fix: file an open, pe-parity-labelled, dispatch-ready issue in TheAxiomFoundation/rulespec-us, modelled on MO Person Level Tax Calculation #1420 or Add AMT parameters for 2020-2023 #1467. Then change the line to axiom: TheAxiomFoundation/rulespec-us#<n> queued. Alternatively, run the signed encoder and cite the PR as encoded. The issue needs:
    • Target module: an ordinary replacement of us-ca/statutes/rtc/17052.yaml that adds the (p) modification. It should feed the qualifying-child count that is now deferred, keeping the existing (q) judgments.
    • Corpus citation: us-ca/statute/rtc/17052, subdivision (p).
    • Verbatim law: (p) as quoted under Summary, including both paragraphs.
    • Required outputs: per child, whether the California identification rule is met; per return, the number of qualifying children counted under 32(b), as modified.
    • Companion tests from FTB, not from PolicyEngine output:
      • Line 7 of the 2020 and 2024 instructions supplies the identification cases: an ITIN child counts from 2020; a benefits-only SSN counts from 2020; a child with neither number does not count.
      • Line 7 of the 2019 instructions supplies the pre-2020 case: an ITIN child does not count.
      • The 2024 FTB 3514 table row for $951 to $1,000 supplies the amounts. It gives $63 with no counted child, $282 with one, $332 with two and $373 with three or more. These are the filed-form table amounts, so use them, not PE's continuous $289, $65.025 and $382.50.
    • Why queued: the blocker, such as corpus scope, the signed release or approval for a billed run.

S2. YCTC still counts a young child who has no SSN or ITIN

  • Where: V/young_child/ca_yctc.py:28-32 reads ca_is_qualifying_child_for_caleitc. V/earned_income/ca_is_qualifying_child_for_caleitc.py:22 returns is_eitc_qualifying_child, which has no identification test. The new V/earned_income/ca_eitc_child_count.py:25-29 adds has_tin, but only to the CalEITC count.
  • The law:
    • Statute. §17052.1(b)(1) requires "at least one qualifying child". Under §17052.1(c), "'Qualifying child' shall have the same meaning as under Section 17052", except for the under-6 age limit.
    • FTB 2024, Step 8: "You have at least one qualifying child for the California EITC."
    • FTB 2024, Line 7: "if a child did not have an SSN or federal ITIN ... you cannot count that child as a qualifying child in figuring the EITC or YCTC". The 2020 instructions say the same.
    • Before 2020. The 2019 Step 8 has the same "qualifying child for the California EITC" test, and the 2019 Line 7 rejects ITINs.
    • Statute vs FTB. The statute's cross-reference alone does not settle whether 32(c)(3)(D) is part of the "meaning" of a qualifying child. FTB settles that question explicitly for YCTC, and §17052.1(d)(1) authorizes FTB guidance.
  • Trace at the head (2024). A single parent aged 30 has $10,000 of wages and a child aged 3 with ssn_card_type: NONE and has_tin: false.
    • ca_eitc_child_count is 0, so CalEITC uses the childless schedule. That is correct.
    • The childless credit is positive, as it is everywhere below $31,951; the PR's boundary test shows $0.009155 even at $31,950. So gets_caleitc is true.
    • The child passes ca_is_qualifying_child_for_caleitc and the under-6 test, so YCTC = $1,154. The $10,000 of earnings is below the $26,626 phase-out start. Under Line 7 it should be $0.
    • 2019. For a 2019 child with only an ITIN, the model also pays YCTC, but the 2019 instructions deny it.
  • What the PR changes: nothing in YCTC's results. Every CalEITC schedule stays positive up to the same $31,950 limit, so ca_eitc > 0 has the same sign at any child count. The defect is on main already.
  • Why it belongs here:
    • Two definitions. The PR creates a California identification rule but leaves ca_is_qualifying_child_for_caleitc without it. Its label is "Child qualifies for CalEITC", yet CalEITC doesn't use it, and the one credit that does (YCTC) skips the rule.
    • Misleading PR body. The body lists ca_yctc.yaml as covering "the downstream California young-child credit". Those 18 cases set ca_is_qualifying_child_for_caleitc directly, so they cannot exercise the identification rule.
  • Severity: should. It's a wrong YCTC result against FTB's instructions, but in a credit the PR doesn't claim to change.
  • Fix: use one California per-person test for both credits.
    • Give ca_is_qualifying_child_for_caleitc a pre-2020 formula, is_eitc_qualifying_child & meets_eitc_identification_requirements, and a 2020 formula, is_eitc_qualifying_child & has_tin. Or switch with the parameter from G2.
    • Make ca_eitc_child_count the tax_unit.sum of that variable.
    • ca_yctc then needs no change. Its existing YAML inputs the variable directly, and the existing ca_is_qualifying_child_for_caleitc.yaml cases use the default Citizen SSN and has_tin: true, so none of them move.
    • Add YCTC cases for a child under 6:
      • 2024 with an ITIN: $1,154.
      • 2024 with neither number: $0.
      • 2019 with an ITIN: $0.
    • If you'd rather keep this PR narrow, file a follow-up issue and note the deferral in the PR body.

Suggestions

G1. CalEITC has no filer or spouse identification test (pre-existing)

  • Where: V/earned_income/ca_eitc_eligible.py checks age, investment income and AGI only.
  • The law.
    • Before 2020: FTB 3514 Step 1 required a work-valid SSN for the filer and spouse (2019: "have a social security number (SSN) that allows you to work and is valid for EITC purposes?").
    • From 2020: it requires an SSN or ITIN (2024 Step 1: "If No, stop here, you cannot take the credit").
  • The head:
    • Trace. An ITIN filer with an SSN child gets the one-child schedule in every year. ca_eitc_child_count doesn't depend on the filer, and nothing checks the filer's ID. That is correct from 2020 and wrong before.
    • A filer with neither number gets CalEITC in any year.
    • Other states. The CO, IL, DC and WA credits each apply filer_has_tin.
  • Fix (optional, separate PR): add a year-dependent filer and spouse gate in ca_eitc_eligible, or open an issue for it. It doesn't touch this PR's child count. The PR body says it scoped this out.

G2. A parameter for the 2020 switch

  • formula_2020 writes the effective date into the variable. The DC fix in Gate the DC EITC ITIN extension to 2023 and apply the IRC 152(c)(2) relationship test to EITC qualifying children #9643 put the same rule in a boolean parameter, gov.states.dc.tax.income.credits.eitc.itin_eligible (false from 2015, true from 2023, with references). The model-development guidance uses a boolean parameter when a rule's structure changes on a date.
  • Fix (optional): add gov.states.ca.tax.income.credits.earned_income.itin_eligible (false from 2015-01-01, true from 2020-01-01), citing §17052(p) and AB 1876. Branch on it with a scalar if. This lets a reform turn the ITIN extension off, and S2's fix could reuse it.

G3. End-to-end tests that derive qualifying-child status

  • Every new case supplies is_eitc_qualifying_child, and the dollar cases also supply ca_eitc_eligible. So no new case would catch a later refactor that put the federal SSN test back into is_eitc_qualifying_child.
  • Fix (optional): add one or two cases that derive both from age, is_tax_unit_dependent and wages:
    • an ITIN filer with an SSN child;
    • an SSN filer with an ITIN child under 6, asserting ca_eitc_child_count, ca_eitc and ca_yctc.
    • Put two tax units in one case (an ITIN child and a no-ID child) to show the count vectorizes across units.

G4. Housekeeping

  • ca_eitc_child_count has no defined_for = StateCode.CA, unlike the neighbouring California variables. That's harmless, since ca_eitc is gated by ca_eitc_eligible, but it's inconsistent.
  • The PR body still opens with "WIP plan", although every item is ticked and the PR is not a draft.

Verified correct

  • Statute and dates. AB 1876 §1 ("Section 17052 of the Revenue and Taxation Code is amended to read") added (p), effective for taxable years beginning on or after January 1, 2020. The current §17052 keeps (p) unchanged after the 2026 amendment (SB 1435). formula_2020 starts on 2020-01-01.

  • Identification types at the head:

    Child eitc_child_count ca_eitc_child_count, 2020+ Law, 2020+
    Citizen or valid-EAD SSN counted counted counted
    SSN not valid for work (OTHER_NON_CITIZEN) not counted counted counted ((p)(1); Line 7 "without regard to whether it was issued for employment")
    ITIN only (NONE, has_tin true) not counted counted counted ((p)(2))
    No SSN or ITIN (has_tin false) not counted not counted not counted (Line 7)

    Before 2020 the CA count equals the federal count, which matches the 2019 instructions.

  • Hand-checks (17 expectations). Unless noted, the dollar cases are 2024, with ca_eitc_eligible supplied and earned income and AGI of $1,000. That is below every 2024 phase-in end ($4,525 with no children, $6,794 with one, $9,537 with two or more) and every phase-out start, so the credit is earnings × rate × .85.

    1. T/earned_income/ca_eitc.yaml, ITIN child. eitc_child_count 0 (NONE fails Citizen or valid EAD); ca_eitc_child_count 1; ca_eitc 1,000 × .34 × .85 = 289.00.
    2. Same file, child with no ID. Counts 0 and 0; ca_eitc 1,000 × .0765 × .85 = 65.025.
    3. Same file, four ITIN children. Counts 0 and 4. calc(4) lands in the 3+ bracket, so 1,000 × .45 × .85 = 382.50. earned_income_amount has no separate three-child bracket, so calc(4) gives $9,537.
    4. T/earned_income/ca_eitc_child_count.yaml, 2019 ITIN child. The pre-2020 formula returns the federal count, so both counts are 0.
    5. Same file, 2020 ITIN child. formula_2020 gives 1; the federal count is 0.
    6. Same file, 2024 mixed family. The federal count is 1 (SSN child). The CA count is 2 (SSN and ITIN children). The child with no ID fails has_tin, and the 25-year-old fails is_eitc_qualifying_child.
    7. Same file, 2024 child whose SSN isn't valid for work. The federal count is 0 and the CA count is 1, as §17052(p)(1) requires.
    8. T/earned_income/ca_eitc_integration.yaml, 2022, one child, $6,400 (input renamed only). The phase-in amount is 6,379 × .289 = 1,843.53, less (6,400 − 6,379) × .289 = 6.07, giving 1,837.46. That is within ±6 of 1,843.
    9. Same file, 2022, three children, $8,000. 8,000 × .3825 = 3,060, within ±20 of 3,051 (phase-in end $8,954).
    • Other renamed fixtures. The ca_eitc.yaml $20,500 case and the two ca_eitc_income_boundary.yaml vectors change only the input's name. ca_eitc reads the same count, so their results can't move. CI passed them.
  • Vectorization and entities.

    • is_eitc_qualifying_child and has_tin are Person booleans, combined with & and summed by tax_unit.sum into a TaxUnit integer.
    • formula_2020 is a period dispatch, not a branch on arrays.
    • The boundary test supplies ca_eitc_child_count: [0, 1, 2, 3] across four tax units.
  • Callers.

    • ca_eitc_child_count is read only by ca_eitc. No California variable reads eitc_child_count any more.
    • ca_foster_youth_tax_credit is gated on ca_eitc_eligible, and YCTC uses ca_eitc > 0. Neither result changes (see S2).
    • The federal reforms and other states that read eitc_child_count are untouched.
  • References. V/earned_income/ca_eitc_child_count.py:15-20 cites AB 1876 §1 and the 2020 FTB 3514 instructions. Both are single HTML sources and both corroborate: (p), and Step 1 question 3 ("have a qualifying child who has a valid SSN or federal ITIN?") together with Line 7.

  • Changelog. changelog.d/statute-bugs-ca-caleitc-itin-children.fixed.md is a top-level fragment, and fixed is the right type.

  • Batch lessons:

Axiom line assessment

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

  • Recommended form: axiom: TheAxiomFoundation/rulespec-us#<n> queued, with a new open, pe-parity-labelled, dispatch-ready issue for §17052(p)'s identification rule as it applies to qualifying children. The required contents are listed under S1. Alternatively, cite an encoder PR as encoded.
  • Not n/a. This is a statutory provision, and the PR changes CalEITC amounts for families with ITIN children from 2020.
  • Not encoded-correct. rulespec-us main (5796861e58) encodes only §17052(q)'s ITIN documentation duties and defers the qualifying-child count. No open issue covers (p).

CI status

27 pass, 3 skipping, 0 pending, 0 failed. I re-checked gh pr checks 10322 at the end of this review.

  • The green run. Run 39608243078 (pull_request, created 2026-10-21 13:28 UTC) tested merge commit d17a1469. That merges head 05f8b82073 into fec98b87c8, which is main after Count the FL and SD LIHEAP comments in the source-conflict ratchet baseline #10334.
  • Where the California tests ran.
    • Quick Feedback selected and passed ca_eitc.yaml (5), ca_eitc_child_count.yaml (4), ca_eitc_income_boundary.yaml (8) and ca_eitc_integration.yaml (21).
    • Baseline states-shard-1, batch 2/14 (states/ca) also passed those files, plus ca_eitc_eligible.yaml, ca_eitc_earned_income.yaml, ca_is_qualifying_child_for_caleitc.yaml and ca_yctc.yaml (18).
  • Guards. Rest (Python, shard-1 + variables) passed test_source_conflicts.py.
  • Earlier runs.
    • The skipped checks are the umbrella jobs of run 39506324946 (2026-10-20 22:12 UTC).
    • The failed run. Run 39529786819 (2026-10-21 01:52 UTC) failed only test_conflict_sounding_comments_do_not_grow, and every file it listed was an FL/SD LIHEAP file. That is the known main-caused failure that Count the FL and SD LIHEAP comments in the source-conflict ratchet baseline #10334 fixed, and the green run superseded it. It is not a finding.
  • Locally: I ran no tests or model probes. CI is green at the current head. Every expectation and the S2 and G1 traces were checked by hand from the code and parameters.

Branch status

0 critical, 2 should and 4 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.

The CalEITC count is right. From TY2020, R&TC 17052(p) accepts an SSN or ITIN for qualifying children, and before 2020 the federal rule stays; all 17 expectations hand-check. Two should-address items: (1) the 'pending: hub files parity' axiom line is invalid, so please file a pe-parity issue for 17052(p) and mark it queued; (2) ca_yctc still reads a qualifying-child variable with no SSN/ITIN test, so a child under 6 with no number gets YCTC ($1,154 in 2024) where FTB says $0. It's pre-existing, but the PR now leaves two definitions; put the ID test in the shared variable. Four 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.

2 participants