Skip to content

Require an eligible activity for Colorado's child care assistance - #10690

Open
MaxGhenis wants to merge 4 commits into
mainfrom
co-ccap-activity-test
Open

MaxGhenis wants to merge 4 commits into
mainfrom
co-ccap-activity-test

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

Colorado's Department of Early Childhood requires a family's adult caretakers to take part in an eligible activity, such as work or school, before its Child Care Assistance Program pays for care. co_ccap_eligible on main has no such test, so an otherwise eligible family receives a subsidy whether or not anyone in it works or studies. We add co_ccap_activity_eligible, which applies the department's test with the inputs the model has, and require it in co_ccap_eligible.

For example, a Denver parent of a 3-year-old with a $1,000 monthly child care bill and $30,000 in wages receives $872 in January 2026, on main and on this branch. With the same $30,000 from a pension and no job, the parent receives the same $872 on main and nothing on this branch.

We fix North Carolina's half of #9289 in #10691.

The rule

In section 3.111(B)(1) of 8 CCR 1403-1, the department provides that "The adult caretaker(s) or teen parent(s) shall: 1. Be actively participating in an eligible activity". Elsewhere in the rules, the department defines who counts as a caretaker and which households qualify:

  • In section 3.103, the department defines an adult caretaker as a parent, step-parent, legal guardian or person acting in loco parentis who contributes financially to the child's welfare and has custody. Under section 3.111(D)(2), it counts two caretakers when two adults contribute to the child's welfare or take on a parent's rights and duties, whatever their tax filing. We treat as caretakers the head and spouse of the tax unit that claims an eligible child and any parent that the child's parent_1_id or parent_2_id names in the same SPM unit. The microdata has no parent ids, so there a parent who files separately and claims no child doesn't count, and neither does a grandparent.
  • Under section 3.111(D)(1), a household qualifies when one caretaker takes part in an activity and any other caretaker does too or has a medical verification that they can't care for the child. Under section 3.111(D)(1)(b), the department counts one caretaker when the other is involuntarily out of the home, as through incarceration. Under section 3.111(E), a single incapacitated caretaker with no activity doesn't qualify.
  • Under section 3.111(G)(1) and (2), the county counts employment when gross income divided by the hours worked reaches the federal minimum wage, and self-employment when it also earns more than its expenses. Under section 3.111(G)(4), it counts enrollment in training, in a post-secondary program for a first bachelor's degree or less, or in basic education.
  • Under section 3.116(A), the department treats Colorado Works participants who take part in allowable work activities under an individualized plan as in an eligible activity. Under sections 3.111(D)(6) and 3.115(C), caretakers outside the Colorado Works assistance unit whose children receive basic cash assistance must meet the low-income test.
  • Under sections 3.119(D) and 3.121(B)(3)(a), protective services households need no activity, and families experiencing homelessness need none during a stabilization period.

We have no record of a physician's statement, a child welfare case or a stabilization period. In their place, we use disability, foster care or protective services, and the homeless flag. We don't treat TANF receipt as Colorado Works participation, since a child can receive basic cash assistance without the caretaker. Users can set meets_ccdf_activity_test for Colorado Works participation, job search, substance use disorder treatment, the launch period of a new business, temporary leave and Child Welfare Child Care. The new co_ccap_in_eligible_education defaults to school or college enrollment, full or part time, and users can set it to false for a graduate student, since the model has no record of degree level.

For the wage test, we multiply usual weekly hours by weeks worked. We treat zero weeks as a full year at the usual hours, as snap_work_requirement_weekly_hours does, and pass a caretaker with earnings and no recorded hours. The model records one figure for weekly hours, so we divide all earnings by all hours, and meets_ccdf_activity_test covers a qualifying job held beside unpaid or loss-making work.

The department set the same requirement, wage floor included, in section 3.105.1 of the 2023 edition. We apply the test in earlier years too, on the strength of 45 CFR 98.20(a)(3). Since at least 2017, HHS has required in it that a child live with a parent who works or attends job training or school, or receive protective services. The federal rule sets no wage floor, and we haven't checked Colorado's editions before 2023 for one.

Invariants

