Repository navigation
Apply the Universal Credit Act 2025 standard allowance uplifts to 2029-30 - #2242
Conversation
…9-30 standard_allowance_uplift held the s. 1 uplifts (2.3%, 3.1%, 4.0%, 4.8%) but nothing read it after the 2026-27 amounts, which include the first uplift, were written into amount.yaml, so 2027-28 to 2029-30 grew by CPI alone. The standard allowance is now uprated by its own index, the benefit uprating CPI index (floored at 0% in 2026-27 to 2029-30, s. 1(3)) times one plus the year's uplift, so it grows by CPI times the change in uplift. A legislated amount for those years is rescaled if the uplift in force differs from the statutory one, so a reform to the uplift or to rebalancing.active reaches every year. Fixes #2239 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ation Review round 1 on #2242: - Treat the uplift as nil before its parameter starts, so switching rebalancing on from 2000 no longer crashes. - Rescale only amounts that still hold their amount.yaml value; an amount a reform sets is used as given. - Build the index from gov.benefit_uprating_cpi as uprating extends it, so a reform to that index is followed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review round 2 on #2242: - Sample gov.benefit_uprating_cpi on 30 April of each year, so a fiscal-year reform to it reaches that year rather than the next. - Rescale only amount entries loaded from amount.yaml (they carry its file path), each at most once, so a reform that sets the legislated amount itself is used as given. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review round 3 on #2242: after a bounded amount reform, Parameter.update writes an entry restoring the legislated amount, with no file path, and the builder took it for a reform amount, so it kept the statutory uplift with rebalancing off. apply_parameter_changes now records the periods each change set; the builder leaves entries in those periods as given and rescales every other entry by the uplift of the amount.yaml entry it carries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ance-uplift-2239 # Conflicts: # docs/book/policy/uc-rebalancing.md # policyengine_uk/tax_benefit_system.py
…he index Review round 4 on #2242 found another bounded-override case in the rescale of legislated amounts. Rather than track which entries a reform wrote, drop the rescale and the simulation.py hook it needed: the legislated 2026-27 amounts stay as legislated, and the index uses the uplift they include for legislated years (read from amount.yaml) and the uplift in force after. Switching rebalancing off or changing a later uplift moves every year after the legislated ones; changing a legislated year needs its amount set. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
PE-UK main fix landed (UK hub, 2026-10-11 21:42Z): #2349 merged as |
The published-rates test skipped the four UC standard allowances because the model did not follow Universal Credit Act 2025 s. 1. It does now, through the allowance's own uprating index, so they are checked like any other series; only the LCWRA element (s. 3) stays an exception. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
vahid-ahmadi
left a comment
There was a problem hiding this comment.
Fine once it is rebased on main and two statements are corrected.
@MaxGhenis the mechanism is right. The s. 1(4) uplifts, the non-compounding reading of s. 1(2) and the 0% floor in s. 1(3) all match the Act, and the projected path checks out by hand. The findings are about main having moved, and about one claimant type that sits above the Act's floor.
-
must,
policyengine_uk/tax_benefit_system.py: the branch conflicts with main. Main has restructuredprocess_parameters(the dated-reform work), so the hook now belongs in_add_generated_parameters, afteradd_threshold_indexation. I tried that resolution locally and the 13 tests intest_uc_standard_allowance_uplift.pypass on it. -
should, the "One limitation remains" paragraph in the PR body, the module docstring (
create_standard_allowance_uprating.py:36-39) anddocs/book/policy/uc-rebalancing.md:98: after the merge with main, both things these describe are no longer true.- A bounded
amountoverride no longer leaves a stale value. On the trial merge,{"2026": 500}gives £438.07 in 2027 (the body says £424.90), and{"2028": 500}leaves 2027 at £438.07. - A
reform=dict now reaches the allowance. On the trial merge,Simulation(reform={uplift: {"2027": 0.07}})gives £454.64 in 2027 (= 438.07 × 1.07 / 1.031). Turningrebalancing.activeoff for 2027 gives £424.90. On the PR head both stay at £438.07.
So the "setamountdirectly instead" advice can go. A test of thereform=route would pin this down.
- A bounded
-
should, single under 25: the 2026-27 rate is above the Act's floor, so "the legislated rate less its uplift" is not the Act's Step 2 amount for that type. Reg 36 as substituted by SI 2026/113 gives £338.58. The Act gives 316.98 × 1.038 = 329.03 (Step 2), then × 1.023 = £336.60 (Step 3). The other three types land exactly on the Act (424.90, 528.34, 666.97). So for single under 25:
- the model's 2027-28 base is 338.58 / 1.023 = £330.97, not the Act's £329.03, and the projection runs about 0.6% above the Act's minimum to 2029-30;
- with rebalancing off, the path starts from £330.97 rather than the Act's Step 2.
The Act sets a minimum, so carrying the margin forward is a defensible projection. But the test docstring (test_uc_standard_allowance_uplift.py:15-17) andtest_amounts_match_the_act_step_by_step(line 108) call this the Act's step-by-step amount, and they derive Step 2 the same way the model does, so the test is not independent for this type. Please either state the assumption in the docstring, the docs and the test, or start Step 2 from the 2025-26 amount × CPI, as s. 1(2) says. The SI 2026/113 explanatory memorandum says only that the rates follow the s. 1 formula. It does not explain the extra £1.98.
-
should, overlap with #2284 (LCWRA freeze): both add a parameter generator to
tax_benefit_system.pyand both editdocs/book/policy/uc-rebalancing.mdandtests/test_dwp_published_rates.py. They conflict in the first two files. Whichever merges second needs to keep both generators in_add_generated_parameters, and the right set of exceptions intest_dwp_published_rates.py. -
nit,
docs/book/policy/uc-rebalancing.md:36says the minimum is increased "by September CPI". The model usesgov.benefit_uprating_cpi, which rises 3.4% from 2025 to 2026, against September 2025 CPI of 3.8%. The PR body says this. One clause in the docs would stop a reader taking the docs as the model's method.
What I checked
- Read the full diff and the PR body. Read UC Act 2025 s. 1 on legislation.gov.uk (Steps 1 to 3, the 0% floor, the uplift table and the "first Monday" definition of a tax year). Checked the 2026-27 amounts against UC Regs 2013 reg 36 as substituted by SI 2026/113 (in force 6 April 2026), which set the UC rates under the Act's own power rather than the Up-rating Order, and read the SI's explanatory memorandum.
- Hand-computed: 400.14 × 1.038 = 415.35, × 1.023 = £424.90. The model's 2027 single 25+ figure is 424.90 × (188.6207 / 184.3803) × 1.031 / 1.023 = £438.07, which matches the model.
- Model path, PR head against main (single 25+, monthly): 2027 £438.07 against £434.67; 2028 £450.73 against £443.36; 2029 £463.28 against £452.23; 2030 £472.55 (CPI alone from 2029).
pytest test_uc_standard_allowance_uplift.py test_dwp_published_rates.pyon the PR head: 1,308 passed, 62 skipped.- Mutation check: the new test file run against main fails 4 tests (the example, the step-by-step test and both rebalancing-off tests).
- Trial merge with main (local only, not pushed), as in finding 1: the uplift tests pass, and the override and
reform=checks give the results in finding 2. ruff checkandruff format --checkon the changed Python files: pass.- CI was green at 2530e4a, but that run predates main's changes.
- Not checked: the national impact and fiscal-event replay tables. They need the certified dataset, which I did not download.
🤖 Generated with Claude Code
|
Adoption hand-off for the hub's delta review. Head:
The higher standard allowance lowers the separate LCWRA component required by the s.4 combined-amount floor. 2026 remains legislated. #2284 is already merged; its head |
juaristi22
left a comment
There was a problem hiding this comment.
Reviewed 6779f95aeb71513f72d8256a4bb09d5e37ef637c against merge base 72fc91559cb6dd042679dc8c66073f30bebe95f9, with separate code/test and policy/source roles. The prior wiring, reform/reset and documentation points are addressed. One confirmed merge blocker remains:
C1 — Include the new standard-allowance index in the generated-parameter regression’s expectations. Adding add_uc_standard_allowance_uprating to GENERATION_STEPS makes generated_parameter_defines('gov.dwp.universal_credit.standard_allowance.uprating') correctly return True, but test_process_time_reforms.py::test_generated_parameters_are_the_series_processing_builds still expects False for this path (lines396–397). Its oracle recognizes the older generated-index prefixes and omits this new series.
This is the sole failure in the current-head Python3/4 job, which reports1failed/1521passed/16skipped, and it leaves Test/Result failed. The focused local batch reproduces exactly the same failure: 38passed,1failed. Update the expected generated-series coverage and obtain passing required checks. This is a demonstrated test/completion failure, not evidence that the allowance formula itself is wrong.
Validation: the complete new uplift file plus focused dated rebuild/reset, published allowance, LCWRA and final-consumer controls ran in84.88s. A10%2029 uplift reaches finalUC and both income measures and survives another dated rebuild plus two resets; disabling rebalancing follows the documented projected path. The protectedLCWRA combination also passes. Local Core3.32.27/Hypothesis6.168.2 differs from the lockfile, but the same failure is present in pinned-environment hostedCI. No install or private population/replay rerun occurred.
The independent source check validated5official originals. UCAct2025s1 supports the noncompounding uplift schedule and0%CPI floor; SI2026/113reg3 confirms the four2026allowance anchors. The under25margin and benefit-CPI forecast proxy are now clearly described. Axiom/Reproducer status lines are present; external signed encoding was not certified.
A merge-tree check against current main 36d2feb57cbde948177efe49d23d495ebd3e99c3 is clean. Merged-blob inspection retains both generators once, in order, and #2428’s2026–2032LCWRA horizon. That is structural integration evidence; the full combined-tree suite was not executed. No branch changes or merge performed.
|
Handoff for the hub's independent delta review. Final head:
Open items: remote CI and the hub's independent review. No self-review or PR merge performed. Progress, receipts and handoff artifacts are in |
juaristi22
left a comment
There was a problem hiding this comment.
Program review
Base repository: PolicyEngine/policyengine-uk
PR number: 2242
Reviewed head SHA: 1582c02
Merge base SHA: 36d2feb
Mode: incremental from 6779f95
Scope: C1 generated-series namespace repair, affected generation/rebuild/reset and UC/LCWRA final-income consumers through2032; identicalmergedmain portions excluded.
Source manifest: /private/tmp/policyengine-command-runs/202cefbfced3/pr-2242-r2-review-sources.json
Review status: COMPLETE
Source Documents
- pr-2242-source-act1.xml — cached original.
- pr-2242-source-act4.xml — cached original.
- pr-2242-source-si113.xml — cached original.
- pr-2242-source-rates2025.html — cached original.
- pr-2242-source-ons202509.html — cached original.
- pr-2242-r2-source-act3.xml — cached original.
- pr-2242-r2-source-ssaa150.xml — cached original.
- pr-2242-r2-source-axiom367.json — cached original.
- pr-2242-r2-source-axiom367-comments.json — cached original.
Critical
C1 — RESOLVED (previous severity: CRITICAL) (RESOLVED)
The original required-check failure was the generated-series classifier regression at policyengine_uk/tests/test_process_time_reforms.py:396. The generated allowance index then lived outside the economic-index namespace recognized by the regression. This head moves its INDEX_NAME and add_child target to gov.economic_assumptions.indices.uc_standard_allowance, updates the allowance parent/leaf uprating metadata, and explicitly asserts that the new index is generated. The old broad classifier oracle remains intact. The exact previously failing test actually PASSED, without skip/xfail, at this captured head in the bounded batch; JUnit proof, raw log, own validation. The confirmed local regression is closed. The old failed hosted run is historical; completion of the new required hosted Python/Test Result checks remains a coordinator merge gate.
Should Address
None.
Suggestions
None.
Evidence Gaps
No material gaps reported.
Notes
- C1 exact formerly failing generated-parameter test PASSED without skip/xfail at1582c02. Namespace migration preserves generator computation; all allowance metadata and consumers use the generated-economic-index path.
- Prior ancestry and unaffected-file/merged-main provenance independently verified. Retained legal noncompounding uplift,0% CPI floor, enacted2026rates, declared benefit-CPIproxy/under25margin.
- s3/SSAA150 support ordinary review timing2030onward; future CPI is disclosed discretionary/model projection. Corrected2029protected LCWRA anchor carries through2032 and finalUC/HBAI controls.
- Axiom issue367 open/pe-parity/dispatch-ready with later-year companion cases and recorded blockedencoder. Queued claim checked, no encoded-correct certification or billedencoder invoked. Historical population/replay totals remain author/historical evidence.
- Fresh14:09 CI at reviewedhead: Lint/Fix evidence/docs/YAML/smokesuccess;4Pythonshards IN_PROGRESS and requiredTestResultnotyetreported. Approval covers implementation; no merge-readyclaim.
- Timing capture-based; source role331.88s from readiness, code420.47s from readiness; acquisitionwindow137.13s. Prior inventory/eligibility triage separatelyrecorded in heartbeatmetadata.
Validation Summary
52 focused tests PASS,0failed/errors/skips in146.45s pytest/150.19s runner/151.57s boundedoffline process. Includes exactC1, full15caseupliftmodule, generated/rebuild/reset/freeze/index/publishedrates controls and3 synthetic finalUC/HBAIcontrols (dated10%+2resets, activeoff, protected2030–2032). No broad1572case rerun/privatepopulation. ExistingPython3.13/Core3.32.27/Hypothesis6.168.2 differsfromlockedCore3.33.2/Hypothesis6.169; importsassertedsnapshot/cachesexternal.9originals+9extracts hashvalid (5cached4new),0renders/rejected/discarded, bounded137.13sacquisition. FreshrequiredLintgreen/TestResultpending athead1582c02.
Timing
elapsed seconds: 539.33s; setup seconds: 0.45s; code role seconds: 420.47s; policy role seconds: 331.88s; source acquisition seconds: 137.13s; adjudication seconds: 0.00s; consolidation cleanup seconds: 64.58s
Review Severity
APPROVE. Open findings: 0 critical, 0 should address, 0 suggestions.
|
Landed by the UK hub (merge queue, pinned to head
|
No conflicts. #2242 uplifts the UC standard allowance (parameters, the rebalancing uprating, its test); it touches no file this PR changes, and nothing it adds reads a variable this PR removes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fresh impact on current main (UK hub, policyengine-uk 2.134.6, uk-data 1.58.1)These figures replace the PR body's historical national impact (
Change in UC components (£bn a year; "UC-paid" sums each tree over its own units with UC above zero):
Full tables, the decomposition and monthly rate paths are in IMPACT.md in UK hub job |
Fixes #2239.
Current update
Head:
1582c02c3f86a44b34e5bcf087d7ddc667f9dae5. Main integration:1582c02c3f86a44b34e5bcf087d7ddc667f9dae5, merging36d2feb57cbde948177efe49d23d495ebd3e99c3(includes #2428 and #2437) without rebasing.gov.economic_assumptions.indices.uc_standard_allowance, following Freeze the UC LCWRA element for 2026-27 to 2029-30 (UC Act 2025 s. 3) #2284's LCWRA-index fix and main's generated-parameter contract. Updated the generator, allowance metadata, docs and tests.6779f95aeb71513f72d8256a4bb09d5e37ef637c→675970f0313c72a6dbe670edf07fe25a98450409; single-25+ allowance for 2025–2032 and protected LCWRA for 2026–2032 are byte-identical in raw float64 monthly parameters and float32 annual simulation arrays. All four standard-allowance types also match. Evidence:.job/mock-differential.jsonplus before/after raw binaries. Single-25+ monthly SHA256:64977c284560a8188345eca4ef50994a9f4e9c6aaee600498b90d3edec9aa352; protected monthly LCWRA SHA256:41cc71c432b742e06a7efe7f5b6e179258a13ee51359c2228156889a76b1fa79.36d2feb57£457.1463889792£447.9895102742−£9.1568787050/month£5,595.4594726563£5,483.3798828125−£112.0795898438/yearThe initial four-worker run was stopped for host memory pressure after 1,473 passes and 60 skips (exit 130). Its 1,533 named JUnit outcomes were retained; four anonymous interruption placeholders were ignored. The remaining 39 exact node IDs then passed in fresh serial foreground pytest processes (
-n0), without changing test settings or examples. The receipt reconciliation requires complete, disjoint coverage of all 1,572 collected IDs. The 60 existing skips comprise 49 non-uprated series and 11 series ending before 2026–27. Evidence:.job/test-summary.json, original JUnit, and 39 per-case JUnit receipts.Initial command (numerical threads limited to one):
Fresh-process completion command:
uv run --frozen --no-sync python .job/run-fresh-cases.py .job/unfinished-fresh.txt. The driver checks compressor use below 30 GB before every case and runs the original node ID with-n0 -o xfail_strict=true -raplus its own JUnit receipt.uv run --frozen --no-sync policyengine-core test policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit -c policyengine_uk.make formatanduvx ruff format --check .: passed. Formatting checked 1,724 files.The full Python suite, documentation build and population/replay simulations were not rerun. Validation covers the focused combined-tree integration routes with MOCK situations only. The national impact figures below remain historical.
The national impact and earlier validation below are historical evidence at
6779f95ae, not measurements against the fresh main merge. This update runs MOCK situations only.What was wrong
rebalancing/standard_allowance_uplift.yamlheld the Universal Credit Act 2025 uplifts (2.3%, 3.1%, 4.0%, 4.8%), but no formula read it. #1691 wrote the 2026-27 amounts, which include the 2.3% uplift, intostandard_allowance/amount.yamland removed the formula step that applied the uplift. From 2027-28 the allowance grew by CPI alone. The reproducer: 2027 was 2.3% above 2026, CPI only.The law
Universal Credit Act 2025 s. 1(2) sets the minimum standard allowance for 2026-27 to 2029-30 in three steps:
Each uplift is measured against the CPI-only path from 2025-26, not compounded, because Step 1 takes the previous year's amount before its Step 3. So from one year to the next the allowance grows by CPI × (1 + this year's uplift) / (1 + last year's uplift).
Check: 2026-27 single 25+ is £400.14 × 1.038 × 1.023, rounded at each step, which gives the legislated £424.90.
Changes
rebalancing/create_standard_allowance_uprating.py(new) runs once per tree in main's sharedGENERATION_STEPS, after threshold indexation and before the LCWRA generator and LSR aliases, before uprating. This covers statutory initialisation, dated reforms, and reset/reprocess. It buildsgov.economic_assumptions.indices.uc_standard_allowancefrom two parts:gov.benefit_uprating_cpiread on 30 April of each year (the fiscal-year sampling date), as uprating extends it and including any reform to it, floored at 0% growth in 2026-27 to 2029-30 (s. 1(3)).amount.yaml(2026-27 so far, read from the file), the uplift is the one those amounts include, from the s. 1(4) table. For later years it is the uplift in force: nil withrebalancing.activefalse, and the reformed value under an uplift reform.amount.yamlis uprated by that index instead ofgov.benefit_uprating_cpi. Years after the legislated ones therefore get CPI times the change in uplift, and CPI alone after 2029-30.gov.benefit_uprating_cpi, so the difference from a CPI-only path is exactly the uplift.amountis used as given, as the replay's CPI-only counterfactual is.standard_allowance_uplift.yamlis dated from 6 April of each tax year and cites s. 1(4).uc-rebalancing.mdexplains the mechanism. Its uplift-reform example keys fiscal years ("2027"): single-day keys ("2026-01-01") never reached the 30 April sampling date.uc_reform.py: corrected a stale comment.Design note (review rounds 1-4). An earlier version rescaled the legislated 2026-27 amounts to the uplift in force, so that switching rebalancing off reached 2026-27 too. Telling legislated entries from reform entries, and from the entries
Parameter.updatewrites to restore a value after a bounded reform, kept producing edge cases. That version also needed a hook insimulation.py, a file the dated-Budget-reform work owns (session "Make dated Budget reforms correct on every route"). This version keeps the legislated amounts fixed and puts the uplift only in the index, which removes that class of case.Main's dated-reform pipeline now restores projected amounts after bounded overrides and rebuilds the allowance index for fiscal-year
reform=dictionaries as well asScenario(parameter_changes=...). The stale limitation and advice to setamountdirectly have been removed from the docs. The new regression pins the statutory uplift and a 10% dated uplift through a further dated rebuild and two reset/reprocess cycles.Projection assumption: the single-under-25 2026-27 rate is £338.58, above the Act's £336.60 minimum when rounding each step. The projection carries that margin forward; its CPI-only anchor is £338.58 / 1.023 rather than the Act's Step 2 minimum. The model still uses benefit uprating CPI as its forecast proxy, not a separate September CPI series for the allowance.
Tests
test_uc_standard_allowance_uplift.py:amountis used as given, including when combined withactivefalse, an uplift reform, or a value equal to the legislated one.active: True(from 2000) matches the baseline.gov.benefit_uprating_cpireform reaches the allowance in that year.amountreform before the legislated year leaves the later path as it would be without it.Earlier mutation checks (before this merge). On the earlier
mainthe example, the differential and the rebalancing-off tests fail. The scalar-activation and benefit-index regressions fail on this PR's first head.Historical validation at
6779f95aeb71513f72d8256a4bb09d5e37ef637c(locked venv, Python 3.13.9 / policyengine-core 3.33.2):UV_LINK_MODE=clone uv sync --frozen --extra dev: passed (workspace-local uv cache)..venv/bin/python -m pytest -n 4: 1714 passed, 60 skipped, 6 warnings in 5807.86s (1:36:47), coveringtest_uc_standard_allowance_uplift.py,test_dwp_published_rates.py,test_dated_reform_routes.py, all other test files containing_rebuildorreset_parameters(test_threshold_indexation.py,test_capital_gains_projection.py,test_triple_lock_statutory_inputs.py,test_input_records.py,test_benefit_cap_specified_benefits_properties.py,test_data_built_imputations.py,test_ni_class_4_profits_properties.py), plustest_uc_health_element_freeze.py,test_uc_rebalancing.py, andtest_no_economic_assumptions.py..venv/bin/policyengine-core test policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit -c policyengine_uk: 482 passed, 1 warning in 295.46s (0:04:55).make format: passed before each commit;uvx ruff format --check .: passed before the single push.Under
no_economic_assumptions, the allowance grows only by the uplift ratio to 2029-30 and is then flat. Full Python suite and documentation build were not run locally; validation covers the requested integration routes and UC policy folder.Historical national impact at
6779f95aeThese retained results compare the earlier PR head
6779f95aewith main72fc91559. They have not been rerun against fresh main36d2feb57; the current update uses MOCK situations only.Two full enhanced-FRS current-law microsimulations, one per source tree, each calculating 2026 and 2029. Main:
72fc91559cb6dd042679dc8c66073f30bebe95f9. Branch:6779f95aeb71513f72d8256a4bb09d5e37ef637c. Dataset:enhanced_frs_2024_25.h5@1.58.0; SHA2565ba399ea5ab9a6c7d4e9aaf6c623080beb34d9ad5f330f6244dbad72b8d960b6. Both use the sameuv.lockand locked dependencies; record IDs and weights match exactly. Weighted sums use float64; gains exceed £0.005 per year. Households are aggregated separately from benefit units.At that earlier head, 2026 had zero impact and the 2029 UC increase was £0.607bn, versus +£0.608bn in the previous body against main
6d89338a; this is a small change from the previous result. The 2029 allowance and LCWRA changes still round to the previous body's +£6.133bn and −£0.575bn; the benefit-unit gain count is now 5.886m versus the previous 5.87m. The previous body's 2025/2027/2028/2030 figures were not rerun at that earlier merge head and are omitted.In 2029, 5,886,158 benefit units gain UC and 264,198 lose UC; 253,956 households lose UC. Some capped families can lose because
uc_deductionsgrows with the standard allowance even where their capped award does not. The standard-allowance total (all benefit units, including those not paid UC) changes by +£6.132734bn and the LCWRA total by −£0.575195bn.2029-30 allowance and protected LCWRA floor
For a single claimant aged 25+, the 2029-30 standard allowance rises from £452.231375 to £463.282973 per month. It now carries the Act's 4.8% uplift above the CPI-only path anchored before the 2026 uplift, rather than retaining only 2026's 2.3%. This is the model forecast using its benefit-CPI proxy; it is not a claim of exact equality to the September-CPI statutory minimum, and the single-under-25 margin is retained as described above.
MOCK situation: one fictional single existing LCWRA claimant aged 30 in 2025, with zero earnings and new-claimant status explicitly false. Monthly protected LCWRA amounts calculated by the model:
The reduction from 2027 is expected: s. 4 protects the combined standard allowance and LCWRA amount for every allowance type. A higher standard allowance lowers the separate protected LCWRA component required by that floor. The legislated 2026 amounts stay unchanged.
Fiscal-event replay
The earlier replay table against main
6d89338apredates the6779f95aemerge and has been removed. That earlier update reran the requested current-law national comparison only; it did not rerun the scorecard SS2025 replay or replace W6's certified-pair estimate. This MOCK-only update does not rerun either national comparison or replay. The parameter result above confirms that the missing 2029 uplift now reaches the allowance.Overlaps
6779f95ae, merged main72fc91559cb6dd042679dc8c66073f30bebe95f9without rebasing.tax_benefit_system.pydiffers from main only by the generator import, one entry after threshold indexation inGENERATION_STEPS, and its docstring bullet. Main's rebuild/rollback/dated-reform structure is retained verbatim. Each active or unreformed tree runs the step once.996c38d2a50902582b70d178e4c75ea4f04aa440); both the s. 1 allowance and s. 3 LCWRA generators are retained.git merge-tree --write-tree HEAD 996c38d2a50902582b70d178e4c75ea4f04aa440at6779f95aeexited 0 and returned that head's tree (6bd5dbf827fb5b007d5a84c9ff600d425b99bb49). The other merge conflicts combine both documentation changes and check both dedicated indices intest_dwp_published_rates.py.uc_reform.pyreads allowances only for the protected LCWRA floor, and Autumn Budget dated reforms add no second uplift.benefit-uprating-september-cpi(session 7d5c5e19, not live; notes in~/reviews/benefit-uprating-sep-cpi-2026-09-29/STATUS.md) also applies the uplift, through its ownstandard_allowance/create_uprating_index.pyon a September CPI index. Whoever revives it should reconcile its index builder and the standard allowance'supratingmetadata with this PR so the allowance selects the intended CPI and uplift path. The two builders produce separate indices; retaining both does not by itself apply the uplift twice.amountto a CPI-only path. With the uplift in this PR's amounts, that reversal widens through 2029-30, as the issue expects.axiom: rulespec-uk#367 queued (UC Act 2025 s. 1, labelled
pe-parity). The 2027-28 to 2029-30 companion cases from this PR are added there.🤖 Generated with Claude Code
Reproducer:
policyengine_uk/tests/test_uc_standard_allowance_uplift.py::test_single_claimant_aged_30_follows_the_act_uplift_scheduleReproducer:
policyengine_uk/tests/test_process_time_reforms.py::test_generated_parameters_are_the_series_processing_builds