Repository navigation
Conversation
…ducation condition UC Regs 2013 reg. 5(1)(a) and SPC Regs 2002 reg. 4A(1)(a) make a person who has reached 16 a qualifying young person up to the 1 September following their 16th birthday, whatever their education. The model encoded only the education route, so a 16-year-old outside education was not a UC or PC qualifying young person. is_before_first_september_following_16th_birthday places that date from the date of birth and counts the route for a year that starts (6 April) before it: every annual age of 16, and a 17-year-old born from 1 September to 6 October. Both QYP variables OR it with the education route, under the same age band and own-right benefits exclusion. Tests: YAML cases hand-computed from the regulations (flags, date edges, UC child element and work allowance, PC child addition), the property-test oracle, a calendar differential over every birth date in 2008-2011 and across years, and a grid test of sufficiency, monotonicity, exclusion and UC/PC agreement. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-qyp-school-leaver-routes
…eavers Child Benefit (General) Regulations 2006 regs 4, 5 and 7 were not modelled: is_qualifying_young_person_for_child_benefit was reg. 3 (education or training) alone, so a 16-year-old who had left school was not a qualifying young person for Child Benefit, nor a young person for Housing Benefit, the legacy benefits or Council Tax Reduction (SSCBA 1992 s.142). - Reg. 4: until the 31 August after the 16th birthday, read from is_before_first_september_following_16th_birthday. - Reg. 5: the 20-week extension period for a 16- or 17-year-old not in remunerative work, from the new input is_in_child_benefit_extension_period. - Reg. 7: until the terminal date after leaving, from the new input is_before_child_benefit_terminal_date. - Reg. 7(3): no Child Benefit for a young person who qualifies through reg. 7 alone and works 24 hours or more a week (is_child_benefit_payable_for_person); they stay a qualifying young person. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…vers Child Tax Credit Regulations 2002 reg. 4 makes a person a qualifying young person from their 16th birthday until the 31 August that next follows, with no education condition, and reg. 5(3)(b) adds the 20 weeks after leaving for an under-18 registered for work or training. The model had only the education condition (reg. 5(3)(a), (ab)). - Reg. 4 reads is_before_first_september_following_16th_birthday. - Reg. 5(3)(b) reads the new input is_in_child_tax_credit_extension_period. - Reg. 5(4)(a): a young person who has left education or training and works 24 hours a week or more is not a qualifying young person through either. Tax credits ended on 5 April 2025, so this changes years to 2024-25. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…school leaver A disabled 16-year-old outside education is now a young person until the 31 August after their 16th birthday (Child Benefit reg. 4; HB reg 19(1)), so HB reg 28(6) counts them. Keep the original point, that the disability age extension does not itself create young-person status, as a second case with the reg. 4 period ended. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two property tests build a member who is outside every programme's family as a 16 to 19 year old not in education. At 16 that member is now a UC qualifying young person under reg 5(1)(a), so the family's UC gains a child element and the tests' premise no longer holds. Their generators now set is_before_first_september_following_16th_birthday false for that member. The test functions are unchanged, so Hypothesis draws the same examples. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-qyp-school-leaver-routes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nefit reg. 4 period test_excluded_member_never_changes_is_eligibility adds a member aged 16 or over who is not in education, on the premise that they are not a qualifying young person. With reg. 4 a 16-year-old who has left education is one until the 31 August after their 16th birthday, so the generator now puts the member past that date, as #2279 does for the same reason in two other property tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-routes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A mutation that opened the leaver routes to a student who fails the entry condition (reg. 5(3A)) passed every test: the grid fixed the entry age at 17. The grid now also draws a course begun at 19, with the date fact set directly, and asserts that such a student never qualifies. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…o ctc-qyp-school-leaver-routes Brings in #2285's review round 2 head through the item 1 branch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…date-of-birth tests - The route variable's docs now warn that setting it for some people gives everyone else false, and point to date_of_birth for placing one person. They also state that the rule departs from the 6 October reading that is_SP_age uses. - YAML: a 2025-26 case where the 16-year-old ranks first under the two-child limit and the youngest child loses the element (GBP 7,581.72), and a case mixing a person with date_of_birth and one without (both in the route). The second kills a mutant that reads the raw date_of_birth input instead of birth_day. - means_test_income_members.yaml: the 17-year-old case's name says why they are outside the route. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e education Review round 1 of #2301: the formula took failing the non-advanced education test as having left education, so a 16-year-old in full-time advanced education working 24 hours a week lost the reg. 4 period. Reg. 5(4)(a) bars work only for a person "having ceased to receive full-time education or approved training", and full-time education at a school or college counts at any level (reg. 5(5)). Reg. 4(2) lifts the first condition only. The 20 weeks of reg. 5(3)(b) are for a person who has ceased. The property oracle had the same conflation and is fixed with it; the grid now draws a course begun at 19, as its comment says. YAML Cases 15 and 16 pin the advanced student. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fixes #2385. Housing Benefit, Income Support, tax credit and Council Tax Reduction applicable income counted the family's own children's and young persons' income, tax, contributions and personal benefits too, an approximation each formula's comment called a follow-up. The law counts the claimant's and partner's alone: HB Regs 2006 reg 25(3) and IS Regs 1987 reg 23(2) say in terms that a child's or young person's income is not the claimant's; the tax credit income regulations (reg 3(1)) and every Council Tax Reduction scheme count the claimant or applicant and partner (SSI 2021/249 reg 36(2) says so in terms). The household head who applies alone for Council Tax Reduction keeps the treatment #2288 gave them. Tests: new YAML (three cases, each failing on main), a property test that a dependant's income never changes any of the seven income totals, and the Scottish CTR young-person tests updated to the rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ent's means tests Review round 1 of #2299: a young person who qualifies through reg. 7 and works 24 hours stays a young person, so their earnings must not enter the parent's Housing Benefit, Income Support or Council Tax Reduction income. #2387, merged in here, makes that so; Case 11 now has £20,000 of earnings and asserts the three applicable incomes are nil. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #2290
Stacked on #2299, #2387 and #2279. Do not merge before them. This PR builds on #2299's Child Benefit routes (which carry #2387) and #2279's date fact. Until they merge, the diff here also shows their commits. This PR's own change:
Summary
is_qualifying_young_person_for_child_tax_creditmodelled only the education and training condition (Child Tax Credit Regulations 2002 reg. 5(3)(a) and (ab)). Two rules for a young person who has left education were missing:is_before_first_september_following_16th_birthday(from #2279)is_in_child_tax_credit_extension_period, false by defaultThe second condition (reg. 5(4)) applies to both. A young person who has left education or training and works 24 hours a week or more qualifies through neither.
Against its base (the item 1 branch at 2575e9e, which carries
main4d80b29 and #2279), 2024-25, YAML cases run as plain simulations on both (scratch/probe_C_base_vs_branch.txt):is_qualifying_young_person_for_child_tax_creditCTC_child_elementCTC_child_elementIt changes years up to 2024-25: tax credits ended on 5 April 2025. This is a follow-up from #2279. It needs #2285, which stops a young person who heads their own benefit unit being their own qualifying young person (QYP).
The law
Child Tax Credit Regulations 2002:
HMRC's TCTM02220, which the entry-condition variable already cites, says: "There is no requirement for the qualifying young person to satisfy the condition of being in full-time non-advanced education or approved training up to and including 31 August following their 16th birthday. However, during this period, they have to satisfy the other conditions relating to qualifying young people."
Change
is_qualifying_young_person_for_child_tax_creditis now: aged 16 to 19, not receiving benefits in their own right (reg. 5(4)(c)), and any ofNew:
is_in_child_tax_credit_extension_period(input),is_in_remunerative_work_for_child_tax_credit(average weekly hours of 24 or more), and the parametersremunerative_work_hoursandextension_period_age_limit.Having ceased. Reg. 5(4)(a) applies to a person "having ceased to receive full-time education or approved training", so a student's hours do not matter (YAML Case 4). Full-time education at a school or college counts at any level (reg. 5(5)): a 16-year-old in full-time advanced education has not ceased it, so works 24 hours and keeps the reg. 4 period (YAML Case 15), although advanced education fails the first condition. An apprentice's education is received by virtue of their employment and is treated as having ceased (Case 5). The review of this PR found that a first version took failing the non-advanced test as having ceased; the property oracle had the same mistake, and both are fixed.
Not modelled: interruptions (reg. 5(7)); the Working Tax Credit rules reg. 2(1) points to for counting hours.
The annual approximation, and a 16th birthday on 31 August
Reg. 4 reads #2279's date fact: a year counts if it starts (6 April) before the end of the period. That is every 16-year-old (age on 6 October) and a 17-year-old born from 1 September to 6 October.
Reg. 4(1A) gives a 16th birthday on 31 August no period without education. Its effect is to stop the period running to the next year's 31 August. The date fact already ends that person's period in the year of the birthday, so no separate exclusion is needed. That year still counts, as the one in which they are a child until 30 August (YAML Case 8), and the year after does not (Case 7). An exclusion for 31 August birthdays was written and removed: it would have dropped a year in which the person is a child for nearly five months.
Invariants
Tests
test_child_tax_credit_school_leaver_routes_properties.py:test_child_and_adult_definitions_properties.py: Child Tax Credit joins the other three programmes in the 16-year-old route, for a person who has left education.child_tax_credit_school_leaver_routes.yaml, 16 cases hand-computed (2024-25; child element £3,455):Mutation checks, each applied alone in a copy of the branch (YAML cases and property tests that fail):
Round 2 mutations at 33fa9ee (
mutation/prC_r2.txt):The rows above them were run at earlier heads, before the formula was restructured. The last of those first passed every test. The grid fixed the age the course began at 17, so it never drew a student who fails reg. 5(3A); it now draws a course begun at 19 as well. No YAML case can catch it without setting the 16th-birthday fact by hand for a 19-year-old: with the fact computed from the date of birth, a student who fails the entry condition is 19, the fact is false and the 20 weeks have ended, so the mutated and the real formula agree.
Run locally at 33fa9ee:
policyengine-core teston the 8 YAML files the branch changes againstmain(the PRs below it included): 87 passed.pyteston the 7 Python test files it changes againstmain: 47 passed.policyengine-core teston the 198 YAML files that mention these programmes, 2,000 passed;pyteston the 76 Python test files that mention them is still running and will be added here.ruff format --checkandruff checkonpolicyengine_uk: clean.The full suites run in CI.
Microsimulation impact
Real runs on Enhanced FRS 2024-25 (uk-data 1.58.0, sha256
5ba399ea5ab9a6c7), one run each for 2024-25 to 2030-31, exact comparison of every record. Base: the item 1 branch at e626d3f (maine01f2f5, #2279, #2387 and #2299), so the figures are this PR's alone. Branch: 33fa9ee. Outputs:impact/prC_r2/.No household's income changes in any year, and no tax credit award changes. Tax credits ended in April 2025; the model still computes the elements for later years, so they are shown, but no award follows from them.
CTC_child_elementrises for those 22 benefit units: +£16.8m in 2024-25. None of them claims tax credits (is_CTC_eligiblefalse andchild_tax_credit£0 before and after;impact/prC_r1/context.txton the earlier base), sochild_tax_credit,tax_credits, net income and poverty are identical in every record and year.tax_credits_applicable_incomeis identical too. On the earlier base, without Count only the claimant's and partner's income in the legacy means tests #2387, it rose by £17,171.75 in 4 of those units, the newly counted young person's ownmiscellaneous_income(impact/prC_r1/income_probe.txt); Count only the claimant's and partner's income in the legacy means tests #2387 stops a young person's own income counting.Reproducer: policyengine_uk/tests/test_child_tax_credit_school_leaver_routes_properties.py::test_status_is_the_first_condition_or_a_leaver_fact_under_the_second
axiom: CTC Regs 2002 reg 4, reg 5(3)(b) and reg 5(4)(a) TheAxiomFoundation/rulespec-uk#361 queued (addendum; blocker stated there: the rows are in an unreleased ingest, axiom-corpus#765, and a billed encoder run needs approval)
🤖 Generated with Claude Code