We generate earnings, hours, weeks, schooling and family makeups in test_co_ccap_activity_properties.py and check six invariants. The first compares the model with rule_says_eligible, which restates the rule on its own and, like the model, divides all earnings by all hours:

  1. A caretaker takes part in an activity when earnings exceed zero and reach the federal minimum wage for the hours worked, or when enrolled in college. Without an exempt path, a household qualifies when one caretaker takes part in an activity and every other caretaker takes part in one or has a disability, which stands in for verified incapacity.
  2. co_ccap_eligible implies co_ccap_activity_eligible, and a family without it receives no co_ccap_subsidy.
  3. Raising a caretaker's earnings, with hours unchanged, never removes eligibility.
  4. An adult who files separately, claims no eligible child and isn't named in the child's parent ids doesn't change the result, whatever that adult earns.
  5. When the child's parent ids name both parents, the result stays the same whether they file together or apart.
  6. A family with no activity qualifies through each exempt path, and TANF receipt alone doesn't qualify it.

Tests

  • We add 31 cases in co_ccap_activity_eligible.yaml, among them:
    • earnings of $15,080 for 2,080 hours, the federal minimum wage, and a dollar less;
    • the combinations of two caretakers;
    • each exempt path, and TANF receipt without one;
    • a graduate student and a part-time college student;
    • two parents whom the child's parent ids name and who file separately, and a working grandparent whom the mother's parent id names but the child's don't;
    • the Denver family end to end.
  • We add 5 cases in co_ccap_in_eligible_education.yaml.
  • In co_ccap_eligible.yaml, we set the new input in the 8 existing cases and add 2 cases in which an otherwise eligible family has no activity.
  • At d9721c1, 143 tests pass in Colorado's child care YAML folder, 6 in the unedited partner file signatures/co.yaml, 11 in test_co_ccap_activity_properties.py and 5 in test_co_ccap_parent_fee_properties.py.
  • When we merge this branch and Pay Colorado's child care assistance only for eligible children #10699 into main at 3386304 locally, 149 cases pass in that folder, 6 pass in the partner file, and all 18 tests in Colorado's three child care property files pass.
  • In CI at d9721c1, the Rest Python group remaining-2 ran the 11 activity property tests in 20 seconds, within a group that ran for 24:23 and peaked at 9.6 GiB of resident memory. CI measures memory for the whole group, and we didn't measure the file's own peak. Locally, on macOS with one process and a load average near 175, the 11 tests took 396 seconds of test time.

Impact

We ran the default dataset for 2026 on this branch at 84d27a4 and on main at 61d9e85. We estimate that Colorado's child care subsidies fall from $203.9 million to $1,917 a year. On main, 8 Colorado records receive a payment, with weights summing to 18,807 families. The 4 that lose it account for 18,797 of those families, and two of them carry 18,074 families and 99% of Colorado's payments, so the estimate rests on little data. In each of the four, a married couple files jointly, and one spouse has earnings while the other has no earnings, schooling, disability or exemption in the data.

As these families pay their whole bills, we estimate that they receive $17.5 million more in SNAP. Their child and dependent care credit stays at zero. Under section 21(d) of the Internal Revenue Code, a married couple can claim no more in expenses than the lower-earning spouse earns. National household net income falls by $185.8 million, all of it in Colorado, and national SPM poverty rates don't change.

axiom: TheAxiomFoundation/rulespec-us#2067 queued

🤖 Generated with Claude Code

8 CCR 1403-1 section 3.111(B)(1) requires adult caretakers and teen
parents to take part in an eligible activity, and section 3.111(D) and
(E) say which households qualify. co_ccap_eligible had no such test, so
the model paid families with no earnings, study or other activity.

co_ccap_activity_eligible adds the test, with the rule's federal minimum
wage floor on earnings and its exempt paths for Colorado Works,
protective services and homelessness.

Part of #9289.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 3 commits November 9, 2026 12:09
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#10721 charges the Denver family in Case 24 the $128 fee that
court_supervision.yaml Case 5 computes, so the subsidy falls from
$884.43 to $872.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Under 8 CCR 1403-1 section 3.111(D)(2), Colorado counts the adults who
support a child or take on a parent's duties whatever their tax filing,
so a parent that the child's parent ids name in the same SPM unit now
counts as a caretaker beside the claiming filers.

