Skip to content

Add UC claimant-only LCWRA, carer and work allowance companion cases - #405

Merged
MaxGhenis merged 2 commits into
mainfrom
pe-parity-uc-claimant-only-elements-cases
Oct 12, 2026
Merged

MaxGhenis merged 2 commits into
mainfrom
pe-parity-uc-claimant-only-elements-cases

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Adds 23 companion cases to uk/regulations/uksi/2013/376/{22,27,29}.test.yaml: claimant-only LCWRA and work-allowance inputs, the reg 29(4) joint-claimant parenthetical, and reg 29(2)'s limits on two carer elements. No module bytes change.

Why now

PolicyEngine/policyengine-uk#1989 changes LCWRA, carer elements and work-allowance eligibility to use the claimants' circumstances. These cases establish the existing atomic RuleSpec behavior independently from PolicyEngine. The ProgramSpec carer composition and benefit-cap receipt/entitlement scopes are queued separately; this PR does not claim those integration paths are correct.

Hand-computed expectations

The expectations come from UC Regs 2013 reg 27, reg 29, reg 22, and reg 36's table, using the revised CLML fetched 2026-10-01. WRA 2012 s 40 defines “claimant” as a single claimant or each of joint claimants. All households are synthetic.

The period conventions match the existing files: 2026-04 for regs 22 and 27; a custom one-day period, 2026-04-06 through 2026-04-06, for reg 29's Day judgments. The £429.80 case supplies the reg 36 amount for a pre-2026 claimant in the 2026-27 regime; it is not a test of a historical assessment period or of upstream rate selection.

Reg 27: one LCWRA element, claimant slots only

The only asserted output is universal_credit_award_lcwra_element_included_amount. The reg 36 amounts are explicit test inputs. Reg 27(1)-(2) includes the qualifying claimant's amount; (4)(a)-(b) permits one element and selects the higher amount when both qualify.

New case Hand computation Expected monthly amount
joint_claimants_both_lcwra_at_same_amount_include_one_element One element: max(217.26, 217.26) 217.26
joint_claimants_both_lcwra_include_one_higher_amount_when_first_is_higher One element: max(429.80, 217.26) 429.80
joint_claimants_only_first_has_lcwra_include_first_amount First qualifies: 217.26; second's 429.80 is inapplicable 217.26
joint_claim_with_neither_lcwra_ignores_single_claimant_slot Neither joint claimant qualifies: 0; single slot is inapplicable 0
single_claimant_pre_2026_lcwra_includes_higher_regulation_36_amount Qualifying single claimant's supplied amount: 429.80 429.80
single_claim_ignores_joint_claimant_lcwra_slots Single claimant does not qualify: 0; joint slots are inapplicable 0

Reg 29: LCWRA priority and the joint-claimant exception

Reg 29's atomic module exposes inclusion judgments; its monetary output is deferred (29.yaml:9). These cases assert those judgments, not a monetary amount. The first six assert claimant_carer_element_included; the last three assert both_joint_claimants_carer_elements_included.

New case Law-derived expectation Expected
joint_claimant_carer_with_lcwra_keeps_carer_element_when_lcwra_element_is_included_for_other_claimant Reg 29(4)'s parenthetical exception applies: the LCWRA element is included for the other joint claimant; other inclusion conditions hold holds
joint_claimant_carer_with_lcwra_has_lcwra_element_only_when_not_included_for_other_claimant Same carer, but exception fails: only LCWRA may be included for this claimant not_holds
single_claimant_carer_with_lcwra_has_lcwra_element_only_even_if_other_claimant_slot_is_set Single claim: joint-claimant exception is inapplicable; only LCWRA not_holds
joint_claimant_carer_without_lcwra_keeps_carer_element_when_other_claimant_has_lcwra_element Claimant has no LCWRA, so (4) does not displace their carer element holds
joint_claimant_not_elected_for_same_severely_disabled_person_has_no_carer_element Reg 29(3): this claimant is neither the sole relevant carer nor the elected/determined carer not_holds
claimant_without_regular_and_substantial_caring_responsibilities_has_no_carer_element Reg 29(1)'s caring condition fails not_holds
joint_claimants_caring_for_same_severely_disabled_person_not_both_included Reg 29(2): caring for the same person prevents both elements not_holds
joint_claimants_not_both_included_when_only_one_qualifies Reg 29(2): both must qualify; only one does not_holds
single_claim_never_includes_two_carer_elements Reg 29(2) applies only to joint claimants not_holds

Reg 22: limited capability alone gives the work allowance

Reg 22(1)(b) gives a work allowance for claimant LCW even without a child. Under (2), the allowance is £710 without a housing costs element and £427 with one. The earned deduction is 0.55 × max(0, E − allowance), or 0.55 × E when neither condition is met. The total deduction adds U under (1)(a). Reg 22(3) uses the joint-claimant calculation for a couple member claiming as a single person.

The table shows every asserted output: effective joint-claimant judgment (J), work-allowance judgment (WA), earned_income_for_deduction (E), unearned_income_for_deduction (U), applicable_work_allowance_amount (A), earned_income_amount_subject_to_taper (T), earned_income_deduction_from_maximum_amount (D), and universal_credit_award_deduction_from_maximum_amount (total).

