Repository navigation
Apply North Carolina Work First's 27.5% earnings exclusion and $25 minimum payment - #10260
Conversation
…nimum payment North Carolina excludes 27.5% of gross earned income and does not count children's earnings (TANF State Plan, Financial Rules 3 and 6), and pays a family when the payment, 50% of the difference between countable income and the need standard, is $25 or more (Financial Rules 8). PE counted all earnings and required $25 of the reduced need standard per household member. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #10260 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 4 3 -1
Lines 76 54 -22
Branches 2 0 -2
=========================================
- Hits 76 54 -22
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PR Review: Apply North Carolina Work First's 27.5% earnings exclusion and $25 minimum paymentSummaryThe PR fixes two errors in North Carolina Work First (#10210):
It also recomputes 7 integration cases, 3 earned-income cases and 4 partner fixtures, adds 2 + 4 + 2 cases, and adds a
Three things need fixing:
Critical (must fix)None. Should address1. The partner contract test edits need Ziming Hua's three-question sign-off before merge. The PR changes
At head The edits look right to me (see "Verified correct"), but the sign-off is Ziming's, not the reviewer's. The changed cases for the comment are:
The file's header comment also changes. Partner impact: NC Work First amounts rise for every earner (each dollar of earnings now cuts the benefit by $0.3625, not $0.50). The size-3 cliff moves from $5,628 to $8,176 a year of earnings. Fix:
2. The new exclusion carries out half of Financial Rules 3. SSI recipients' earnings still count, and the 18-year-old test presents an approximation as the rule.
The two parts of this finding: (a) SSI recipients' earnings. The formula still counts 72.5% of an SSI recipient's earnings, although
(b) The 18-year-old test (
PolicyEngine includes every non-SSI member in the need standard, so counting their earnings is a consistent approximation. But the test name and comment state it as North Carolina's rule. Fix (either):
3. Add the The body (head
Suggestions
Verified correct
Axiom line assessmentThe line is missing (Should 3), and
Recommended line. File a dispatch-ready
CI statusAll 30 checks pass at
None is pending or failing. The "Partner API impact notice" workflow also ran and posted its Slack alert (see Should 1). Branch statusThe branch is 2 commits ahead of main (the change on 2026-10-16 and a merge of main on 2026-10-23) and 48 behind.
Verdict: REQUEST_CHANGES |
DTrim99
left a comment
There was a problem hiding this comment.
The law is right in every year (the State Plans, Financial Rules 6 and 8, and 10A NCAC 71W .0601(a)), the 50% payment formula matches, and all 27 expectations hand-check. Three should-address items: (1) the PR edits partners/analytics_coverage/.../nc/tanf.yaml (4 fixtures, 2 inputs) without @hua7450 as reviewer, and under CLAUDE.md his approval of a head with those edits is needed before merge; (2) Financial Rules 3-4 and 71W .0408(a) exclude SSI recipients' income, but an SSI parent's earnings still count ($91 vs $236/month); (3) there's no axiom line. Four suggestions. Full report in the comment above.
State Plan Financial Rules 3 and 4, 10A NCAC 71W .0408(a)(1) and the WF-114 income chart exclude all income of SSI recipients. The household size already drops them; the earned and unearned income variables now drop their income too, with the same ssi/receives_ssi check. Rename the 18-year-old earnings test so that it describes the PolicyEngine approximation, add SSI cases, cite 10A NCAC 71W .0601(a) and the 2019-2022 State Plan, and fix the 2016-2019 payment anchor. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks @DTrim99. New head: Should address1. Partner contract test edits: review requested from @hua7450. @hua7450, this PR edits
The file's header comment also changes to describe the 27.5% exclusion and the $25 payment test.
Before merge, Ziming, please answer:
This PR will not merge until you approve a head that contains these edits. 2. SSI recipients' income: fixed with option (a).
No partner fixture changes because of this commit. 3. I filed TheAxiomFoundation/rulespec-us#1947 ( Suggestions
Tests at
|
PR Review (round 2): Apply North Carolina Work First's 27.5% earnings exclusion and $25 minimum paymentSummaryRound 1 (head
One new problem came in with the unearned-income change, and it is critical. The commit also drops child support that an SSI-recipient parent receives. North Carolina treats child support as income of the dependent child, so support that an SSI parent receives for a child in the unit still counts.
CI has 34 passing checks and 2 failing. Both failures come from the main-caused Montana AGI test, which #10496 fixes. The merge with main is clean. Prior findings
New findingsCritical (must fix)1. This head no longer counts child support that an SSI-recipient parent receives for a child in the unit.
child_support = person("child_support_received", period)
...
countable_child_support = spm_unit.sum(
where(is_ssi_recipient, 0, child_support)
)The new test North Carolina counts child support as the child's income, not the income of the parent who receives it:
These sources exclude the SSI recipient's own income:
Child support paid for a non-SSI child in the unit is that child's income, and (a)(2) counts it. No source conflict is involved, because all three sources agree.
Example: 2024, a unit not enrolled in TANF. A single parent receives SSI and has one child aged 5. The parent receives $300 a month of child support.
This head pays $1,800 a year too much, and main gets it right. In the PR's own test, the rule gives 1,200 + 500 + 1,000 = 2,700. Fix:
Should addressNone. Suggestions
Verified correct
Axiom line assessmentValid. The line is
CI statusAt
This PR doesn't touch Montana AGI, so this is a CI note, not a finding. Merge main and re-run once #10496 lands. All the jobs that exercise this PR pass: Baseline states shards 1-4, Household API Partners, PR validation (lock, guard tests, lint, changelog), Quick Feedback, Microsimulation, and codecov patch and project. Branch statusThe branch is 3 commits ahead of main (the original change, a merge of main on 2026-10-23, and the SSI commit) and 70 behind.
Verdict: REQUEST_CHANGES |
DTrim99
left a comment
There was a problem hiding this comment.
Requesting changes, round 2: 1 critical, 0 should. All round-1 items are handled. The new commit also stops counting child support an SSI-recipient parent receives for a child in the unit, which WF-114 XII and 10A NCAC 71W .0408(a)(2) count as the child's income ($1,800/yr overpayment in the report's example; the new test pins 1,700 where the rule gives 2,700). The partner-test edits still need Ziming's approval before merge. Full report in the comment above.
WF-114 section XII and 10A NCAC 71W .0408(a)(2) count child support as the dependent child's income. The SSI exclusion now removes only the SSI recipient's own unearned income, and child support only when an SSI-recipient child receives it. The unearned test now expects 2,700, and new cases pin the SSI-parent and SSI-child child-support paths. Also cite the ACF-approved 2019-2022 State Plan in payment_percentage. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks @DTrim99. Round-2 fixes are in Critical 1, child support received by an SSI-recipient parent: fixed.
Suggestion 1: done. Partner fixtures. This commit changes no partner file, and all 32 cases in the 10 NC partner files pass at Local tests at |
PR Review (round 3): Apply North Carolina Work First's 27.5% earnings exclusion and $25 minimum paymentSummaryRound 2 (head
No new critical or should findings. One optional suggestion: record how child support is attributed to members. CI at the last check: 27 passing, 2 failing and 7 still pending (the Contrib shards and Microsimulation). Neither failure comes from this PR. policyengine-core 3.33.13, released today, breaks a Social Security test in the Rest Python shard 3 job, and main's own push run fails the same test. The Montana AGI failure from round 2 is gone, because #10496 has merged and CI tests the PR merged with main. Every job that runs the NC Work First tests passed. The merge with main is clean, and main hasn't changed any NC Work First file since the merge base. Merge gate: the PR still edits the NC partner fixtures, and @hua7450 hasn't reviewed yet. Under CLAUDE.md the PR can't merge until he approves a head that contains those edits. This approval doesn't clear that gate. Prior findings
New findingsCritical (must fix)None. Should addressNone. Suggestions
Verified correct
Axiom line assessmentValid. The line is
CI statusAt
Branch statusThe branch is 4 commits ahead of main (the original change, a merge of main on 2026-10-23, the round-2 SSI commit and this commit) and 80 behind.
Verdict: APPROVE |
DTrim99
left a comment
There was a problem hiding this comment.
Approving round 3: 0 critical, 0 should. The child support fix is correct. Full report in the comment above. Merge gate: the partner fixture edits still need @hua7450's approval of a head that contains them; this approval doesn't clear that. CI note: the Rest shard 3 failure (test_social_security_input_state_machine, NameError 'operator' under policyengine-core 3.33.13) also fails on main's own push run.
hua7450
left a comment
There was a problem hiding this comment.
Approved at c711e7034b for the fixes in #10210. The 27.5% earnings exclusion, exclusion of ordinary dependent children's earnings, and $25 minimum applied to the calculated family payment correctly address the reported problems. The SSI-income exclusion and latest child-support correction also handle the reviewed ordinary cases correctly.
Validation: all 40 existing tests in the four changed non-partner NC test files passed locally. Both original issue examples match the expected results: $1,586.70/year for the parent with five children and $7,176 annual earnings, and $54.50/month for the parent with two children and $600 monthly earnings.
The broader child-status and assistance-unit cases belong in the #10492 follow-up. Please explicitly include emancipated minor parents: the new age-only filter exempts their earnings, although Work First treats them as adults. This newly affected case is being deferred to that follow-up as discussed.
The partner-test communication requirements remain as documented in the existing PR discussion.
Summary
North Carolina Work First had three errors.
nc_tanf_countable_earned_incomeadded every member's gross earnings. The TANF State Plan FFY 2026-2028 Financial Rules has two rules here, and the 2022-2025, 2019-2022 and 2016-2019 plans have the same wording. Rule 6 says "27.5% of gross earned income is excluded". Rule 3 says all income is counted "except the earnings of children, and the income of SSI recipients". The Work First Manual, section 114 I also says "Do not count a child's earned income". The variable now excludes earnings of members under the program's child age limit (18) and of SSI recipients, and then excludes 27.5% of the rest. The rate is a new parameter,gov.states.nc.ncdhhs.tanf.income.earned_income_exclusion_rate.nc_tanf_household_sizealready drops them from the need standard.nc_tanf_countable_earned_incomeandnc_tanf_countable_gross_unearned_incomenow drop their earnings and unearned income, with the samessi > 0 | receives_ssicheck. Child support still counts when an SSI-recipient parent receives it, because WF-114 section XII and 71W .0408(a)(2) treat it as the dependent child's income; only an SSI-recipient child's own child support is excluded.nc_tanf_income_eligibledivided the reduced need standard by the household size and required $25 a month per person. Financial Rules 8 (FFY 2026-2028, p. 19) says "A family remains eligible if the result of the payment calculation is twenty-five dollars ($25.00) or more", and 10A NCAC 71W .0601(a) says payments "shall not be made for less than twenty five dollars ($25.00)". The payment is 50% of the difference between countable income and the need standard. The test is now0.5 × reduced need standard ≥ $25 a month, with no division by household size. The existinghousehold_size > 0guard stays.Tests
nc_tanf_countable_earned_income.yaml: three existing cases now expect 72.5% of earnings ($1,000 gives $725, $500 gives $362.50). New cases: a 16-year-old's earnings are excluded (6,000 × 0.725 = $4,350); an 18-year-old not in high school has earnings counted ($2,175, the PolicyEngine approximation; see North Carolina Work First: non-parent adults, 18-year-olds in high school, and all-SSI children #10492); an SSI-recipient parent's $4,800 is excluded and the other parent's $2,000 counts ($1,450).nc_tanf_countable_gross_unearned_income.yaml: an SSI-recipient parent's $6,000 of Social Security is excluded, and the $1,000 of child support they receive for the child counts with the other parent's $1,200 pension and $500 of child support ($2,700). Child support that an SSI-recipient child receives is excluded ($1,800).nc_tanf_income_eligible.yaml: a size-6 unit with a $50 payment is eligible (main: 100 / 6 < 25, ineligible). A size-1 unit with a $20 payment is ineligible (main: eligible). Two controls test exactly $25 (eligible) and $24.50 (ineligible).integration.yaml: the issue's case is a parent of five with $7,176 a year of earnings. Countable income is $5,202.60 andnc_tanf= 0.5 × (8,376 − 5,202.60) = $1,586.70 (main: $0). A parent of two with $600 a month gets 0.5 × (544 − 435) = $54.50 a month (main: $0). Two parents and a child, where the parent with $400 a month of earnings receives SSI, get 0.5 × 472 = $236 a month (previous head: $91; main: $36). A parent on SSI who receives $300 a month of child support for a child aged 5 gets 0.5 × (362 − 300) = $31 a month (main: $31). Seven existing cases with earnings were recomputed by hand with the exclusion. Each has the arithmetic in a comment.partners/analytics_coverage/edge_cases/state/nc/tanf.yaml: four fixtures were recomputed for the 27.5% exclusion and the $25 rule. The two cliff fixtures moved to the new cliff: $8,176 a year of earnings gives a $300.20 payment (eligible), and $8,177 gives $299.84 (ineligible). The SSI change moves no partner fixture. These edits need @hua7450's approval (see the PR comments).With this PR,
gov/states/ncpasses (402 tests), the NC partner fixtures pass (32 cases in 10 files),gov/hhs/tanf/cashpasses (36), and the code-health and parameter checks pass (450).The
average_reduced_need_standard_thresholdparameter keeps its name to keep the change small. It now has the State Plan and 10A NCAC 71W .0601(a) references, and its label already says "monthly minimum benefit".Follow-up for the older gaps (non-parent adults, 18-year-olds in high school, all-SSI children): #10492.
Fixes #10210
axiom: TheAxiomFoundation/rulespec-us#1947 queued
🤖 Generated with Claude Code