Under sections 3.111(D)(6) and 3.115(C), caretakers of children who
receive basic cash assistance without them must meet the low-income
test, so TANF receipt no longer exempts a family; Colorado Works
participants under 3.116(A) set meets_ccdf_activity_test.

Section 3.111(G)(4)(a)(1) counts training and post-secondary programs
for a first bachelor's degree or less, full or part time. The new
co_ccap_in_eligible_education defaults to school or college enrollment
and lets users exclude a graduate student.

The references now give one entry per document, with the 2023 edition
and 45 CFR 98.20(a)(3) for earlier years.

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

DTrim99 commented Nov 13, 2026

Copy link
Copy Markdown
Collaborator

PR Review: Require an eligible activity for Colorado's child care assistance

PR #10690 (author: MaxGhenis), head d9721c191c: 4 commits, +1,294/−2 across 9 files. This is the first review.

Path prefixes:

  • V/ = policyengine_us/variables/gov/states/co/ccap/
  • P/ = policyengine_us/parameters/gov/states/co/ccap/activity/
  • T/ = policyengine_us/tests/policy/baseline/gov/states/co/ccap/

I read the rule before the code, in four editions of Colorado's CCCAP rules:

  • 8 CCR 1403-1, ruleVersionId 12658 (effective 08/14/2026), which the PR cites;
  • 8 CCR 1403-1, ruleVersionId 12277 (effective 12/15/2025), which governs the PR's January 2026 test periods;
  • 8 CCR 1403-1, ruleVersionId 11042 (effective 08/14/2023), which the PR cites for 2023;
  • 9 CCR 2503-9, ruleVersionIds 8430 (12/30/2019) and 9031 (10/01/2020), the Department of Human Services rules that governed CCCAP before October 2022.

Page numbers below are PDF file pages. Each claim says what it rests on: my reading of the code, a hand trace, a source PDF, or a CI log. I ran no Python or tests.

Summary

The fix is needed, and most of it matches the rule. On main, any Colorado family with an eligible child gets CCCAP whether or not anyone in it works or studies, but 3.111(B)(1) requires the adult caretakers to be "actively participating in an eligible activity".

The PR adds co_ccap_activity_eligible and requires it in co_ccap_eligible, the gate for co_ccap_subsidy. The effect stays inside Colorado's program and what reads its subsidy. These parts match the rule (source PDFs):

  • no minimum hours, only the wage floor of (G)(1)(b) and (G)(2)(d);
  • the self-employment profit test of (G)(2)(c);
  • both caretakers in an activity, or one in an activity and the other incapacitated ((D)(1)(c));
  • no eligibility for a single incapacitated caretaker ((E));
  • leaving out a caretaker who is involuntarily out of the home ((D)(1)(b));
  • counting part-time college, since (G)(4)(a)(1) sets no full-time condition;
  • the protective services and homelessness exemptions (3.119(D), 3.121(B)(3)(a)).

The PR also fixes two of the problems we found in the North Carolina sibling #10691. It reads is_part_time_college_student, and it counts a co-resident parent who files separately when the child's parent ids name them. I confirmed the second through co_resident_parent_indices and Cases 29 to 31.

One critical:

  • C1. Basic education counts only through the age 5 to 17 school imputation. A teen parent aged 18 to 20 in high school, or an adult in a high school equivalency, ABE or ESL program, has no activity in the model. 3.103(Q) and 3.111(G)(4)(b) count all of them, and is_in_secondary_school already exists as an input.

Three should items:

  • S1. Six new terms or list entries fail no test when deleted.
  • S2. The parameter's reference cites pages 36 and 37 but follows the one-page format.
  • S3. rulespec-us#2067 defers the protective services and homelessness exemptions that this PR encodes, and no issue tracks them.

Five suggestions: G1 to G5.

CI and branch. CI is 36/36 green at the head. The branch is 140 behind main and 4 ahead, and git merge-tree is clean.

Critical (must fix)