New case J / WA E / U / A (£) Hand computation T → D → total (£)
joint_claimants_without_child_one_with_lcw_higher_work_allowance_without_housing_costs holds / holds 1500 / 120 / 710 1500 − 710 = 790; 790 × .55 = 434.50; 120 + 434.50 = 554.50
joint_claimants_without_child_one_with_lcw_lower_work_allowance_with_housing_costs holds / holds 1500 / 120 / 427 1500 − 427 = 1073; 1073 × .55 = 590.15; 120 + 590.15 = 710.15
single_claimant_with_lcw_and_no_child_higher_work_allowance_without_housing_costs not_holds / holds 2000 / 0 / 710 2000 − 710 = 1290; 1290 × .55 = 709.50; 0 + 709.50 = 709.50
single_claimant_with_lcw_and_no_child_lower_work_allowance_with_housing_costs not_holds / holds 900 / 0 / 427 900 − 427 = 473; 473 × .55 = 260.15; 0 + 260.15 = 260.15
single_claimant_without_child_or_lcw_has_no_work_allowance_with_housing_costs not_holds / not_holds 800 / 50 / 0 800 − 0 = 800; 800 × .55 = 440; 50 + 440 = 490
joint_claimants_without_child_or_lcw_have_no_work_allowance holds / not_holds 1200 / 0 / 0 1200 − 0 = 1200; 1200 × .55 = 660; 0 + 660 = 660
single_claim_ignores_joint_claimant_child_and_lcw_slots not_holds / not_holds 1000 / 0 / 0 Joint slots are inapplicable; 1000 × .55 = 550; 0 + 550 = 550
member_of_couple_claiming_as_single_with_partner_lcw_uses_joint_work_allowance holds / holds 1000 / 0 / 710 Reg 22(3) applies; 1000 − 710 = 290; 290 × .55 = 159.50; 0 + 159.50 = 159.50

Verification

Unsigned local python -m axiom_encode.cli test at current-main CI pins: axiom-encode c326d1ac0acdb557f047a3054160b19dd72602fa; axiom-rules-engine 05eac9d2f89dabe5c6673176260762cef3a58f47, built from the exact pinned source in scratch. All three runs return success: true and empty failure lists.

File Existing New Passed
22.test.yaml 4 8 12/12
27.test.yaml 4 6 10/10
29.test.yaml 4 9 13/13
Total 12 23 35/35

Repository pytest tests -p no:cacheprovider: 26 passed, 2 skipped. git diff --check passes. Saved JSON logs, the reproducible runner, pinned-source metadata and the engine-build log are in a local scratch checkout; the completion report records their exact paths. These are synthetic companion tests; no paid encode, signing, oracle or survey-data run was made.

CI: Repository Checks is green and terminal: validate / shards, validate / validate (uk) and validate / validate passed; drift-alarm was skipped as expected on a pull request. Background gh pr checks --watch exited 0. The PR is ready for review and remains unmerged.

Scope

This follows the test-only companion pattern of #391. The atomic modules use claimant-specific slots (27.yaml:43, 22.yaml:151); reg 29(4)'s parenthetical is present (29.yaml:42). The tests establish these paths as encoded-correct for parity, conditional on correctly projected claimant inputs. They do not establish which members an upstream runtime places in those slots.

Queued separately: #404 covers claimant-only ProgramSpec carer composition and independent oracle projections; the scope comment on #389 covers reg 83 receipt/entitlement limbs. The atomic tests here do not close either queue.

🤖 Generated with Claude Code

Verification at the merged head (2026-10-12)

The verification links above describe the original 2026-10-01 head. Before merging, main was merged in (head faad423a). CI is green at that head, and an independent review re-checked all 23 expectations against the regulations: reg 22's 2026-04-06 table, reg 27, reg 29 and the reg 36 amounts. It confirmed that only the three companion files change.

Reg 27(4): one LCWRA element for joint claimants who both have LCWRA at
the same amount, the higher amount when the first is higher, only the
first's amount when only the first has LCWRA, and the pre-2026 amount
for a single claimant. Each claim type ignores the other type's slots.

Reg 29(4) parenthetical: a joint claimant who is a carer with LCWRA
keeps the carer element when the LCWRA element is included for the
other joint claimant, and has the LCWRA element only when it is not.
Reg 29(2): not both carer elements for the same severely disabled
person, when only one qualifies, or on a single claim.

Reg 22(1)(b): a work allowance from limited capability for work alone
(no child), for joint and single claimants, with and without housing
costs; no work allowance with neither; reg 22(3) for a member of a
couple claiming as a single person.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis merged commit b918260 into main Oct 12, 2026
4 checks passed
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Merged by the Axiom engineering hub at faad423 with --merge. Gates: gh pr checks exit 0; MERGEABLE; not draft. Reviewed head: faad423. Independent GPT-6.1 Sol review: APPROVE_WITH_NITS; all 23 companion expectations match UC Regs 2013 regs 22, 27, 29 and 36; no module changes. Body nits addressed.

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.

1 participant