Repository navigation
Start England childcare entitlements in the term after birthdays - #2593
juaristi22 wants to merge 3 commits into
Conversation
Aggregate impact on certified data: passBase Checks: 0 broken by this change, 1 failing on both sides, 0 fixed. Moves flagged for review: 35 (thresholds in Notes
Moves flagged for review
Spending by benefit and service
Caseloads
Government balance, each component counted once
Model totals
Household income totals
Mean household net income in each side's own deciles
Standard reform costings (change in gov_balance)
Standard reforms: change in each reform's target
Household net income by decileMean change in household net income per household, and as a share of the decile's base income; households stay in the base run's deciles.
No change in any year: receipts by tax head; population; poverty rates; people in poverty; inequality. Checks failing on both base and head (1)
Counted-once checkEach of 84 components was raised by £1 per unit in 2026-27, and every head of its totals was read household by household: its own head must rise by exactly £1, no other tax head may move, no other benefit may rise, and the model's own total must move by what its heads moved. A head that breaks a rule is measured again twice: with every other head held at its baseline value, and with every other head held at its value after the first £1 while the component rises again. It fails where either still shows the response. 0 failed; 0 were skipped. Provenance
Dataset: Receipts by tax head: head levels
Spending by benefit and service: head levels
Caseloads: head levels
Government balance, each component counted once: head levels
Model totals: head levels
Household income totals: head levels
Population: head levels
Poverty rates: head levels
People in poverty: head levels
Inequality: head levels
Mean household net income in each side's own deciles: head levels
Standard reform costings (change in gov_balance): head levels
Standard reforms: change in each reform's target: head levels
|
|
Aggregate probe provenance is fixed in |
|
Fixed the standalone aggregate-tool import regression by deferring the existing provenance imports until simulation operations. All 369 tests in the fresh combined compare/provenance selection passed, along with the unchanged selected outcome checker and Ruff. Resulting-head Linux CI still requires verification. |
Fixes #2588
Universal and targeted childcare awards now follow the term after the qualifying birthday, using the existing date-of-birth and age input contract. Terms start on 1 April, 1 September and 1 January; a birthday on a term's first day waits until the following term. This includes children who reach the qualifying age after the 6 October snapshot. Baseline targeted provision continues through the term before universal provision begins, so both annual awards can be positive in different terms.
A shared internal term calculation allocates legally available base hours first within working-parent provision, once in the same funded terms. It also keeps the receiving flags consistent with positive awards. Universal and targeted age parameters remain independently reformable; raising one does not extend the other across an arbitrary reform-created gap. Existing England, family eligibility, take-up, school/deferred-start and upper-age guards remain.
The model retains three equally weighted terms, its existing annual hours/rollout schedule and the existing national-average funding table sampled once for the model year, including the following January. All funded hours in a common term use the same qualifying age-band rate. These are annual valuation approximations, not provider fees or actual term lengths. The age-only whole-age fallback remains a 6 April birthday; existing 6 October date validation and data birth-month behavior are preserved.
Explicit inputs for any of these five existing annual variables retain the complete original eligibility and valuation route:
early_years_term_share_before_schoolextended_childcare_entitlement_term_shareuniversal_childcare_entitlementtargeted_childcare_entitlementextended_childcare_entitlement_total_per_childThose shares and amounts are authoritative but do not identify individual terms. Calculated caches and model-written values do not become supplied inputs. No new public scalar term-share input is introduced. Annual family eligibility does not reconstruct a child's prior take-up history. Microcosm PR #1338 remains separate producer/consumer and private-data adoption work; this PR does not claim that adoption or a private-data retrofit is complete.
The source basis is the DfE publication record, its statutory guidance valid from 1 April 2026, especially A1.2, A1.4, A1.7 and A1.11, and SI 2014/2147 regulation 3.
Validation:
policyengine-core test ... -c policyengine_ukcommand. Their explicit synthetic 31 March birthdays preserve their documented full-year universal assumptions; the EntitledTo file remains a PolicyEngine regression comparison, not an externally verified EntitledTo match. All 265 other affected YAML cases retain qualified unchanged-source/runtime pass evidence. The 23 calls overlap 21 earlier passes and are not added to the earlier 288-case batch.uv run --frozen --offline --no-sync make formatpassed Ruff formatting and lint. Formatting preserved all Python ASTs and every YAML/non-Python byte.make test/make test-ci, private survey-wide validation, encoded parity and deployed/consumer acceptance were not run. Actual current-head Linux CI remains required.Reproducer: policyengine_uk/tests/policy/baseline/gov/dfe/universal_childcare_entitlement/birthday_terms.yaml; policyengine_uk/tests/policy/baseline/gov/dfe/targeted_childcare_entitlement/birthday_terms.yaml; policyengine_uk/tests/test_childcare_birthday_receiving.py::test_receiving_follows_a_positive_native_birthday_term
axiom: needed
Follow-up validation: aggregate probes now preserve genuine and model-owned registered inputs, including inherited placement and cleanup after partial writes. All 236 selected Python tests passed, including 42 new controls, and the unchanged selected outcome checker passed. Formatting preserved every Python AST and non-Python source byte. The local runtime witness includes an independently qualified empty Core template storage directory. New-head CI remains pending.
Import-isolation follow-up: the standalone aggregate tool now loads the existing input-provenance registry and helpers only during simulation operations, preserving its pre-construction model fingerprint. One fresh combined selection passed all 369 Python tests, including the complete compare module and prior provenance controls, with the unchanged selected outcome checker passing. The original import-isolation assertion and all policy formulas, guard accounting rules and input-origin semantics remain unchanged. Formatting and lint passed; resulting-head Linux CI still requires verification.