C1. V/co_ccap_in_eligible_education.py:20-26: basic education counts only for people aged 5 to 17. A teen parent aged 18 to 20 in high school, or an adult working toward a high school equivalency, has no activity.

  • The rule (source PDFs, 12658):
    • 3.103(Q), page 4: "'Basic education' is a Low-Income Child Care eligible activity where an adult caretaker or teen parent is in middle school, high school education programs working towards a high school diploma or high school equivalency; Adult Basic Education (ABE); and/or English as a Second Language (ESL)."
    • 3.111(G)(4)(b), page 40: "An adult caretaker who is enrolled in a basic education program is eligible for CCCAP for up to fifty-two (52) weeks", and "Teen parents participating in basic education are not subject to time limits for this activity."
    • 3.103(EEEEE), page 20: a "teen parent" is "a person under twenty-one (21) years of age". 3.103(LLL), page 13, also counts "children under nineteen (19) years of age who are still in high school".
    • The December 2025 edition, which governs the PR's test periods, has the same text: 3.103(Q) on page 3 and 3.111(G)(4)(b) on page 21.
    • None of these sets an age limit on basic education, and none sets a full-time condition.
  • The code (code reading):
    • The formula returns is_full_time_student | is_part_time_college_student.
    • is_full_time_student is is_full_time_college_student | is_in_k12_school, and is_in_k12_school is an imputation from age 5 to 17.
  • The input that already exists: is_in_secondary_school, "Is in secondary school (or in an equivalent level of training)". It is a pure input, and az_ccap_activity_eligible reads it.
  • The result (hand trace):
    • Take a 19-year-old teen parent with is_in_secondary_school: true, no earnings and an eligible child.
    • Age 19 fails the 5-to-17 imputation, and both college flags are false, so co_ccap_in_eligible_education is false. works is false.
    • So co_ccap_activity_eligible is false, co_ccap_eligible is false, and co_ccap_subsidy is 0.
    • Under 3.103(Q) and (G)(4)(b), the parent is in an eligible activity. A 30-year-old in an equivalency program gets the same wrong result.
  • Why it isn't a reasoned deferral. The comment at line 23 says "3.111(G)(4)(b) counts basic education", and the PR body says the default covers "school or college enrollment, full or part time". Both read as full coverage. A user can override the variable, but the model can already see this case. We gave the same ruling on Require a need for care in North Carolina's child care program #10691's C1.
  • Fix:
    • Return person("is_full_time_student", period) | person("is_part_time_college_student", period) | person("is_in_secondary_school", period).
    • Consider technical_institution_student too, for the workforce training of (G)(4)(a)(2): "vocational, technical or job skills training that will result in a diploma, license, or certificate" (page 39).
    • Pin each new input in T/co_ccap_in_eligible_education.yaml: a 19-year-old in secondary school (true), and an adult aged 30 in secondary school (true).
    • Update the line 23 comment, the variable's documentation, the PR body, and in_activity in the property test, which repeats the same two flags.

Should address

S1. Six new terms or list entries are unpinned: deleting any one fails no fixed test. This rests on my reading of the YAML, the Hypothesis @examples and the unedited partner cases.

  • sstb_self_employment_income and farm_operations_income in P/earned_income_sources.yaml:6-7. No case uses either input. The property test sets only employment_income and self_employment_income, and the Colorado partner cases use employment_income_before_lsr.
  • is_incapable_of_self_care in incapacitated (V/co_ccap_activity_eligible.py:76-79). Only is_disabled is tested (Cases 13, 14, 15, 30).
  • The eligible_child & mask in protective_services (lines 87-93). Cases 21 and 22 put the flag on the eligible child, so they pass without the mask. No case expects false when the flag sits on someone who isn't an eligible child. Without the mask, an adult or a 15-year-old flagged for protective services would exempt the household.
  • same_unit (lines 67-68). Every parent-id case puts the whole household in one SPM unit. The guard matters only for the named parent's own SPM unit, where it stops a parent of a child in another unit from counting as a caretaker. No case outputs that unit's result.
  • min_(weeks, WEEKS_IN_YEAR) (line 38). No case and no draw has more than 52 weeks; the strategy stops at 52. This guard only covers bad input, so you could drop it instead of pinning it.
  • Fix: add short cases to T/co_ccap_activity_eligible.yaml:
    • SSTB self-employment income only (true);
    • farm income only (true);
    • one parent working beside an idle parent with is_incapable_of_self_care only (true);
    • an idle single parent with a 15-year-old flagged for protective services and a 3-year-old not flagged (false);
    • one household with two SPM units: a working mother and her child in one, and the father, named by the child's id, working in the other. Expect co_ccap_activity_eligible: [true, false]; without same_unit, the father's unit turns true;
    • either 60 weeks at 40 hours with $16,000 in wages (60 is capped to 52, and 15,080 ≤ 16,000, so true) or delete the min_.

