Repository navigation
Fix CalEITC child counts for ITIN holders - #10322
Conversation
PR Review: Fix CalEITC child counts for ITIN holdersPR #10322 (author: MaxGhenis), head Path prefixes:
Sources read for this review (all fetched 2026-10-21):
SummaryWhat is right.
There are no critical findings and two should-address items:
There are also four suggestions: the filer identification gate (pre-existing), a parameter for the 2020 switch, end-to-end tests, and housekeeping. Status.
Critical (must fix)None. Should addressS1. The Axiom line
|
| 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.
T/earned_income/ca_eitc.yaml, ITIN child.eitc_child_count0 (NONEfails Citizen or valid EAD);ca_eitc_child_count1;ca_eitc1,000 × .34 × .85 = 289.00.- Same file, child with no ID. Counts 0 and 0;
ca_eitc1,000 × .0765 × .85 = 65.025. - 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_amounthas no separate three-child bracket, socalc(4)gives $9,537. T/earned_income/ca_eitc_child_count.yaml, 2019 ITIN child. The pre-2020 formula returns the federal count, so both counts are 0.- Same file, 2020 ITIN child.
formula_2020gives 1; the federal count is 0. - 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 failsis_eitc_qualifying_child. - 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.
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.- 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 twoca_eitc_income_boundary.yamlvectors change only the input's name.ca_eitcreads the same count, so their results can't move. CI passed them.
Vectorization and entities.
is_eitc_qualifying_childandhas_tinare Person booleans, combined with&and summed bytax_unit.suminto a TaxUnit integer.formula_2020is 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_countis read only byca_eitc. No California variable readseitc_child_countany more.ca_foster_youth_tax_creditis gated onca_eitc_eligible, and YCTC usesca_eitc > 0. Neither result changes (see S2).- The federal reforms and other states that read
eitc_child_countare 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:
- Source-conflict ratchet (Tie source-conflict markers to the register shared with Axiom #10287). The scanned roots are
variables,parametersandreforms. I ran main'sCONFLICT_COMMENT_REoverca_eitc_child_count.pyandca_eitc.py: 0 matches, including the docstring. The test YAML comments are outside the scan. CI's post-Count the FL and SD LIHEAP comments in the source-conflict ratchet baseline #10334 run passedtest_conflict_sounding_comments_do_not_growon the merge withmain. - NH Add New Hampshire state supplementation for 2026 #10156 (state-gated keys): not applicable.
ca_eitc_child_counthas nodefined_for, so its default 0 is never a missing key, and every bracket accepts any non-negative count. - Integrate modeled state unemployment insurance into income flows #9558, Document disjoint health premium inputs and correct consumer treatment #10046 and OK Add Oklahoma state supplementation for 2026 #10165: not applicable. No income-source list or wage definition changes.
- Partner tests: untouched. The Household API Partners check passed.
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 asencoded. - 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-usmain(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 commitd17a1469. That merges head05f8b82073intofec98b87c8, which ismainafter 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) andca_eitc_integration.yaml(21). - Baseline states-shard-1, batch 2/14 (
states/ca) also passed those files, plusca_eitc_eligible.yaml,ca_eitc_earned_income.yaml,ca_is_qualifying_child_for_caleitc.yamlandca_yctc.yaml(18).
- Quick Feedback selected and passed
- 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
- Position: 2 commits ahead of
main(328d1721e2) and 18 behind. The merge base is461f78e1ee. - Merge: clean.
git merge-tree --write-tree PolicyEngine/main 05f8b82073exits 0 (tree1f98231b47).- Since the merge base,
mainhas touched no file in this PR and nothing under California credits or the federal EITC.
- Siblings (note only).
- Fix EITC eligibility for married separate filers #10307 (MFS eligibility) and Apply Arizona, Arkansas and California rules for a filer who can be claimed as a dependent #10053 (California dependent-filer rules) both edit
ca_eitc_eligible.py, and each merges cleanly with this head. - Fix EITC eligibility for married separate filers #10307's CalEITC fixtures use the default Citizen SSN and
has_tin, so both counts agree there, as the PR body says.
- Fix EITC eligibility for married separate filers #10307 (MFS eligibility) and Apply Arizona, Arkansas and California rules for a filer who can be claimed as a dependent #10053 (California dependent-filer rules) both edit
0 critical, 2 should and 4 suggestions are open at this head.
Verdict: REQUEST_CHANGES
DTrim99
left a comment
There was a problem hiding this comment.
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.
|
Picking this up for the US hub. I'll post a hand-off comment here when it's ready. Generated by Claude Code |
…YCTC ca_yctc read ca_is_qualifying_child_for_caleitc, which had no SSN or ITIN test, so a child under 6 with neither number earned the full YCTC ($1,154 in 2024), and a 2019 child with only an ITIN did too. R&TC 17052.1(c) gives the YCTC qualifying child the section 17052 meaning, and FTB 3514 Line 7 bars such a child from both credits. Move the identification test into ca_is_qualifying_child_for_caleitc: the federal rule (meets_eitc_identification_requirements) before 2020, and an SSN of any kind or an ITIN (has_tin) from 2020 under 17052(p), switched by a new itin_eligible parameter. ca_eitc_child_count now sums that variable and is defined for California only, so both credits share one definition. Adds 2024 YCTC cases for a child under 6 with an SSN ($1,154), an ITIN ($1,154) and neither ($0), and a 2019 ITIN case ($0), each deriving qualifying-child status from the household. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Ready for hub review Head: What changed
Statutory basis (quoted from the review; I could not reach leginfo or ftb.ca.gov, so these are unverified by me)
Hand computations
Tests (local, one file per process)
CIPull request run 41732562938 at Judgment calls
Reply to DTrim99
Proposed follow-up issue
Generated by Claude Code |
|
Hub review in progress Head reviewed: Findings so far (the final review follows in a separate comment):
Generated by Claude Code |
|
Ready for hub review The PR reads R&TC 17052.1(c)'s "same meaning as under Section 17052" as carrying the 17052(p) identification rule into the YCTC qualifying child. The statute's cross-reference alone doesn't settle that, and the PR follows FTB 3514 Line 7, which fills the gap. Under CONTRIBUTING's source-conflict rules that is gap-filling, not a conflict, so no register entry is needed. The head hasn't moved since the hand-off. FindingsP2-1. The body has no
|
| Item | Answer | Holds? |
|---|---|---|
| S1, axiom line | The body now reads axiom: TheAxiomFoundation/rulespec-us#1861 queued, which is a valid form. The hub made this change, not a commit. |
Probably. I couldn't open rulespec-us#1861 (outside this session's repository scope), so its labels and contents are unchecked. |
| S2, YCTC identification | bc62f59ebf makes ca_is_qualifying_child_for_caleitc.py:31-47 apply the rule, and ca_eitc_child_count.py:24 is add(...) of it. |
Yes. ca_yctc.py:29-31 and ca_eitc.py:20 (via the count) now read one definition, and nothing else reads either variable. Four YCTC cases at ca_yctc.yaml:410,437,462,489. |
| G1, filer and spouse identification | Not taken; proposed as a follow-up in the hand-off. | Reasonable to leave out of scope, but the body should say so (P3-2). |
| G2, parameter | eligibility/itin_eligible.yaml: false from 2015, true from 2020, with three references. |
Yes. Branches with a scalar if; mutants M2 and M4 are killed. |
| G3, end-to-end tests | Partly. The new YCTC cases derive qualifying-child status from age and household. | Yes as far as it goes. No ITIN-filer case. |
| G4, housekeeping | defined_for = StateCode.CA at ca_eitc_child_count.py:21; "WIP plan" is gone. |
Yes. |
Checked and sound
-
The defect, at
main(6145ad4513). One Python probe per worktree. Household: a single parent aged 30 with $10,000 wages and a child aged 3, in CA.Year and child mainca_eitchead ca_eitcmainca_yctchead ca_yctc2024, SSN 1,036.932 1,036.932 1,154 1,154 2024, ITIN 200.952 1,036.932 1,154 1,154 2024, neither 200.952 200.952 1,154 0 2021, ITIN 166.822 533.102 1,000 1,000 2021, neither 166.822 166.822 1,000 0 2019, ITIN 158.53 158.53 1,000 0 2019, SSN 514.42 514.42 1,000 1,000 So both defects reproduce at
main: the CalEITC count for an ITIN child, and YCTC for a child with no number. -
Hand values, computed before running.
- 2024 cases. The YCTC amount is $1,154 and the phase-out starts at $26,626 (
young_child/amount.yaml,phase_out/start.yaml). $10,000 is below the start, so there is no reduction. That gives $1,154 for the SSN and ITIN children (each with a positive CalEITC, above) and $0 for the child with neither number. - 2019 case. YCTC
amount,ineligible_ageandloss_thresholdstart in 2021. So I checked that 2019 YCTC isn't zero for everyone: the 2019 SSN control gets $1,000. The 2019 ITINca_yctc: 0assertion therefore isn't vacuous.
- 2024 cases. The YCTC amount is $1,154 and the phase-out starts at $26,626 (
-
Every year, filing status and entity the change reaches.
ca_is_qualifying_child_for_caleitcis a Person boolean:is_eitc_qualifying_child, combined with eithermeets_eitc_identification_requirements(before 2020) orhas_tin(from 2020).- The rule is per child, so filing status doesn't enter.
- Before 2020,
ca_eitc_child_count= Σ(is_eitc_qualifying_child&meets_eitc_identification_requirements). That iseitc_child_count's formula, so pre-2020 CalEITC can't move. The 2019 rows above confirm it.
-
has_tinand ATINs.has_tinis labelled "Has TIN (ITIN or SSN)". It's input-only, defaulting toTrue, and falls back to legacyhas_itininputs.- A child with only an ATIN reaches the rule only if the input sets
has_tinfalse. Nothing separates ATINs, and the body's "Existing input limitations" says so. - From 2020 the rule ignores
ssn_card_type, so a work-valid-SSN child entered withhas_tin: falsedoesn't count. That is consistent with the variable's label.
- A child with only an ATIN reaches the rule only if the input sets
-
Readers (
grep -rnacrosspolicyengine_us, tests excluded).ca_is_qualifying_child_for_caleitc:ca_yctc.py:30andca_eitc_child_count.py:24.ca_eitc_child_count:ca_eitc.py:20.itin_eligible(CA):ca_is_qualifying_child_for_caleitc.py:37only. The DC hits are DC's own parameter.- Downstream:
ca_eitcandca_yctcfeedca/.../credits/refundable.yaml,household/state_eitcs.yamlandhousehold/state_ctcs.yaml. - No reform reads any of these. No other CA variable reads
eitc_child_countoris_eitc_qualifying_child. - No reader is made worse.
-
Tests, one per process at the head:
File Result ca_eitc.yaml5 passed ca_eitc_child_count.yaml4 passed ca_eitc_income_boundary.yaml8 passed ca_eitc_integration.yaml21 passed ca_eitc_eligible.yaml8 passed ca_is_qualifying_child_for_caleitc.yaml5 passed ca_eitc_earned_income.yaml10 passed ca_yctc.yaml22 passed federal eitc_child_count.yaml8 passed test_source_conflicts.py103 passed That is 91 YAML cases, matching the hand-off. The new tests assert the claims directly: the per-person qualifying status, the count and the dollar amount. They use no generated ranges.
-
Mutants, each run on a scratch worktree, one process per file (
ca_eitc_child_count,ca_eitc,ca_yctc), then restored with a cleangit status:Mutant ca_eitc_child_countca_eitcca_yctcM1 (hand-off): return is_child2 of 4 fail 1 of 5 fail 2 of 22 fail M2 (hand-off): itin_eligibletrue from 20151 fail pass 1 fail M3 (mine): the federal rule from 2020 too 3 fail 2 fail 1 fail M4 (mine): switch moved to 2021 1 fail pass pass M5 (mine): ca_yctcreadsis_eitc_qualifying_childpass pass 3 fail M6 (mine): ca_eitcreadseitc_child_countpass 2 fail pass All six are killed. The runner's output cut off the failing case names, so which case kills each mutant is my inference from the inputs. The cases are named after the 2019 ITIN, 2020 ITIN, 2024 neither and 2024 ITIN rows of each file.
-
Hand-off line citations (
:31-47,:24,:21,ca_yctc.yaml:410/437/462/489) match the files. -
CI. Run 41732562938 (
pull_request, headbc62f59ebf): completed, success. All 36 jobs concludedsuccess; none was skipped or cancelled. -
Scope.
- No file under
.github/ortests/policy/baseline/partners/. - The open-PR search on each changed file name finds only Fix CalEITC child counts for ITIN holders #10322.
- Apply the Maryland and Maine EITC waivers of the 32(m) SSN requirement #10527 (open) rewrites
eitc_child_count.pyto useeitc_identification_accepted. That differs frommeets_eitc_identification_requirementsonly for Maryland and Maine units with a waiver, so California's pre-2020 equivalence survives it. This is an overlap to note, not a conflict. - Apply Arizona, Arkansas and California rules for a filer who can be claimed as a dependent #10053 edits
ca_eitc_eligible.py, which this PR doesn't touch.
- No file under
-
Changelog. One top-level
fixedfragment. Its YCTC sentence matches the code.
What I couldn't check
-
Law and FTB text. leginfo.legislature.ca.gov, www.ftb.ca.gov, govinfo.gov and uscode.house.gov are all blocked by this session's network policy. So I confirmed none of these quotes:
- R&TC 17052(p), 17052.1(b)-(d) and AB 1876;
- the 2019, 2020 and 2024 FTB 3514 instructions.
The hub's quotes of FTB 3514 2020 "Expansion for Credits Eligibility" and 2024 Line 7 are consistent with the code: SSN or ITIN for qualifying children from 2020, any valid SSN, and ATIN excluded. But I haven't seen the text.
-
rulespec-us#1861. It is outside this session's repository scope, so I couldn't check its
pe-paritylabel or whether it is ready to dispatch. -
Population impact. I couldn't run it (no microdata here, and no microsimulation per the brief). See P2-1 for the check this calls for, including whether the dataset populates
has_tin.
Generated by Claude Code
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
David, thanks for the review. Here's where the PR answers each item, as of
An independent review checked S1 through G3 at 🤖 Generated with Claude Code |
The PR answers each item at 09d09a9; the comment above maps each one to its commit: #10322 (comment)
|
US + core hub merge audit, us#10322 at
🤖 Generated with Claude Code |
us-ca-caleitc-itin-children
Source: R&TC §17052(p), which AB 1876 (Stats. 2020, ch. 87, §1) added, substitutes "federal individual taxpayer identification number or a social security number" for "social security number" in IRC 32(m) for taxable years beginning on or after January 1, 2020. The FTB applies that rule to qualifying children in FTB 3514's 2020 instructions, Step 1 question 3 and Line 7, and again in the 2024 instructions.
Change:
ca_is_qualifying_child_for_caleitcnow applies California's identification rule: before 2020 the federal per-child rule (meets_eitc_identification_requirements), from 2020 an SSN of any kind or an ITIN (has_tin). The new boolean parametergov.states.ca.tax.income.credits.earned_income.eligibility.itin_eligible(false from 2015, true from 2020) switches between them.ca_eitc_child_countsums that variable (so before 2020 it equalseitc_child_count), and CalEITC uses it throughout the California schedule calculation. The young child tax credit reads the same variable, so a child under 6 with neither an SSN nor an ITIN no longer earns it. Under R&TC 17052.1(c), the credit's qualifying child has "the same meaning as under Section 17052", and FTB 3514 Line 7 tells filers they cannot count a child without an SSN or federal ITIN for either credit. Existing schedule fixtures now supply the California count. Federal child counting, credit parameters, andca_eitc_eligible.pyremain outside this change. The #10307 fixtures 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. The model computes these amounts from its formula; the agency tables use income bins.
Years: CalEITC child counts change from 2020. The young child tax credit changes in every year. Before 2020 a child under 6 needs a work-valid SSN, and from 2020 an SSN or ITIN, so a child without the required number no longer earns it (a 2019 ITIN child: $1,000 → $0). Direct child-count tests cover the 2019/2020 transition. Dollar witnesses use 2024 because several existing California schedule parameters begin in 2021, and this identification fix leaves the historical schedules unchanged.
Existing input limitations:
has_tindoes not separately model expiration/revocation, acquisition timing, ATINs, or the instructions' deceased-newborn exception. We found no competing defensible reading of the statute for the ITIN expansion.Follow-up (not in this PR):
ca_eitc_eligibledoesn't apply the identification test to the filer and spouse (FTB 3514 Step 1), which requires a work-valid SSN before 2020 and an SSN or ITIN from 2020. A later PR can gate it onfiler_has_tinanditin_eligible, as PE-US does for Colorado, Illinois, DC and Washington.Validation
make format(Ruff formatting and lint) andgit diff --checkpassed.After review (at
bc62f59ebf, which mergesmain), 91 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: 22 passed. New cases derive the child's status from the household: 2024 SSN $1,154, 2024 ITIN $1,154, 2024 neither $0, 2019 ITIN $0.test_source_conflicts.py: 103 passed.The runs cover the whole California earned-income test folder, the federal child-count regression, and the downstream young child tax credit file.
Microsimulation impact
We compared
mainat the merge base6145ad4513with this head,09d09a9035, on the default dataset for 2026. We estimate that the branch raises CalEITC (ca_eitc) by $118.65m and cuts state income tax by the same amount, so household net income rises by $118.65m. Federal income tax, benefits and the young child tax credit don't change.ssn_card_typebut nothas_tin, sohas_tinreturns true for everyone. From 2020, CalEITC then counts every qualifying child, including children whosessn_card_type(NONE or OTHER_NON_CITIZEN) fails the federal identification test thatmainapplies througheitc_child_count.maincounts qualifying children for the credit without an identification test. This branch requires an SSN or ITIN from 2020, andhas_tinreturns true for every child in the data, so no family loses the credit.maintotal, 2026ca_eitcca_yctcincome_taxstate_income_taxhousehold_net_income(households)household_benefitsimpact: on the default dataset in 2026, CalEITC rises by $118.65m for 23 tax units (174,130 weighted), and state income tax falls by the same amount. The young child tax credit, federal income tax and benefits don't change.
axiom: TheAxiomFoundation/rulespec-us#1861 queued
🤖 Generated with Claude Code