S2. P/earned_income_sources.yaml:14-15: the reference cites two pages in the one-page format.

  • The title cites "Section 3.111(G)(1) and (2)" and the href opens page 36.
  • (G)(2)(c) starts on page 36, but (G)(2)(d), the self-employment wage floor, is on page 37 (source PDF).
  • CLAUDE.md, "Parameter and variable references": "Several cited pages: the href opens the first, and the title ends with #page 72-75 (consecutive) ... Quote the title, since an unquoted # starts a YAML comment."
  • Fix: title: "8 CCR 1403-1 Section 3.111(G)(1) and (2), employment and self-employed criteria #page 36-37".
  • The variable references follow the rules. Each tuple has one entry per source, and a # PDF pages comment sits above each multi-page href. I checked the pages: 3.103(C) is on page 2, 3.111(B) on 31, (D) on 33-34, (E) on 35, (G) on 36-37 and 39-40, 3.116(A) on 63, 3.118(A) on 68, 3.119(D) on 69 and 3.121(B)(3) on 72.

S3. Axiom coverage leaves out two exemptions that this PR encodes.

  • rulespec-us#2067 queues 3.111(B)(1), (D)(1) and (2), (E), (G)(1)(b), (G)(2)(c) and (d), and (G)(4)(a)(1). Its review finding says: "Leave the exemptions for Colorado Works (3.116(A)), protective services (3.119(D)) and homelessness (3.121(B)(3)(a)) ... for later modules."
  • This PR encodes two of those as formula paths: protective_services (3.118(A), 3.119(D)) and homeless (3.121(B)(3)(a)). The Colorado Works path rests only on an input, so it needs no module.
  • No issue tracks the deferred exemptions, so they aren't queued in rulespec-us as CLAUDE.md "Axiom Parity" requires: "Any PR that adds, updates or fixes policy must also leave the same provision correct in rulespec-us." We raised the same point on Require a need for care in North Carolina's child care program #10691 (its S4).
  • Fix:
    • Extend South Carolina rate structure #2067 to 3.118(A), 3.119(D) and 3.121(B)(3)(a), or open a companion queued issue and add it to the axiom line.
    • After C1, add 3.103(Q) and (G)(4)(b), and (G)(4)(a)(2) if you adopt it, to South Carolina rate structure #2067's provision list. Today it lists only (G)(4)(a)(1), although its "PolicyEngine implementation" section mentions basic education.

Suggestions

G1. A grandparent who claims both a teen parent and the teen's child counts as a caretaker. When the child's ids name the teen, both of them count.

  • Under 3.103(EEEEE), page 20, a teen parent under 21 with custody is the applicant. Under 3.103(LLL), page 13, the CCCAP household is the children and "the adult caretaker(s) or teen parent(s)".
  • In the model, the claiming filers are the head and spouse of the tax unit with the eligible child. Take a grandmother who claims her 17-year-old daughter and the daughter's baby:
    • Without ids, only the grandmother is tested. The family qualifies if she works, whatever the teen does, and fails if she is retired, even while the teen is in school.
    • With ids naming the teen (hand trace): the teen is a linked parent and in K-12, but the retired grandmother is still a claiming filer with no activity, so the result is false. If the teen claims the baby herself, the same family is true. So tax filing changes the result even though the ids name the parent.
  • The rule is not fully clear. 3.111(D)(2) counts two caretakers when adults "contribute financially to the welfare of the child and/or assume parent rights", and a grandparent claiming the child does contribute financially. So I'm not treating this as a law violation.
  • Consider this: when a child's ids name a co-resident parent, count only the named parents and their head-or-spouse partners as claiming filers. Add a case for the grandmother who claims both.

G2. Cite the edition in force for each period.

  • The January 2026 test periods fall under ruleVersionId 12277 (effective 12/15/2025), not 12658 (08/14/2026) or 11042 (2023). I compared 12277's 3.111(B), (D), (E), (G)(1), (G)(2) and (G)(4) (pages 15-21) with 12658, and the text matches. So the tests are right, and only the citation is off. Either add a 12277 entry or move the cases to September 2026 or later, as South Carolina rate structure #2067's companion cases do.
  • Before October 2022, CCCAP ran under 9 CCR 2503-9 section 3.905.1. Versions 8430 (12/30/2019, page 16) and 9031 (10/01/2020, pages 16-17) already have the employment and self-employment wage floors and the incapacitated-second-caretaker rule. That answers the PR body's "we haven't checked Colorado's editions before 2023". Consider citing it in P/earned_income_sources.yaml, which starts in 2020, and in the variable.
  • Optional: V/co_ccap_eligible.py keeps three pre-existing 11042 entries that differ only by #page= (17, 19, 31). The PR edits this tuple, so it could fold them into one entry under # PDF pages 17, 19, 31.

G3. Narrow the protective-services stand-in, or say how far it reaches (V/co_ccap_activity_eligible.py:85-93).

  • 3.118(A), page 68, defines protective services households as those "in which child(ren) have been placed by the county in foster home care, kinship foster home care, or non-certified kinship care, and have an open child welfare case".
  • receives_or_needs_protective_services also covers a child served at home. Such a case falls under 3.120, Child Welfare Child Care, which the county's child welfare division decides case by case (page 70) and which the comment at lines 98-105 sends to meets_ccdf_activity_test.
  • A sentence in the comment would make the stand-in's reach explicit, or the path could use is_in_foster_care alone.

G4. Reuse the shared helpers.

  • Since Deem income from a disabled parent who is not eligible for SSI #10630 merged today, _parent_links.py on main has linked_child_count(person, period, children) and is_parent_of_any. linked_child_count(person, year, eligible_child) > 0 gives the linked parents. You'd keep only the SPM-unit check, if you keep it at all (S1).
  • P/earned_income_sources.yaml repeats the four earned entries of gov.states.co.ccap.income.countable_income.sources, and Require a need for care in North Carolina's child care program #10691 adds the same four-entry list for North Carolina.
  • The two PRs also treat TANF differently. Colorado ignores TANF receipt for the reason in the comment, while North Carolina counts Work First through is_tanf_enrolled. A shared caretaker helper, or a shared list, would keep the CCDF activity tests aligned.

G5. The property file overlaps the YAML (CLAUDE.md "Test design and CI cost").

  • in_activity and rule_says_eligible restate the formula's wage floor and caretaker rule.
  • test_each_exempt_path_qualifies_a_family_with_no_activity, test_tanf_receipt_alone_is_not_an_exempt_path and test_a_family_with_no_activity_fails_without_an_exempt_path repeat YAML Cases 2 and 19 to 23.
  • The distinct checks are monotone earnings, the unnamed separate filer, and filing invariance under parent ids. The PR body reports the CI time, about 20 s in Rest group remaining-2 (CI log), and says the file's own peak memory wasn't measured, as CLAUDE.md asks. Trimming is optional.

Verified correct

  • Scope (code reading; grep at the head):
    • co_ccap_eligible is now activity_eligible & (entry | re-determination).
    • co_ccap_subsidy is defined_for = "co_ccap_eligible", and it flows on to co_child_care_subsidies, spm_unit_benefits and household_child_care_subsidies.
    • Nothing else reads co_ccap_activity_eligible or co_ccap_in_eligible_education. No variable outside Colorado's program changes, except through the lower Colorado subsidy, as the PR body's SNAP note describes.
  • Minimum hours: none (source PDFs). (G)(1)(a): "Adult caretakers or teen parents may be employed full or part time." The only floor is gross income divided by hours of at least the federal minimum wage ((G)(1)(b), (G)(2)(d)). The code passes earnings above zero with no recorded hours, which can't fail the floor, and it reads gov.dol.minimum_wage ($7.25 since 2009-07-24).
  • Self-employment (code reading). Clipping each source at zero means a loss never offsets wages (Case 9), and a net loss fails (G)(2)(c) (Case 8).
  • Two-parent households (source PDFs; code reading):
    • (D)(1)(c) requires both caretakers in an activity, or one in an activity and the other incapacitated "according to a physician's statement or other medical verification".
    • has_active_caretaker & no_inactive_caretaker encodes exactly that. Two incapacitated caretakers fail (Case 15), as does a single incapacitated caretaker ((E); Case 14).
  • Which parents count (code reading of _parent_links.py):
    • The caretakers are the claiming head and spouse, plus the parents that an eligible child's parent_1_id or parent_2_id names.
    • co_resident_parent_indices resolves each id among household members. It returns −1 when the id is unresolved or ambiguous, and drops a second slot that repeats the first. So parents[children] with the resolved mask is sound, and the bincount over non-negative indices can't fail.
    • This matches 3.111(D)(2), "whatever their tax filing", for co-resident parents. Under 3.103(C) and (D)(1)(b), an incarcerated person drops out.
  • Exemptions (source PDFs). 3.119(D): "Protective services households are not subject to low-income eligible activity requirements." 3.121(B)(3)(a): no activity is needed "during the stabilization period". Not treating TANF receipt alone as an activity fits 3.115(C) and 3.111(D)(6). 3.116(A) requires an individualized plan and a referral, which the model can't see.
  • Mechanics (code reading):
    • The variable is an SPMUnit MONTH variable. YEAR inputs are read at period.this_year; co_ccap_child_eligible, is_incarcerated and is_in_foster_care are read at the month.
    • The vectorized calls (np.sum(..., axis=0), spm_unit.sum and .any, person.tax_unit.sum) are sound, and there is no builtin sum over arrays.
    • The new variables are bools, so the NH Add New Hampshire state supplementation for 2026 #10156 key pattern doesn't apply.
    • Reading weekly_hours_worked_before_lsr avoids a labor-supply loop, as the Arizona, Georgia, Hawaii, Iowa and Kansas activity tests do. employment_income is already a Colorado countable-income source.
  • No vacuous pass. A household with no caretaker gets has_active_caretaker false, so it fails unless an exempt path applies. Unlike Require a need for care in North Carolina's child care program #10691, there is no vacuous true.
  • Housekeeping:
    • The changelog fragment changelog.d/co-ccap-activity-test.fixed.md is present.
    • The new YAML files are named after their variables, and the test periods are plain.
    • The 8 existing co_ccap_eligible cases set the new input to true, so True & X leaves every expected value unchanged.
  • Source conflicts: none to record (source PDFs).
    • The 2019, 2020, 2023, 2025 and 2026 editions agree on the provisions encoded here.
    • 45 CFR 98.20(a)(3) sets a floor that the state rule builds on, not a rule that conflicts with it.
    • The stand-ins are approximations, not choices between conflicting sources.
    • No added comment matches the ratchet's CONFLICT_COMMENT_RE (checked statically), and CI ran the ratchet at this head.
  • Partner tests. The PR doesn't touch them. In each Colorado signature household, the head earns $36,000 and the spouse $12,000 with no hours recorded, so both caretakers pass. Household API Partners passed.

Hand checks (all at 2026-01; federal minimum wage $7.25):

Case Trace Expected
act 1 20,000 > 0, no hours, so floor 0 true ✓
act 2 0 earnings, so earnings > 0 fails; age 30, no school; not disabled false ✓
act 3 7.25 × 40 × 52 = 7.25 × 2,080 = 15,080 ≤ 15,080 true ✓
act 4 15,079 < 15,080 false ✓
act 5 7.25 × 40 × 26 = 7,540 ≤ 10,000 true ✓
act 6 0 weeks → 52; 15,080 > 10,000 false ✓
act 7 7.25 × 30 × 52 = 11,310 ≤ 20,000 true ✓
act 8 max(−5,000, 0) = 0, not > 0 false ✓
act 9 20,000 + max(−30,000, 0) = 20,000 ≥ 15,080 true ✓
act 12 parent2 is the inferred spouse (age 30, not younger than the head), so a caretaker with no activity and no incapacity false ✓
act 13 the same, with parent2 disabled, so incapacitated true ✓
act 16 parent2 incarcerated in 2026-01, so out; parent1 works true ✓
act 17 the grandparent's tax unit has 0 eligible children and no ids, so not a caretaker; the parent works true ✓
act 18 the grandparent isn't a caretaker; the parent is idle, so no active caretaker false ✓
act 24 Denver, 30,000/12 = 2,500. Fee 0.01 × 2,500 + 0.14 × (2,500 − 1,762.50) = 128.25 → 128 (as in court_supervision.yaml Case 5). 12,000/12 − 128 872 ✓
act 25 a pension isn't an earned source: no activity, not eligible, 0 through defined_for false / false / 0 ✓
act 26 the input co_ccap_in_eligible_education: false overrides the formula false ✓
act 29 ids give mother row 0 and father row 1, same SPM unit; father idle, not disabled false ✓
act 30 father works (30,000, no hours); mother is the claiming filer, disabled true ✓
act 31 only eligible children's ids are read, so the grandparent named by the mother's id isn't a caretaker; mother idle false ✓
edu 3 age 17, inside the 5-17 imputation true ✓
edu 5 NM, outside defined_for false ✓
eligible new 1, 2 activity input false, so False & ... false ✓

Axiom line assessment

The line is axiom: TheAxiomFoundation/rulespec-us#2067 queued. The issue meets the requirements and matches the head as it stands:

  • It is OPEN and labelled pe-parity. It was created 2026-11-07 and last updated 2026-11-11, the day of the head's CI run.
  • It gives the module path (us-co/regulations/8-ccr-1403-1/3.111/b-eligible-activity), the corpus citation (us-co/regulation/8-ccr-1403-1-eff-2026-08-14), the verbatim text of each provision and the required outputs.
  • It has 13 companion cases and four properties. Cases 1 to 13 mirror YAML cases that are hand-built from the rule text, and it gives hours explicitly where the YAML records none.
  • It records its blocker: the encoder run needs approval, and the pinned corpus release lacks the Colorado scope.
  • Its "PolicyEngine implementation" section describes the parent ids, the wage floor, the weeks handling and the TANF treatment as they are at the head.

Caveats:

  • S3: the protective services and homelessness exemptions have no queued coverage.
  • C1: the provision list should gain 3.103(Q) and (G)(4)(b) once basic education is fixed.

CI status

  • 36/36 checks pass at the head: run 43082215285 on 2026-11-11, head d9721c191c. I re-checked gh pr checks 10690 near the end of this review. Nothing is pending or failing.
  • The run postdates Tie source-conflict markers to the register shared with Axiom #10287, so the source-conflict ratchet ran against this head.
  • YAML (CI log). Baseline states-shard-2 ran co_ccap_activity_eligible.yaml (31 cases), co_ccap_eligible.yaml (10) and co_ccap_in_eligible_education.yaml (5), all passed.
  • Python (CI log). Rest (Python shard 4), group remaining-2, ran all 11 tests in test_co_ccap_activity_properties.py, and all passed. The heaviest took 5.19 s, 4.79 s and 4.52 s of call time.

Branch status

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.

Requesting changes: 1 critical, 3 should address, 5 suggestions (details in the report above). The activity rule matches 8 CCR 1403-1 in every version that governs the test years: no minimum hours, both caretakers active or one incapacitated. Part-time college and co-resident separate filers are handled correctly, and all 25 expectations check by hand.

  • Critical: basic education counts only through the age 5-17 K-12 imputation. A teen parent aged 18-20 still in high school, or an adult in HSE, ABE or ESL classes, fails the activity test and gets $0. 3.103(Q) and 3.111(G)(4)(b) count those activities, and is_in_secondary_school already exists.
  • Should:
    1. Six new entries and guards have no case.
    2. The earned-income parameter cites pp. 36-37 in the one-page format.
    3. rulespec-us#2067 defers exemptions the PR encodes, and nothing queues them.

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