Skip to content

Assess Oxford Universal Credit applicants on Appendix 3 income - #2794

Merged
juaristi22 merged 23 commits into
mainfrom
fix-2520-oxford-ctr-uc-income
Nov 5, 2026
Merged

juaristi22 merged 23 commits into
mainfrom
fix-2520-oxford-ctr-uc-income

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Nov 1, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #2520

What and why

In its Council Tax Reduction Scheme 2026 to 2027, Oxford City Council divides working-age applicants into two groups and bands each on weekly income (Part 1 para 9).

  • For an applicant without Universal Credit, the council calculates income "in accordance with paragraphs 14-27" and deducts "50% of contributions to occupational or personal pension schemes" from earnings (para 18). In the heading before para 14 it limits paragraphs 14 to 27 and Annexes 5 and 6 to pensioners and working-age applicants without Universal Credit.
  • For an applicant with Universal Credit, the council sets the income in Appendix 3. It adds "their net earned income (as provided by DWP) to the amount of Universal Credit awarded", ignores any transitional element and counts other (unearned) income weekly. It ignores "£48.15 of the Universal Credit carer element" and "£84.46 of the Universal Credit disabled child element". DWP deducts "any relievable pension contributions" in full when it calculates net earned income (UC Regs 2013 reg 55(5)(a)).

In oxford_council_tax_reduction the model banded every working-age applicant on council_tax_reduction_applicable_income, the paragraphs 14 to 27 income with Oxford's 50% share. So the model deducted half of a Universal Credit claimant's pension contributions instead of all of them, and left out their Child Benefit and child maintenance. A reform of Oxford's pension contribution share also moved their reduction.

This PR makes five changes.

  • Appendix 3 income. The model adds three amounts in a new variable, oxford_council_tax_reduction_universal_credit_income:

    • uc_earned_income_before_work_allowance, DWP's net earned income after tax, National Insurance and relievable pension contributions, before the work allowance;
    • oxford_council_tax_reduction_universal_credit_other_income, a new variable in which the model sums the applicant's and partner's receipts that it lists in a new parameter (below);
    • the award: universal_credit plus uc_deductions, the amount DWP awards before it takes deductions for debts out of the payment, less the element disregards and not below nil.

    For the four other councils (_legacy.py), the model counts Universal Credit's own unearned income and, since Count the UC award before debt deductions in four councils' CTR #2822, the award before deductions for debts. This PR leaves _legacy.py alone.

  • Other income. The model lists its variables one by one in gov.local_authorities.oxford.council_tax_reduction.universal_credit.other_income_sources, with the reason for each in the file.

  • Disregards. The model holds the weekly amounts from 1 April 2026 in two Oxford parameters: universal_credit.carer_element_disregard (£48.15) and universal_credit.disabled_child_element_disregard (£84.46).

  • Start date. The model switches the route on from 1 April 2026 through universal_credit.in_effect, which is false from 2015. The model reads each year's parameters at 30 April. So the Appendix 3 route starts in model year 2026, and in model years 2025 and earlier oxford_council_tax_reduction gives the results it gave before. A user can move the route with a reform of in_effect. The model gates only the route this way. The list and the two disregards start on 1 April 2026, and the model carries them back to 2015 like its other Oxford parameters. So the two new variables still return Appendix 3 amounts for earlier years, though the reduction does not read them. In 2025, the new variables give a lone parent earning £15,600 with two children and £2,600 of child maintenance other income of £4,851.60 and Appendix 3 income of £27,833.34. Paragraphs 14 to 27 still set their reduction, £1,800.

  • Banding and docs. In oxford_council_tax_reduction the model bands a Universal Credit applicant on a fifty-second of the Appendix 3 income. An applicant without Universal Credit keeps the same arithmetic, bit for bit, and the model still adds Oxford's tariff income only for them. This PR also rewrites the pension contribution share's variable and parameter documentation to name the applicants the share reaches.

The model builds the award's maximum amount (uc_maximum_amount) from the standard allowance and the child, disability, carer, housing and childcare elements, and nothing else. So the award holds no transitional element to remove.

Earlier schemes. In its 2025-26 scheme Oxford City Council sets an Appendix 3 with the same income rule. It tops the bands at £500, £575, £650 and £700, ignores £46.40 of Carer's Allowance in place of the two element disregards, and includes no transitional-element sentence. The model applies the 2026-27 parameters to every earlier year, so this PR keeps earlier years on their previous results and does not model 2025-26. The council's 2024-25 scheme pages at the same address return 404.

Readings

  • Other income. In Appendix 3 Oxford City Council lists the income it ignores and says "All other unearned income is taken into account". It ignores Child Benefit and child maintenance in Appendix 5, which "applies to pensioners and working-age applicants who do not receive Universal Credit". In Appendix 3 it repeats several items from that list, Attendance Allowance, Disability Living Allowance, Personal Independence Payment, Discretionary Housing Payments and Housing Benefit among them, but not those two. So the council counts Child Benefit and child maintenance for these applicants, along with the receipts DWP counts, and so does the model. For a receipt DWP counts, DWP takes each pound off the award and Oxford adds it back as other income. The two effects cancel while DWP's net earned income and the award's other terms stay fixed, no benefit cap applies and the award stays above nil after the disregards. A taxable receipt can break the first condition. In 2027, a 70-year-old earning £13,036.40, in a couple with a 60-year-old, loses £93.28 of Pension Tax Allowance when they receive £520 of private pension. DWP's net earned income then falls £93.28, the award £468.70 and the Appendix 3 income £41.98.
  • Miscellaneous income. The model counts miscellaneous income in DWP's net earned income (uc_individual_earned_income_before_mif) and leaves it off the list, so it counts the income once. DWP counts miscellaneous income as unearned income (reg 66(1)(m)). If UC counts royalties, trust income and overseas pensions in miscellaneous_income as earned income #1961 moves the model's figure there, the model will take it off the award pound for pound, as DWP does, and must add it back to the list.
  • Carer Support from Scotland. Social Security Scotland keeps paying Carer Support for 13 weeks after a carer moves to another part of the United Kingdom (SSI 2023/302 reg 42). It pays the Scottish Carer Supplement for each week it pays the carer support payment (reg 14A). DWP counts the carer support payment only up to a year of Carer's Allowance (reg 66(1)(b)(iiia)) and does not count the supplement. Oxford City Council ignores the part above Carer's Allowance only in Appendix 5, so the model counts both payments whole.
  • One-off receipts. In Appendix 6 Oxford City Council names some one-off payments as capital: the first month's Bereavement Support Payment, Energy Rebate Scheme 2022 payments, "any other payments made by the Government to help with the cost of living" and payments for a personal injury. The model reads the council's capital and income lists together. It keeps out of Appendix 3 income a one-off payment that attaches to no period and that the council names in Appendix 6. It counts regular Bereavement Support Payment and Armed Forces Compensation Scheme payments, Guaranteed Income Payments included: the model reads bsp_reported and afcs_reported as regular payments and counts bsp and afcs whole. If a user enters a lump sum in either input, the model counts it as income.
  • Capital. Oxford City Council treats "any income derived from capital" as capital (para 30 and Annex 7) and sets no other rule for it in Appendix 3, so the model leaves out interest, dividends and rent. DWP deems an assumed yield from capital (uc_tariff_income, reg 72) and takes it off the award, but nobody receives it, so the model does not add it back. The council adds its own assumed income only under paragraphs 14 to 27 (para 15), and ignores capital "already taken into account when the applicant is receiving Universal Credit" (Appendix 6). So the council counts capital for these applicants only through the award DWP reduces. Oxford City Council publishes nothing on its practice for Child Benefit or capital beyond the scheme text.
  • Whose income. Oxford City Council counts "the income of the applicant and, where appropriate, their partner" (Appendix 3). The model counts each person's receipts for the Council Tax Reduction applicant and partner, as council_tax_reduction_applicable_income does, so a younger partner's receipts count and a 17-year-old's do not. A household head who applies alone has no award, so the council assesses them under paragraphs 14 to 27 on their own income, without the benefit unit's Child Benefit.
  • Who has an award. In Appendix 3 Oxford City Council also covers an applicant whose award DWP reduces to nil through deductions or other adjustments. The model puts a family on this route when DWP pays it Universal Credit. It does the same when the family claims Universal Credit and the benefit cap or deductions for debts take its award to nil (council_tax_reduction_universal_credit_award, which Treat income derived from capital as capital in the legacy means tests #1995 added).
  • DWP figures. The model reads "net earned income (as provided by DWP)" as the earned income DWP uses in the Universal Credit calculation. For a self-employed claimant DWP uses the minimum income floor where it applies (UC Regs 2013 reg 62), and so does the model.
  • Award before deductions for debts. Oxford City Council counts "the amount of Universal Credit awarded" and, in Appendix 3's first sentence, names deductions apart from the award. So the model adds back uc_deductions (the deductions for debts DWP takes from the payment), and a reform of those deductions does not move Oxford reductions. DWP applies the benefit cap to the award itself, so the model keeps the capped award.
  • One disregard for each element. £48.15 and £84.46 match the 2026-27 carer premium and disabled child premium. Councils include the carer premium in Housing Benefit "in respect of each person" who meets the carer condition. They include the disabled child premium for "each child or young person" who meets its condition (HB Regs 2006 Sch 3 para 20(7) and (8)). DWP includes a carer element for each claimant who cares (reg 29) and a disabled child addition for each disabled child (reg 24(2)). So the model ignores up to each amount for each element, taking it off the award but not below nil.

The model treats these receipts as follows:

Variable Appendix 3 income Oxford text
child_benefit counted Oxford City Council applies its Appendix 5 disregard only without Universal Credit
maintenance_income (child maintenance received) counted Oxford City Council applies its Appendix 5 disregard only without Universal Credit
spousal_maintenance_income, private_pension_income, state_pension, carers_allowance, carer_support_payment, jsa_contrib, esa_contrib, maternity_allowance, iidb, widowed_parents_allowance, incapacity_benefit, sda counted "All other unearned income"; the receipts DWP counts as unearned income (reg 66). The council gives its £15 disregards only without Universal Credit (Appendix 5)
scottish_carer_supplement counted "All other unearned income"; Social Security Scotland pays it with the carer support payment, for 13 weeks after a move from Scotland. The model pays 52 weeks (Limits)
bsp, afcs, war_widows_pension, armed_forces_independence_payment, ssmg, healthy_start_vouchers, private_transfer_income counted "All other unearned income"; the council names none of them in Appendix 3, and applies its war pension, Armed Forces Independence Payment and Healthy Start disregards only without Universal Credit. The model reads bsp and afcs as regular payments
income_support, claimant_or_partner_jsa_income, claimant_or_partner_esa_income, tax_credits, pension_credit counted "All other unearned income"; DWP replaces these awards with Universal Credit, so a claimant receives none of them
miscellaneous_income in DWP's net earned income the model's Universal Credit earnings (#1961)
uc_tariff_income, Oxford's tariff income out an assumed yield, not a receipt; para 15
savings_interest_income, other_investment_income, tax_free_savings_income, dividend_income, individual_savings_account_dividend_income, property_income, capital_gains out para 30 and Annex 7: income derived from capital; the council also ignores rent from sub-tenants and boarders in Appendix 3
attendance_allowance, dla, pip, housing_benefit, council_tax_benefit out Oxford City Council ignores them in Appendix 3 (council_tax_benefit holds the reduction itself)
statutory_sick_pay, statutory_maternity_pay, statutory_paternity_pay in DWP's net earned income reg 55(4)
winter_fuel_allowance, winter_fuel_payment, cost_of_living_support_payment, energy_bills_rebate, household_energy_payment, epg_subsidy out one-off payments that attach to no period: Oxford City Council names Energy Rebate Scheme 2022 payments and other Government cost-of-living payments, such as the £100 Household Energy Payment, as capital in Appendix 6
student_loans, education_grants, student_payments, adult_dependants_grant, access_fund out Oxford City Council treats them under Annex 8, with its own rules and disregards; the model counts student income in no Council Tax Reduction scheme
adult_ema out Annex 8 keeps an educational maintenance allowance out of "grant", and Appendix 3 does not ignore it, so the council counts one the applicant or partner receives (Limits)
child_ema out a child's receipt; the council counts only the applicant's and partner's income
scottish_child_payment, two_child_limit_payment, pension_age_winter_heating_payment, pawhp; Guardian's Allowance out the model computes the Scottish ones only for households in Scotland; the model has no Guardian's Allowance

When a lone parent earning £15,600 with two children receives £520 more of a listed source in 2026, DWP's net earned income and the income tax DWP deducts from it stay the same. For each receipt DWP counts, DWP lowers the award by £520, and the Appendix 3 income stays the same. For each other listed source, the award stays the same and the Appendix 3 income rises £520. With Carer's Allowance, the model also adds the carer element (£2,512.08) to the award, and Oxford ignores £2,503.80 of it, so the Appendix 3 income rises £8.28. With the carer support payment, the model adds the carer element and also pays its £608.40 supplement, so other income rises £1,128.40 and the Appendix 3 income £616.68. The carer support payment gives Carer's Allowance's £8.28 only with the supplement held fixed. The model now counts miscellaneous income only in DWP's net earned income: £520 more raises that figure by £416 after income tax, lowers the award by £228.80 and raises the Appendix 3 income by £187.20.

This family shows none of three other routes:

  • Where the model computes Carer's Allowance, DWP reduces it by maternity allowance, contributory JSA or ESA, incapacity benefit, severe disablement allowance, Widowed Parent's Allowance or State Pension (Overlapping Benefits Regs 1979 reg 12). So £520 more of one of them leaves other income, the award and the Appendix 3 income unchanged.
  • Where the benefit cap applies, a receipt can lift it. In a capped Oxford family in the South East, the model keeps the cap on with £520 of War Widow's Pension, though reg 83(1)(d) lifts it, so the Appendix 3 income rises £520. With £520 of the Armed Forces Compensation Scheme it lifts the cap, and the Appendix 3 income rises £12,808.84.
  • In 2027 a taxable receipt can cut the Pension Tax Allowance, as under Readings.

Limits.

  • For a disabled applicant, the council also ignores an amount equal to any disability premium payable before the move to Universal Credit. The model holds no record of that earlier award and ignores nothing, so it can overstate such an applicant's income and understate their reduction.
  • The council counts students' loans and grants under Annex 8, with its own disregards, and counts an educational maintenance allowance the applicant or partner receives as other income. DWP counts student income in the award (reg 66(1)(e)). The model counts none of them, so it can misstate a student's income and reduction.
  • The model counts bsp and afcs whole, so if a user enters a lump sum there, the model counts it as income.
  • The model pays the Scottish Carer Supplement for 52 weeks whenever the carer support payment is positive. An Oxford household receives at most 13 weeks of it (SSI 2023/302 regs 14A and 42), or 25 after a death in the run-on. For a lone parent of two with housing costs of £12,560 and 13 weeks of Carer Support, the model's £608.40 of supplement gives band 3 and £900. The law's 13 weeks, £152.10, give band 2 and £1,350.

Overlap with other work

Of the 76 open pull requests, one touches this PR's files. #1966 (draft, ctr-working-age-shortfall) conflicts with this branch in the council_tax_reduction_pension_contribution_deduction_rate documentation: keep #1966's Wales and Scotland route and this PR's Oxford sentence. #1966 also conflicts with main in three files this PR does not touch.

We merged main at acba5efc1 into this branch, bringing in #1995 and #2822. With #1995 the model ignores capital for Universal Credit and passported applicants under Appendix 6, and looks up council_tax_reduction_relevant_income_based_benefit above that rule in oxford_council_tax_reduction.py. We kept both in the merge, with this PR's Appendix 3 block below them and no second lookup.

Invariants

Invariants 1 to 6 and 8 hold for every working-age Oxford family whose applicant has a Universal Credit award, from 2026. Invariant 7 covers earlier years, and invariant 9 families without an award.

  1. Locality. No reform of Oxford's pension contribution share changes the family's Oxford reduction, while every Oxford family reads the reform's share.
  2. Appendix 3 income.
    • Other income is the family's Child Benefit at HMRC's rates plus child and spousal maintenance and its other listed receipts, with no interest, dividends, rent or assumed yield.
    • The income is net earned income plus other income plus the award before deductions for debts, less ignored amounts.
    • The ignored amounts are never negative and never exceed the award or the elements. They are at most £48.15 a week for each carer element and £84.46 a week for each disabled child, and nil with no such element.
  3. Bands. The reduction is the council tax share times the rate Oxford City Council sets in its band table for a fifty-second of the income, less non-dependant deductions.
  4. Pound for pound. While the award stays above nil after the disregards, no benefit cap applies, and DWP's net earned income and the award's other terms stay the same:
    • £1 more of a receipt DWP deducts from the award (spousal maintenance, a private pension) leaves the income unchanged, because DWP lowers the award by £1;
    • £1 more of Child Benefit or child maintenance raises it by £1;
    • £1 more interest leaves it unchanged;
    • more capital lowers it by the rise in DWP's assumed yield.
  5. Monotonicity. More pension contributions never lower the reduction of a family that keeps its award.
  6. Differential with the other councils. Swap Oxford's other income in the Appendix 3 income for Universal Credit's unearned income. For a family with no carer or disabled child element and no capital, the result equals the Universal Credit income behind the awards of Merton, Kingston upon Thames, Newham and Westminster. Those councils, like Oxford, count the award before deductions for debts.
  7. Earlier years. In model years 2025 and earlier, every family's Oxford reduction equals origin/main's. A family with an award keeps the band of its paragraphs 14 to 27 income less Child Benefit, with no tariff income.
  8. Each receipt once. More of a receipt Oxford City Council counts as other income, with every other receipt held fixed, raises other income by the whole amount, including a carer support payment above DWP's cap. It leaves DWP's net earned income unchanged while the income tax DWP deducts stays fixed. A receipt DWP takes off Carer's Allowance under the overlapping-benefit rules raises other income by the net amount: nothing, where DWP takes the whole receipt off. The model adds miscellaneous income to DWP's earned-income calculation, where a minimum income floor can absorb it, and leaves other income unchanged. The model leaves interest, dividends and rent out of other income; their effect on DWP's net earned income depends on the income tax DWP deducts. Receipts of anyone but the applicant and partner never change other income.
  9. Differential with origin/main. In 2026, every family not on Universal Credit gets origin/main's Oxford reduction, bit for bit.

Test plan

  • For policy changes: YAML tests whose expected values come from an external source.

    • oxford_council_tax_reduction_universal_credit.yaml holds 36 cases, and oxford_council_tax_reduction_universal_credit_earlier_years.yaml holds 9. Each case shows hand-worked arithmetic from the scheme text, DWP's and HMRC's rates for the year and the income tax and National Insurance rules, citing the paragraph.
    • The 2026 cases cover the Appendix 3 income with pension contributions, two reforms of the Oxford share and a lone parent before the work allowance. They cover the carer and disabled child disregards (one carer, two carers, the floor at nil, one disregard for each child) and the award before deductions for debts. They also cover Child Benefit, child maintenance, spousal maintenance, a private pension, miscellaneous income, a regular Armed Forces Compensation Scheme payment, interest, dividends, rent, and capital of £11,250 and £16,000.
    • Seven cases test whose receipts count and how. A younger partner's child maintenance counts, and a 17-year-old's private transfers do not. Personal Independence Payment, Attendance Allowance and Disability Living Allowance stay out. A self-employed claimant under the minimum income floor counts the floor's £20,386.03, not the £5,000 they earn. A carer whose Carer's Allowance the model computes, £4,495.40 less £2,600 of Widowed Parent's Allowance, counts the £1,895.40 DWP pays.
    • Two cases follow carers who move from Scotland, and each supplies the supplement. One receives 13 weeks of it with 13 weeks of carer support payment, and one receives a carer support payment above DWP's cap. A household head who applies alone keeps her own income, without the couple's award. Two cases without Universal Credit keep origin/main's results.
    • The earlier-years cases pin 2024 and 2025 to origin/main's results for a single claimant, a parent with Child Benefit and a parent with child maintenance. They also check that reforms of in_effect move the route in 2025 and 2026.
    • All 36 and all 9 pass at aa2f0a579 (39.17 s and 82.37 s), and at d5403d70a, whose tests and model match. Every mutant in the table below fails at least one 2026 case, except two that agree with the code on every lawful input.
  • Property tests: test_oxford_council_tax_reduction_universal_credit_properties.py holds 7 test functions, one for each of invariants 1 to 8 (invariants 2 and 3 share one). Each runs 5 generated populations plus its explicit examples, with Hypothesis derandomised. Every formula and every list entry stand as they did at 290b095e6. 2343a7861 changes only invariant 6's test. Its oracle no longer takes uc_deductions off the Appendix 3 income, and the test gains an explicit example of a single claimant who repays debts at a quarter of the standard allowance.

    • At 2343a7861, one -n 4 run of the whole file: 7 passed in 167.18 s. The locality test took 114.28 s, test_more_pension_contributions_never_lower_the_reduction 71.10 s, test_appendix_3_income_and_band 43.82 s, test_pound_for_pound 37.47 s, test_appendix_3_income_matches_the_other_councils_universal_credit_income 36.81 s, test_each_receipt_counts_once 33.42 s and test_earlier_years_keep_the_paragraphs_14_to_27_income 29.58 s.
    • With only the explicit examples run, the debt example fails by £1,274.69 when the oracle takes off uc_deductions (£1,274.70), and passes with the oracle as it stands. The family keeps its award, and each other council's award falls below its maximum, so the test reads back its income at all four councils.
    • test_each_receipt_counts_once supplies each of 31 receipts, written out from the scheme rather than read from the parameter, to the last adult of each generated family and, for person-level receipts, to the first child. With the new test file, it fails at ae9bbabd1, this branch before the miscellaneous income and Scottish Carer Supplement changes: the supplement moves other income by £0, not £520. On origin/main (2da212abc) it fails on its first explicit example: "Variable oxford_council_tax_reduction_universal_credit_other_income does not exist".
    • The generated families give each adult receipt to the last adult, the eldest, who heads the benefit unit, and supply Carer's Allowance and the supplement as inputs. They hold no 16-to-19-year-old, self-employment or disability benefit, so the seven route cases above cover those.
  • Mutations: each ran in its own copy of d5403d70a, one at a time, under a 2 GB memory cap, against the 36 cases of the 2026 YAML file.

    Mutant 2026 YAML (36 cases) Property test run against it
    Other income read from uc_unearned_income 23 failed test_appendix_3_income_and_band fails (290b095e6)
    One carer disregard for the award 1 failed: the couple who both care, 26,680.50 instead of 24,176.70 not run
    Benefit unit's awards counted for a head who applies alone 1 failed: her other income, 28,806.60 instead of 27,400 not run
    DWP's figures and the award counted for a head who applies alone 1 failed: her Appendix 3 income, 37,387.36 instead of 27,400 not run
    uc_tariff_income added to the list 2 failed: the assumed yield and £16,000 capital cases not run
    afcs removed from the list 1 failed: the Armed Forces Compensation Scheme case, other income 2,337.40 instead of 4,937.40 test_each_receipt_counts_once fails on afcs (290b095e6)
    carer_support_payment replaced by DWP's capped uc_unearned_carer_support_payment 1 failed: the carer support payment above DWP's cap, other income 7,441.20 instead of 8,145.80 test_each_receipt_counts_once fails (290b095e6)
    miscellaneous_income put back on the list 1 failed: the miscellaneous income case, other income 4,937.40 instead of 2,337.40 test_each_receipt_counts_once fails (290b095e6)
    scottish_carer_supplement removed from the list 2 failed: the two Scottish carer cases test_each_receipt_counts_once fails (290b095e6)
    Other income counts every member aged 16 or over, not the applicant and partner 1 failed: the 17-year-old's receipt, other income 4,937.40 instead of 2,337.40 not run
    Other income counts the benefit unit head's receipts alone 1 failed: the younger partner's maintenance, other income 1,406.60 instead of 4,006.60 not run
    pip and attendance_allowance added to the list 2 failed: the two cases, other income 4,937.40 instead of 2,337.40 and 7,600 instead of 5,000 not run
    Appendix 3 reads each claimant's earned income before the minimum income floor 1 failed: the floor case, Appendix 3 income 11,386.48 instead of 26,772.51 not run
    The supplement counts only beside a carer support payment 36 passed test_each_receipt_counts_once fails on scottish_carer_supplement, which it supplies with no carer support payment (d5403d70a)
    tax_credits taken off the list 36 passed test_each_receipt_counts_once fails on tax_credits (7fa10f27e)

    The miscellaneous income and supplement removal mutants undo this PR's two list changes. Social Security Scotland pays the supplement only in weeks it pays the carer support payment (reg 14A), and no claimant receives tax credits beside Universal Credit. So no lawful YAML case tells the last two mutants from the code.

  • Differential against origin/main (2da212abc), with this branch at 7238eba63, on 400 generated Oxford households and 497 benefit units, for 2024, 2025 and 2026. numpy.random.default_rng(2520) draws one or two adults with earnings, pension contributions, self-employment, spousal maintenance, private pensions and carers. It adds up to two children, some disabled, a non-dependant in a quarter of households, housing costs and savings of 0 to 17,000, and default_rng(25200) adds child maintenance and interest.

    • 2024 and 2025: all 497 benefit units get origin/main's Oxford reduction, and all 400 households its Council Tax Reduction, bit for bit.
    • 2026: all 378 benefit units without a Universal Credit award match bit for bit; 123 of them get a reduction. Of the 108 working-age claimant families with an award, 6 rise (+£4,000) and 29 fall (−£19,850), −£15,850 in all and −£146.76 per claimant family. 25 of the 29 that fall receive Child Benefit.
    • Later commits change two list entries (miscellaneous income out, the Scottish Carer Supplement in), tests and documentation, and no formula. The population holds no miscellaneous income, and the model pays no carer support payment or Scottish Carer Supplement in Oxford, so those entries cannot move its results. At 7fa10f27e its 2026 arrays for the reduction, the award, other income, Appendix 3 income and household Council Tax Reduction match ae9bbabd1's bit for bit.
  • Existing tests: test_parameter_descriptions.py, 24 passed at aa2f0a579. At ae9bbabd1, the policy/baseline/gov/local_authorities YAML tree passed 403 cases and test_council_tax_reduction_applicant_properties.py 2 tests. At 7fa10f27e, the tree's 113 cases outside oxford/ that hold an Oxford household passed, and so did test_council_tax_reduction_assesses_the_liable_head. At aa2f0a579, test_head_applying_alone_matches_her_own_benefit_unit 1 passed in 2,188.36 s. No Oxford case outside oxford/ holds miscellaneous income, a carer support payment or the supplement, so the later list changes cannot reach them. At 2343a7861, the policy/baseline/gov/local_authorities YAML tree passed 429 cases in one policyengine-core test run, test_council_tax_reduction_applicant_properties.py 2 tests and code_health 3,150 tests.

  • At 2343a7861, ruff format --check ., ruff check . and ruff check --select F811,F821 policyengine_uk (ruff 0.17.2) pass, and git diff --check finds nothing in the PR's diff. The branch merges with main at af9361114 without conflicts.

  • Changelog fragment changelog.d/2520.fixed.md.

  • 19378b97f rewrites one variable's documentation and changes no code: its syntax tree, with documentation removed, matches aa2f0a579's.

No survey data: every simulation uses hand-built situations.

Follow-ups: #2789 (Oxford's route before April 2026), #2790 (student income), #2791 (Scottish Carer Supplement weeks), #2792 (War Widow's Pension and the benefit cap) and #2793 (the ESA support component and the benefit cap).

Reproducer

Reproducer: policyengine_uk/tests/test_oxford_council_tax_reduction_universal_credit_properties.py::test_each_receipt_counts_once; policyengine_uk/tests/policy/baseline/gov/local_authorities/oxford/council_tax_reduction/oxford_council_tax_reduction_universal_credit.yaml; policyengine_uk/tests/policy/baseline/gov/local_authorities/oxford/council_tax_reduction/oxford_council_tax_reduction_universal_credit_earlier_years.yaml

axiom: TheAxiomFoundation/rulespec-uk#513 queued

🤖 Generated with Claude Code

MaxGhenis and others added 21 commits October 31, 2026 05:34
Oxford's Council Tax Reduction scheme 2026-27 bands a working-age applicant
who receives Universal Credit on Appendix 3's income: DWP's net earned income
plus the Universal Credit awarded, with other income counted weekly. Its
paragraphs 14 to 27, with their 50% share of pension contributions (para 18),
apply only to applicants without Universal Credit. The model banded every
working-age applicant on the paragraphs 14 to 27 income.

oxford_council_tax_reduction_universal_credit_income adds Universal Credit's
earned income before the work allowance (which deducts relievable pension
contributions in full, UC Regs 2013 reg 55(5)(a)), its unearned income and
the award, the three amounts the four other councils use. Oxford's award
bands a Universal Credit applicant on a fifty-second of it, so a reform of
Oxford's pension contribution share no longer moves them. Applicants without
Universal Credit keep the same arithmetic.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Appendix 3 of Oxford's Council Tax Reduction scheme 2026-27 ignores £48.15 of
the Universal Credit carer element and £84.46 of the disabled child element,
the 2026-27 carer and disabled child premiums. Two Oxford parameters hold the
weekly amounts. The Appendix 3 income ignores up to each amount for each
carer element and each disabled child addition, taking it off the award but
not below nil.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Hypothesis tests over generated Oxford families on Universal Credit: a reform
of Oxford's pension contribution share leaves their reductions unchanged;
the Appendix 3 income is DWP's net earned income, unearned income and the
award less disregards bounded by the elements; the scheme's band table sets
the reduction; more pension contributions never lower it; and the income
equals the Universal Credit income Merton, Kingston upon Thames, Newham and
Westminster use for the same family.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Cite HB Regs 2006 Sch 3 para 20(7) and (8) for the carer and disabled child
premiums being given for each carer and each disabled child.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Appendix 3 counts "the amount of Universal Credit awarded". The model's
deductions for debts (uc_deductions) come out of the payment, not the
award, so the Appendix 3 income adds them back and a reform of those
deductions no longer moves Oxford reductions. The property tests now check
the disregards exactly against DWP's 2026-27 additions, draw deduction
rates, and recover the other councils' income net of deductions. The
documentation names Universal Credit's assumed yield from capital as part
of the other income, and the changelog says current-law reductions move.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Appendix 3 takes "All other unearned income" into account, and Appendix 5's
Child Benefit and child maintenance disregards apply only to applicants
without Universal Credit. A new Oxford parameter, universal_credit.
other_income_sources, lists the receipts counted, with the reason for each:
Child Benefit, child maintenance, the receipts in Universal Credit's
unearned income, and the other unearned income Appendix 3 does not ignore.
Universal Credit's assumed yield from capital and income derived from
capital (para 30 and Annex 7) stay out. The income is the applicant's and
partner's; a household head who applies alone counts only their own.

The model holds Oxford's 2026-27 scheme, so universal_credit.in_effect
turns the Appendix 3 route on from April 2026 and earlier years keep the
results they had before. YAML cases work the income by hand for Child
Benefit, child and spousal maintenance, a private pension, interest,
dividends, rent, capital, two carers and a head applying alone, and pin
2024 and 2025 and reforms that move the start.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The income property now works other income from the family's own receipts
and HMRC's Child Benefit rates, so counting Universal Credit's unearned
income in its place fails it. A new property adds £520 of each kind of
receipt and £1,000 of capital: receipts Universal Credit deducts leave the
income unchanged, Child Benefit and child maintenance raise it by £520,
interest leaves it unchanged, and capital lowers it by the rise in the
assumed yield. Another checks that 2025 keeps the paragraphs 14 to 27
income. The generated families now carry child maintenance, interest and
capital, and the changelog describes the other income and the start date.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The YAML cases' couple who both care and a claimant repaying debts join the
Appendix 3 income property as an explicit example, so one carer disregard
for the couple or the award after deductions fails it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Child Benefit variant supplies Child Benefit, and a variable supplied
for some families reads as nil for the rest, so every family in the
property now gets its Child Benefit at HMRC's rates as an input. The
property also holds DWP's net earned income fixed between a family and its
variant.

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

The model already counts miscellaneous income in DWP's net earned income,
so Oxford's Appendix 3 other income no longer adds it a second time. Social
Security Scotland pays the Scottish Carer Supplement with the carer support
payment, including for 13 weeks after a carer moves to England (SSI
2023/302 regs 14A and 42), and Oxford City Council does not ignore it, so
the list now counts it.

New hand-worked YAML cases cover miscellaneous income, a regular Armed
Forces Compensation Scheme payment, the supplement the model pays and a
supplied 13 weeks of it, a carer support payment above DWP's cap, and the
Appendix 3 income of a household head who applies alone. The parameter
descriptions and the new variables' documentation name Oxford City Council
and DWP as the actors and state the one-off receipts limit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A new property supplies each receipt to generated Universal Credit
families, from a list written out from the scheme rather than read from
the parameter. More of a receipt Oxford City Council counts raises other
income by the whole amount, a carer support payment above DWP's cap
included, and leaves DWP's net earned income alone. Miscellaneous income
reaches only DWP's net earned income, income from capital reaches neither,
and a child's receipts never count.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r and changelog

The YAML file's header now gives the scheme's actions to Oxford City
Council and DWP and notes that DWP applies no benefit cap to an award with
a carer element (reg 83(1)(j)). The changelog fragment adds the Scottish
Carer Supplement and miscellaneous income.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The model pays the supplement for 52 weeks whenever the carer support
payment is positive, while Social Security Scotland pays it for each award
week of Carer Support, at most 13 weeks after a move from Scotland (SSI
2023/302 regs 14A and 42). Drop the case that pinned the model's 52 weeks
and supply the supplement in the two remaining cases, so a fix to
scottish_carer_supplement moves no Oxford case.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add hand-worked 2026 cases for a younger partner's receipt, a
17-year-old's receipt, Personal Independence Payment, Attendance Allowance
and Disability Living Allowance, a self-employed claimant under the minimum
income floor, and a Carer's Allowance the model computes and reduces for
Widowed Parent's Allowance.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DWP counts miscellaneous income as unearned income (UC Regs 2013 reg
66(1)(m)); the model counts it in uc_individual_earned_income_before_mif
(#1961). Correct the other-income documentation, and name the model as the
actor that lists the sources.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Say the model reads bsp_reported and afcs_reported as regular payments,
that a user enters a lump sum, and that the model, not the list, leaves
receipts out. Name backdate_parameters as what carries the 2026-27 values
back.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Break the other-income documentation, the parameter description and
comments, the income variable's disability premium sentence and the
changelog fragment into one thought per sentence. No formula, list entry or
value changes.

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

github-actions Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Aggregate impact on certified data: pass

Base af93611144 against head 8a10c7f9d9, both on enhanced_frs_2024_25.h5 (policyengine-uk-data 1.58.1, sha256 056e80fd8e91), fiscal years 2025-26 to 2031-32. Each year is a full microsimulation run on each side.

Checks: 0 broken by this change, 1 failing on both sides, 0 fixed. Moves flagged for review: 0 (thresholds in report_spec.yaml; a flag does not fail the job).

Workflow run and full report

Notes

  • In the years a figure from fewer than 10 records is suppressed (spending.disabled_students_allowance), every total containing it, and the decile incomes, are rebuilt from their other components, so no published total includes it. Those totals are marked †. A change is withheld where the two sides leave out different figures and can't be lined up.

Moves flagged for review

None.

Spending by benefit and service

Measure 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Disabled Students' Allowance suppressed suppressed suppressed suppressed suppressed suppressed suppressed

Caseloads

Measure 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Disabled Students' Allowance suppressed suppressed suppressed suppressed suppressed suppressed suppressed

Household net income by decile

No household's net income changes in any year.

No change in any year: receipts by tax head; government balance, each component counted once; model totals; household income totals; population; poverty rates; people in poverty; inequality; 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.

Checks failing on both base and head (1)
  • VAT excluding private school fees is never negative (sign:vat): 2025-26: 76 units below zero, a weighted £-53,888,684 in total; 2026-27: 76 units below zero, a weighted £-55,777,260 in total; 2027-28: 76 units below zero, a weighted £-57,727,917 in total
Counted-once check

Each of 92 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.

  • widowed_parents_allowance: pension_credit responds only through other heads in fewer than 10 households (other heads that moved there: carers_allowance; gov_spending; not a failure)
  • widowed_parents_allowance: pension_credit responds only through other heads in fewer than 10 households (other heads that moved there: carers_allowance; household_benefits; not a failure)
Provenance
Side Commit Runtime Environment hash Partition hash Time
base main af93611144 uk 2.174.4 (files fd9a1c311618), core 3.34.1, py 3.13.18 aarch64 a4d0aba37b1e 7cb61324a46b 2364.51s
head #2794 merged into main 8a10c7f9d9 uk 2.174.4 (files 6c70661a4152), core 3.34.1, py 3.13.18 aarch64 a4d0aba37b1e 7cb61324a46b 2348.07s

Dataset: hf://policyengine/policyengine-uk-data-private/enhanced_frs_2024_25.h5@2526edbbb687a3b54dbb11272e5389e4b62d2ac2, sha256 056e80fd8e9151d78f432a25cde863340baee81304c6216a37fb575ce8563784 (verified on both sides), policyengine-uk-data 1.58.1.

Receipts by tax head: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Final charge on cash interest in non-cash ISAs £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Lifetime ISA withdrawal charge £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Income tax £294.46bn £315.23bn £335.82bn £351.28bn £366.96bn £385.36bn £399.99bn
National Insurance (employee and self-employed) £51.70bn £54.14bn £56.13bn £57.73bn £59.76bn £61.64bn £63.51bn
National Insurance (employer) £148.71bn £155.37bn £160.88bn £165.09bn £172.06bn £177.36bn £182.57bn
Employer NI change borne by capital £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Employer NI change borne by consumers £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Capital gains tax £12.60bn £13.15bn £13.60bn £14.11bn £14.67bn £15.24bn £15.80bn
Student loan repayments £7.82bn £8.13bn £8.39bn £8.58bn £8.79bn £9.04bn £9.29bn
VAT excluding private school fees £249.37bn £256.87bn £266.33bn £272.70bn £278.97bn £285.24bn £291.59bn
Change in VAT from its baseline £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
VAT on private school fees £1.95bn £2.01bn £2.09bn £2.14bn £2.20bn £2.26bn £2.31bn
Change in private school VAT from its baseline £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Fuel duties £24.71bn £24.13bn £26.00bn £26.83bn £26.51bn £25.78bn £24.63bn
Alcohol duties £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Tobacco duties £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Vehicle excise duties £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Betting and gaming duties £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
TV licence fee £4.26bn £4.40bn £4.41bn £4.42bn £4.43bn £4.44bn £4.45bn
Council tax £49.21bn £52.16bn £54.89bn £57.95bn £61.16bn £64.47bn £67.91bn
High value council tax surcharge £0.00bn £0.00bn £0.00bn £0.48bn £0.49bn £0.50bn £0.51bn
Northern Ireland domestic rates £0.55bn £0.58bn £0.60bn £0.63bn £0.66bn £0.69bn £0.72bn
Business rates £34.68bn £36.20bn £38.00bn £39.46bn £42.27bn £43.25bn £44.29bn
Stamp duty land tax on the household's own purchases £6.88bn £7.32bn £7.66bn £8.06bn £8.47bn £8.91bn £9.35bn
Stamp duty land tax paid by companies £4.72bn £4.57bn £5.29bn £6.03bn £6.37bn £6.92bn £7.45bn
Land transaction tax (Wales) £0.07bn £0.08bn £0.08bn £0.09bn £0.10bn £0.10bn £0.11bn
Land and buildings transaction tax (Scotland) £0.31bn £0.32bn £0.33bn £0.35bn £0.36bn £0.38bn £0.40bn
Unspecified tax change borne by capital £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Unspecified tax change borne by consumers £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Wealth tax £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Wealth tax excluding the main residence £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Land value tax £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Carbon tax £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Spending by benefit and service: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Lifetime ISA bonus £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
State Pension £121.68bn £125.92bn £126.72bn £129.48bn £132.98bn £136.65bn £140.41bn
Pension Credit £6.21bn £6.46bn £6.68bn £6.82bn £6.89bn £7.07bn £7.22bn
Winter Fuel Payment £1.86bn £1.85bn £1.79bn £1.77bn £1.78bn £1.78bn £1.78bn
Pension Age Winter Heating Payment (Scotland) £0.19bn £0.20bn £0.20bn £0.21bn £0.21bn £0.22bn £0.22bn
Universal Credit £75.48bn £80.52bn £82.95bn £84.96bn £86.11bn £87.61bn £88.21bn
Housing Benefit £8.56bn £8.89bn £9.23bn £9.46bn £9.69bn £9.99bn £10.27bn
Council Tax Reduction £2.07bn £2.20bn £2.32bn £2.45bn £2.59bn £2.73bn £2.87bn
Employment and Support Allowance (income-related) £0.79bn £0.82bn £0.84bn £0.86bn £0.88bn £0.90bn £0.92bn
Employment and Support Allowance (contribution-based) £5.20bn £5.37bn £5.56bn £5.69bn £5.82bn £5.95bn £6.09bn
Jobseeker's Allowance (income-based) £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Jobseeker's Allowance (contribution-based) £0.29bn £0.30bn £0.31bn £0.31bn £0.32bn £0.33bn £0.34bn
Income Support £0.11bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Working Tax Credit £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Child Tax Credit £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Incapacity Benefit £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Personal Independence Payment £26.95bn £28.03bn £29.05bn £30.09bn £30.75bn £31.51bn £32.21bn
Disability Living Allowance £7.49bn £7.79bn £8.07bn £8.36bn £8.55bn £8.76bn £8.95bn
Attendance Allowance £8.68bn £9.03bn £9.36bn £9.69bn £9.90bn £10.15bn £10.38bn
Carer's Allowance £4.48bn £4.66bn £4.83bn £5.00bn £5.11bn £5.27bn £5.42bn
Carer Support Payment (Scotland) £0.31bn £0.32bn £0.33bn £0.34bn £0.35bn £0.36bn £0.37bn
Carer's Allowance Supplement (Scotland) £0.00bn £0.04bn £0.04bn £0.05bn £0.05bn £0.05bn £0.05bn
Severe Disablement Allowance £0.03bn £0.03bn £0.03bn £0.03bn £0.03bn £0.03bn £0.03bn
Industrial Injuries Disablement Benefit £0.50bn £0.52bn £0.54bn £0.55bn £0.56bn £0.58bn £0.59bn
Armed Forces Compensation Scheme £0.61bn £0.63bn £0.65bn £0.66bn £0.68bn £0.69bn £0.71bn
War Widow's or Widower's Pension £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Child Benefit £16.19bn £16.82bn £17.39bn £18.00bn £18.39bn £18.84bn £19.25bn
Scottish Child Payment £0.49bn £0.52bn £0.53bn £0.55bn £0.56bn £0.57bn £0.56bn
Two Child Limit Payment (Scotland, counterfactual) £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Healthy Start vouchers £0.05bn £0.05bn £0.05bn £0.05bn £0.05bn £0.05bn £0.05bn
Maternity Allowance £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Statutory Maternity Pay £3.30bn £3.41bn £3.54bn £3.62bn £3.70bn £3.78bn £3.87bn
Statutory Paternity Pay £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Statutory Sick Pay £1.12bn £1.16bn £1.20bn £1.23bn £1.26bn £1.29bn £1.32bn
Sure Start Maternity Grant £0.01bn £0.01bn £0.01bn £0.01bn £0.01bn £0.01bn £0.01bn
Bereavement Support Payment £0.67bn £0.69bn £0.71bn £0.73bn £0.75bn £0.76bn £0.78bn
Widowed Parent's Allowance £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Tax-Free Childcare £0.56bn £0.57bn £0.57bn £0.58bn £0.60bn £0.61bn £0.59bn
Extended childcare entitlement £2.99bn £3.50bn £3.59bn £3.71bn £3.78bn £3.86bn £3.93bn
Universal childcare entitlement £2.06bn £2.22bn £2.29bn £2.37bn £2.43bn £2.48bn £2.53bn
Targeted childcare entitlement £0.50bn £0.51bn £0.52bn £0.54bn £0.55bn £0.57bn £0.56bn
Childcare Offer for Wales £0.26bn £0.28bn £0.28bn £0.29bn £0.30bn £0.31bn £0.32bn
Care to Learn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Childcare Grant £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Parents' Learning Allowance £0.20bn £0.20bn £0.20bn £0.20bn £0.20bn £0.20bn £0.20bn
Adult Dependants' Grant £0.06bn £0.06bn £0.04bn £0.04bn £0.04bn £0.04bn £0.04bn
Travel Grant £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Disabled Students' Allowance suppressed suppressed suppressed suppressed suppressed suppressed suppressed
16 to 19 Bursary Fund £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
NHS spending £203.89bn £204.30bn £204.56bn £204.91bn £205.34bn £205.85bn £206.35bn
State education spending £0.02bn £0.02bn £0.02bn £0.02bn £0.02bn £0.02bn £0.02bn
Transport subsidy spending £25.05bn £25.10bn £25.14bn £25.18bn £25.23bn £25.30bn £25.36bn
Cost-of-living support payment £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Energy Bills Rebate £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Household Energy Payment £0.00bn £2.11bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Energy Price Guarantee subsidy £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Basic income £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Disability basic income £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Other public spending budget change £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Caseloads: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Lifetime ISA bonus 0k 0k 0k 0k 0k 0k 0k
State Pension 11,264k 11,145k 10,819k 10,700k 10,723k 10,750k 10,776k
Pension Credit 1,489k 1,484k 1,476k 1,454k 1,452k 1,457k 1,466k
Winter Fuel Payment 7,844k 7,783k 7,473k 7,375k 7,391k 7,409k 7,427k
Pension Age Winter Heating Payment (Scotland) 803k 802k 800k 797k 799k 801k 802k
Universal Credit 6,342k 6,347k 6,336k 6,297k 6,292k 6,271k 6,223k
Housing Benefit 1,249k 1,245k 1,244k 1,227k 1,227k 1,229k 1,232k
Council Tax Reduction 3,180k 3,200k 3,206k 3,219k 3,234k 3,245k 3,252k
Employment and Support Allowance (income-related) 71k 71k 71k 71k 71k 71k 71k
Employment and Support Allowance (contribution-based) 719k 720k 721k 722k 724k 726k 728k
Jobseeker's Allowance (income-based) 0k 0k 0k 0k 0k 0k 0k
Jobseeker's Allowance (contribution-based) 67k 67k 67k 67k 67k 68k 68k
Income Support 25k 0k 0k 0k 0k 0k 0k
Working Tax Credit 0k 0k 0k 0k 0k 0k 0k
Child Tax Credit 0k 0k 0k 0k 0k 0k 0k
Incapacity Benefit 0k 0k 0k 0k 0k 0k 0k
Personal Independence Payment 3,567k 3,575k 3,579k 3,585k 3,593k 3,602k 3,611k
Disability Living Allowance 1,291k 1,294k 1,296k 1,298k 1,300k 1,304k 1,307k
Attendance Allowance 1,695k 1,698k 1,700k 1,703k 1,707k 1,711k 1,715k
Carer's Allowance 1,034k 1,037k 1,038k 1,040k 1,042k 1,060k 1,062k
Carer Support Payment (Scotland) 71k 71k 71k 72k 72k 72k 72k
Carer's Allowance Supplement (Scotland) 0k 71k 71k 72k 72k 72k 72k
Severe Disablement Allowance 4k 4k 4k 4k 4k 4k 4k
Industrial Injuries Disablement Benefit 137k 137k 137k 138k 138k 138k 139k
Armed Forces Compensation Scheme 93k 93k 94k 94k 94k 94k 94k
War Widow's or Widower's Pension 0k 0k 0k 0k 0k 0k 0k
Child Benefit 8,123k 8,120k 8,120k 8,130k 8,145k 8,161k 8,178k
Scottish Child Payment 351k 352k 352k 353k 350k 348k 337k
Two Child Limit Payment (Scotland, counterfactual) 0k 0k 0k 0k 0k 0k 0k
Healthy Start vouchers 200k 200k 200k 201k 201k 201k 202k
Maternity Allowance 0k 0k 0k 0k 0k 0k 0k
Statutory Maternity Pay 333k 333k 334k 334k 335k 336k 337k
Statutory Paternity Pay 0k 0k 0k 0k 0k 0k 0k
Statutory Sick Pay 181k 182k 182k 182k 182k 183k 183k
Sure Start Maternity Grant 26k 26k 26k 26k 26k 26k 26k
Bereavement Support Payment 98k 98k 98k 98k 98k 99k 99k
Widowed Parent's Allowance 0k 0k 0k 0k 0k 0k 0k
Tax-Free Childcare 1,043k 1,027k 1,014k 1,009k 1,011k 1,009k 993k
Extended childcare entitlement 795k 800k 796k 797k 798k 798k 792k
Universal childcare entitlement 1,071k 1,072k 1,072k 1,073k 1,076k 1,079k 1,074k
Targeted childcare entitlement 165k 156k 154k 154k 155k 155k 150k
Childcare Offer for Wales 39k 39k 39k 39k 39k 39k 39k
Care to Learn 0k 0k 0k 0k 0k 0k 0k
Childcare Grant 0k 0k 0k 0k 0k 0k 0k
Parents' Learning Allowance 98k 98k 98k 99k 99k 99k 99k
Adult Dependants' Grant 18k 18k 12k 12k 12k 12k 12k
Travel Grant 0k 0k 0k 0k 0k 0k 0k
Disabled Students' Allowance suppressed suppressed suppressed suppressed suppressed suppressed suppressed
16 to 19 Bursary Fund 0k 0k 0k 0k 0k 0k 0k
Cost-of-living support payment 0k 0k 0k 0k 0k 0k 0k
Energy Bills Rebate 0k 0k 0k 0k 0k 0k 0k
Household Energy Payment 0k 21,065k 0k 0k 0k 0k 0k
Energy Price Guarantee subsidy 0k 0k 0k 0k 0k 0k 0k
Basic income 0k 0k 0k 0k 0k 0k 0k
Disability basic income 0k 0k 0k 0k 0k 0k 0k
Government balance, each component counted once: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Government receipts, each component once £892.00bn £934.66bn £980.50bn £1,015.93bn £1,054.24bn £1,091.56bn £1,124.89bn
Government spending £528.93bn † £545.10bn † £550.16bn † £558.85bn † £566.49bn † £575.19bn † £582.78bn †
Government balance, each receipt once £363.07bn † £389.57bn † £430.34bn † £457.08bn † £487.75bn † £516.37bn † £542.11bn †
Benefits in household_benefits but not in gov_spending £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn £0.00bn
Model totals: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
gov_tax £892.00bn £934.66bn £980.50bn £1,015.93bn £1,054.24bn £1,091.56bn £1,124.89bn
household_tax £491.97bn £520.41bn £551.21bn £576.00bn £601.00bn £626.69bn £648.42bn
pre_budget_change_household_tax £484.15bn £512.28bn £542.82bn £566.95bn £591.72bn £617.16bn £638.61bn
gov_spending £528.93bn † £545.10bn † £550.16bn † £558.85bn † £566.49bn † £575.19bn † £582.78bn †
household_benefits £528.93bn † £545.10bn † £550.16bn † £558.85bn † £566.49bn † £575.19bn † £582.78bn †
gov_balance £363.07bn † £389.57bn † £430.34bn † £457.08bn † £487.75bn † £516.37bn † £542.11bn †
Household income totals: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Household market income £1,637.96bn £1,702.77bn £1,757.35bn £1,806.41bn £1,855.97bn £1,912.43bn £1,970.44bn
Household net income £1,636.24bn † £1,687.25bn † £1,714.85bn † £1,746.83bn † £1,777.98bn † £1,816.26bn † £1,858.87bn †
Household net income (HBAI definition) £1,449.13bn £1,499.27bn £1,530.25bn £1,564.51bn £1,597.18bn £1,634.83bn £1,675.80bn
Population: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
People 69,245k 69,383k 69,473k 69,592k 69,738k 69,912k 70,080k
Benefit units 35,110k 35,181k 35,226k 35,286k 35,360k 35,449k 35,534k
Households 31,046k 31,108k 31,149k 31,201k 31,267k 31,345k 31,420k
Poverty rates: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Absolute poverty, before housing costs: everyone 16.3% 15.5% 16.4% 16.3% 16.5% 16.5% 16.6%
Absolute poverty, before housing costs: children 24.7% 22.1% 23.3% 22.9% 23.1% 23.2% 23.5%
Absolute poverty, before housing costs: working-age adults 14.1% 13.8% 14.7% 14.7% 14.8% 14.8% 15.0%
Absolute poverty, before housing costs: pensioners 13.7% 13.4% 14.0% 13.8% 13.9% 14.0% 13.9%
Absolute poverty, after housing costs: everyone 21.6% 21.0% 22.0% 22.6% 22.9% 23.1% 23.4%
Absolute poverty, after housing costs: children 33.3% 31.3% 32.3% 32.5% 32.9% 33.4% 34.2%
Absolute poverty, after housing costs: working-age adults 19.9% 19.8% 20.8% 21.6% 21.9% 22.0% 22.3%
Absolute poverty, after housing costs: pensioners 12.7% 12.4% 13.1% 13.2% 13.3% 13.4% 13.6%
Relative poverty, before housing costs: everyone 17.0% 16.0% 16.4% 16.3% 16.4% 16.3% 16.6%
Relative poverty, before housing costs: children 25.9% 22.9% 23.3% 22.9% 23.0% 22.9% 23.5%
Relative poverty, before housing costs: working-age adults 14.5% 14.1% 14.6% 14.7% 14.7% 14.7% 15.0%
Relative poverty, before housing costs: pensioners 14.5% 14.0% 13.9% 13.8% 13.8% 13.9% 13.9%
Relative poverty, after housing costs: everyone 21.5% 21.0% 21.3% 21.3% 21.3% 21.5% 21.7%
Relative poverty, after housing costs: children 33.1% 31.1% 31.2% 31.0% 31.1% 31.2% 31.8%
Relative poverty, after housing costs: working-age adults 19.9% 19.8% 20.2% 20.4% 20.5% 20.6% 20.8%
Relative poverty, after housing costs: pensioners 12.5% 12.4% 12.2% 11.7% 11.7% 11.8% 12.0%
People in poverty: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Absolute poverty, before housing costs: everyone 11,277k 10,778k 11,402k 11,365k 11,475k 11,514k 11,650k
Absolute poverty, before housing costs: children 3,688k 3,314k 3,496k 3,445k 3,480k 3,502k 3,549k
Absolute poverty, before housing costs: working-age adults 5,965k 5,893k 6,308k 6,362k 6,420k 6,430k 6,521k
Absolute poverty, before housing costs: pensioners 1,624k 1,571k 1,597k 1,558k 1,575k 1,581k 1,580k
Absolute poverty, after housing costs: everyone 14,944k 14,599k 15,310k 15,721k 15,937k 16,140k 16,426k
Absolute poverty, after housing costs: children 4,975k 4,682k 4,837k 4,888k 4,945k 5,040k 5,179k
Absolute poverty, after housing costs: working-age adults 8,463k 8,461k 8,971k 9,344k 9,491k 9,584k 9,706k
Absolute poverty, after housing costs: pensioners 1,506k 1,456k 1,501k 1,489k 1,501k 1,517k 1,541k
Relative poverty, before housing costs: everyone 11,750k 11,084k 11,387k 11,364k 11,416k 11,416k 11,654k
Relative poverty, before housing costs: children 3,872k 3,423k 3,496k 3,445k 3,466k 3,454k 3,551k
Relative poverty, before housing costs: working-age adults 6,159k 6,013k 6,301k 6,362k 6,389k 6,389k 6,523k
Relative poverty, before housing costs: pensioners 1,719k 1,648k 1,590k 1,558k 1,561k 1,573k 1,580k
Relative poverty, after housing costs: everyone 14,864k 14,552k 14,777k 14,809k 14,872k 15,012k 15,232k
Relative poverty, after housing costs: children 4,944k 4,660k 4,673k 4,663k 4,679k 4,707k 4,806k
Relative poverty, after housing costs: working-age adults 8,431k 8,440k 8,711k 8,823k 8,873k 8,967k 9,062k
Relative poverty, after housing costs: pensioners 1,489k 1,452k 1,393k 1,323k 1,321k 1,338k 1,364k
Inequality: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Gini coefficient, equivalised HBAI income before housing costs 0.3078 0.3050 0.3056 0.3055 0.3060 0.3066 0.3082
Mean household net income in each side's own deciles: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Decile 1: mean household_net_income per household £17,681 † £17,998 † £17,916 † £18,152 † £18,308 † £18,533 † £18,718 †
Decile 2: mean household_net_income per household £27,942 † £29,026 † £28,715 † £29,017 † £29,280 † £29,698 † £30,156 †
Decile 3: mean household_net_income per household £34,316 † £35,481 † £36,069 † £36,606 † £37,195 † £37,732 † £38,182 †
Decile 4: mean household_net_income per household £38,934 † £40,684 † £41,726 † £42,728 † £43,331 † £44,130 † £44,432 †
Decile 5: mean household_net_income per household £43,235 † £45,581 † £46,012 † £46,961 † £47,713 † £48,725 † £50,296 †
Decile 6: mean household_net_income per household £47,931 † £49,202 † £50,891 † £51,936 † £52,936 † £53,820 † £54,663 †
Decile 7: mean household_net_income per household £55,659 † £56,569 † £57,437 † £57,642 † £58,733 † £59,661 † £61,087 †
Decile 8: mean household_net_income per household £68,784 † £70,802 † £71,864 † £73,512 † £73,886 † £75,319 † £77,177 †
Decile 9: mean household_net_income per household £78,889 † £81,012 † £80,859 † £82,645 † £85,463 † £86,945 † £89,508 †
Decile 10: mean household_net_income per household £116,861 † £120,161 † £124,545 † £126,420 † £125,753 † £128,368 † £130,693 †
Standard reform costings (change in gov_balance): head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Raise basic rate by 1pp £6.41bn £6.66bn £6.63bn £6.85bn £7.03bn £7.25bn £7.49bn
Raise higher rate by 1pp £3.61bn £3.87bn £4.00bn £4.22bn £4.44bn £4.71bn £4.83bn
Raise personal allowance by ~800GBP/year £-3.81bn £-3.93bn £-3.99bn £-4.05bn £-4.11bn £-4.24bn £-1.95bn
Raise child benefit by 25GBP/week per additional child £-1.99bn £-1.75bn £-1.55bn £-1.38bn £-1.30bn £-1.18bn £-1.07bn
Reduce Universal Credit taper rate to 20% £-20.77bn £-21.32bn £-21.75bn £-22.00bn £-22.35bn £-22.75bn £-22.94bn
Raise Class 1 main employee NICs rate to 10% £10.89bn £11.30bn £11.71bn £12.01bn £12.31bn £12.62bn £13.00bn
Raise VAT standard rate by 2pp £24.89bn £25.71bn £26.63bn £27.24bn £27.87bn £28.50bn £29.14bn
Raise additional rate by 3pp £2.90bn £3.15bn £3.22bn £3.41bn £3.61bn £3.85bn £4.14bn
Raise the Universal Credit standard allowance by 10% £-3.06bn £-3.18bn £-3.26bn £-3.35bn £-3.44bn £-3.49bn £-3.50bn
Raise the State Pension by 10% £-7.76bn £-7.99bn £-8.22bn £-8.45bn £-8.80bn £-8.53bn £-8.87bn
Standard reforms: change in each reform's target: head levels
Measure (head) 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Raise basic rate by 1pp: change in income_tax £6.55bn £6.86bn £6.79bn £7.00bn £7.20bn £7.44bn £7.66bn
Raise higher rate by 1pp: change in income_tax £3.61bn £3.92bn £4.01bn £4.23bn £4.45bn £4.72bn £4.84bn
Raise personal allowance by ~800GBP/year: change in income_tax £-3.93bn £-4.07bn £-4.13bn £-4.18bn £-4.22bn £-4.40bn £-1.75bn
Raise child benefit by 25GBP/week per additional child: change in child_benefit £2.33bn £2.14bn £1.94bn £1.76bn £1.65bn £1.52bn £1.40bn
Reduce Universal Credit taper rate to 20%: change in universal_credit £20.74bn £21.31bn £21.79bn £22.05bn £22.37bn £22.78bn £22.99bn
Raise Class 1 main employee NICs rate to 10%: change in national_insurance £11.15bn £11.63bn £12.00bn £12.29bn £12.61bn £12.94bn £13.31bn
Raise VAT standard rate by 2pp: change in vat £24.69bn £25.51bn £26.42bn £27.03bn £27.65bn £28.28bn £28.91bn
Raise additional rate by 3pp: change in income_tax £2.90bn £3.15bn £3.22bn £3.42bn £3.62bn £3.86bn £4.12bn
Raise the Universal Credit standard allowance by 10%: change in universal_credit £3.06bn £3.19bn £3.28bn £3.37bn £3.43bn £3.49bn £3.51bn
Raise the State Pension by 10%: change in state_pension £10.68bn £11.17bn £11.28bn £11.60bn £12.03bn £12.46bn £12.96bn

@juaristi22 juaristi22 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.

Reviewed 19378b97fb7b139ca1df7d73b42451bd68e295f8. Complete review; no findings or material evidence gaps.

The 2026 Oxford UC route follows Appendix 3: full relievable pension contributions in DWP net earnings, the award before debt deductions, bounded element disregards and the separate other-income list. Earlier-year and non-UC behavior stays within the documented scope. Official scheme/statutory sources and the queued Axiom record were checked.

Validation: all 52 repository tests passed, including all seven new properties. Native final-output controls show the no-pension parent’s CTR and household income each fall £450 under the corrected route; the pension case uses the full contribution and the non-UC control is unchanged. Exact-head CI passed. Local Core 3.33.2 and locked-runtime hosted evidence are distinguished; private population effects and the declared baseline follow-ups remain outside this review.

#1995 moved the council_tax_reduction_relevant_income_based_benefit
lookup in oxford_council_tax_reduction above its new capital rule. The
merge keeps that lookup and this branch's Appendix 3 block without its
second lookup.

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

@juaristi22 juaristi22 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.

Re-reviewed 98a2e575520a5d8312b244f09af3b021fa88cb56 after the main merge. COMPLETE — requesting changes for C1, a failing required regression property.

test_oxford_council_tax_reduction_universal_credit_properties.py:671, in test_appendix_3_income_matches_the_other_councils_universal_credit_income, fails at this head. For the generated case with a 25-year-old parent earning £20,784.920404, two infants, no pension/other income/capital/housing costs and the test's £50,000 council tax, the Merton route implies income of £25,397.50, against the property's Oxford-based oracle of £24,632.670715 (tolerance £0.25). The complete generated case and failure were retained.

The property is unchanged, but the merged assessment paths no longer satisfy its cross-council equality assertion. Please reconcile the implementation/oracle with the merged routes and retain an appropriate regression. This is a confirmed test blocker; it does not establish that either council's cash assessment is legally wrong.

The focused current-head campaign completed with 76 passes and this one failure, with no skips. The native Oxford final CTR/household-income checks passed. Earlier passing evidence and pending hosted CI do not override this current failure.

@juaristi22 juaristi22 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.

Checked the updated description at unchanged head 98a2e575520a5d8312b244f09af3b021fa88cb56. The pre-debt UC wording and the capped/debt-nil-award route now accurately describe the merged code and Oxford Appendix 3. No new source or code finding.

C1 remains open; changes are still required. The cross-council property at test_oxford_council_tax_reduction_universal_credit_properties.py:671 and its oracle are unchanged. The previous exact-head result remains 76 passes and one failure; the description edit does not repair it. Please reconcile that required property with the merged assessment paths. This remains a test blocker, not a finding that either council's cash assessment is legally wrong.

The prior execution and source evidence were retained and checked; no tests or model calculations were repeated.

@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Picking this up for the UK hub. Reply here if you're mid-change and I'll stop.


Generated by Claude Code

Merton, Kingston upon Thames, Newham and Westminster now count the
Universal Credit award before deductions for debts, as Oxford's Appendix 3
does, so the cross-council property no longer takes uc_deductions off
Oxford's income. Add an explicit example of a claimant repaying debts at a
quarter of the standard allowance.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LwQq6GC8zqh3aNDgFt3nd9
@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

PR_BODY.md

Fixes #2520

## What and why

In its [Council Tax Reduction Scheme 2026 to 2027](https://www.oxford.gov.uk/council-tax-reduction/council-tax-reduction-scheme-2026-27), Oxford City Council divides working-age applicants into two groups and bands each on weekly income (Part 1 para 9).
- For an applicant without Universal Credit, the council calculates income "in accordance with paragraphs 14-27" and deducts "50% of contributions to occupational or personal pension schemes" from earnings (para 18). In the heading before para 14 it limits paragraphs 14 to 27 and Annexes 5 and 6 to pensioners and working-age applicants without Universal Credit.
- For an applicant with Universal Credit, the council sets the income in [Appendix 3](https://www.oxford.gov.uk/council-tax-reduction/council-tax-reduction-scheme-2026-27/4). It adds "their net earned income (as provided by DWP) to the amount of Universal Credit awarded", ignores any transitional element and counts other (unearned) income weekly. It ignores "£48.15 of the Universal Credit carer element" and "£84.46 of the Universal Credit disabled child element". DWP deducts "any relievable pension contributions" in full when it calculates net earned income (UC Regs 2013 [reg 55(5)(a)](https://www.legislation.gov.uk/uksi/2013/376/regulation/55)).

In `oxford_council_tax_reduction` the model banded every working-age applicant on `council_tax_reduction_applicable_income`, the paragraphs 14 to 27 income with Oxford's 50% share. So the model deducted half of a Universal Credit claimant's pension contributions instead of all of them, and left out their Child Benefit and child maintenance. A reform of Oxford's pension contribution share also moved their reduction.

This PR makes five changes.
- **Appendix 3 income.** The model adds three amounts in a new variable, `oxford_council_tax_reduction_universal_credit_income`:
  - `uc_earned_income_before_work_allowance`, DWP's net earned income after tax, National Insurance and relievable pension contributions, before the work allowance;
  - `oxford_council_tax_reduction_universal_credit_other_income`, a new variable in which the model sums the applicant's and partner's receipts that it lists in a new parameter (below);
  - the award: `universal_credit` plus `uc_deductions`, the amount DWP awards before it takes deductions for debts out of the payment, less the element disregards and not below nil.

  For the four other councils (`_legacy.py`), the model counts Universal Credit's own unearned income and, since #2822, the award before deductions for debts. This PR leaves `_legacy.py` alone.
- **Other income.** The model lists its variables one by one in `gov.local_authorities.oxford.council_tax_reduction.universal_credit.other_income_sources`, with the reason for each in the file.
- **Disregards.** The model holds the weekly amounts from 1 April 2026 in two Oxford parameters: `universal_credit.carer_element_disregard` (£48.15) and `universal_credit.disabled_child_element_disregard` (£84.46).
- **Start date.** The model switches the route on from 1 April 2026 through `universal_credit.in_effect`, which is false from 2015. The model reads each year's parameters at 30 April. So the Appendix 3 route starts in model year 2026, and in model years 2025 and earlier `oxford_council_tax_reduction` gives the results it gave before. A user can move the route with a reform of `in_effect`. The model gates only the route this way. The list and the two disregards start on 1 April 2026, and the model carries them back to 2015 like its other Oxford parameters. So the two new variables still return Appendix 3 amounts for earlier years, though the reduction does not read them. In 2025, the new variables give a lone parent earning £15,600 with two children and £2,600 of child maintenance other income of £4,851.60 and Appendix 3 income of £27,833.34. Paragraphs 14 to 27 still set their reduction, £1,800.
- **Banding and docs.** In `oxford_council_tax_reduction` the model bands a Universal Credit applicant on a fifty-second of the Appendix 3 income. An applicant without Universal Credit keeps the same arithmetic, bit for bit, and the model still adds Oxford's tariff income only for them. This PR also rewrites the pension contribution share's variable and parameter documentation to name the applicants the share reaches.

The model builds the award's maximum amount (`uc_maximum_amount`) from the standard allowance and the child, disability, carer, housing and childcare elements, and nothing else. So the award holds no transitional element to remove.

**Earlier schemes.** In its [2025-26 scheme](https://www.oxford.gov.uk/council-tax-reduction/council-tax-reduction-scheme-2025-26/4) Oxford City Council sets an Appendix 3 with the same income rule. It tops the bands at £500, £575, £650 and £700, ignores £46.40 of Carer's Allowance in place of the two element disregards, and includes no transitional-element sentence. The model applies the 2026-27 parameters to every earlier year, so this PR keeps earlier years on their previous results and does not model 2025-26. The council's 2024-25 scheme pages at the same address return 404.

### Readings

- **Other income.** In Appendix 3 Oxford City Council lists the income it ignores and says "All other unearned income is taken into account". It ignores Child Benefit and child maintenance in Appendix 5, which "applies to pensioners and working-age applicants who do not receive Universal Credit". In Appendix 3 it repeats several items from that list, Attendance Allowance, Disability Living Allowance, Personal Independence Payment, Discretionary Housing Payments and Housing Benefit among them, but not those two. So the council counts Child Benefit and child maintenance for these applicants, along with the receipts DWP counts, and so does the model. For a receipt DWP counts, DWP takes each pound off the award and Oxford adds it back as other income. The two effects cancel while DWP's net earned income and the award's other terms stay fixed, no benefit cap applies and the award stays above nil after the disregards. A taxable receipt can break the first condition. In 2027, a 70-year-old earning £13,036.40, in a couple with a 60-year-old, loses £93.28 of Pension Tax Allowance when they receive £520 of private pension. DWP's net earned income then falls £93.28, the award £468.70 and the Appendix 3 income £41.98.
- **Miscellaneous income.** The model counts miscellaneous income in DWP's net earned income (`uc_individual_earned_income_before_mif`) and leaves it off the list, so it counts the income once. DWP counts miscellaneous income as unearned income (reg 66(1)(m)). If #1961 moves the model's figure there, the model will take it off the award pound for pound, as DWP does, and must add it back to the list.
- **Carer Support from Scotland.** Social Security Scotland keeps paying Carer Support for 13 weeks after a carer moves to another part of the United Kingdom ([SSI 2023/302 reg 42](https://www.legislation.gov.uk/ssi/2023/302/regulation/42)). It pays the Scottish Carer Supplement for each week it pays the carer support payment ([reg 14A](https://www.legislation.gov.uk/ssi/2023/302/regulation/14A)). DWP counts the carer support payment only up to a year of Carer's Allowance ([reg 66(1)(b)(iiia)](https://www.legislation.gov.uk/uksi/2013/376/regulation/66)) and does not count the supplement. Oxford City Council ignores the part above Carer's Allowance only in Appendix 5, so the model counts both payments whole.
- **One-off receipts.** In Appendix 6 Oxford City Council names some one-off payments as capital: the first month's Bereavement Support Payment, Energy Rebate Scheme 2022 payments, "any other payments made by the Government to help with the cost of living" and payments for a personal injury. The model reads the council's capital and income lists together. It keeps out of Appendix 3 income a one-off payment that attaches to no period and that the council names in Appendix 6. It counts regular Bereavement Support Payment and Armed Forces Compensation Scheme payments, Guaranteed Income Payments included: the model reads `bsp_reported` and `afcs_reported` as regular payments and counts `bsp` and `afcs` whole. If a user enters a lump sum in either input, the model counts it as income.
- **Capital.** Oxford City Council treats "any income derived from capital" as capital (para 30 and Annex 7) and sets no other rule for it in Appendix 3, so the model leaves out interest, dividends and rent. DWP deems an assumed yield from capital (`uc_tariff_income`, reg 72) and takes it off the award, but nobody receives it, so the model does not add it back. The council adds its own assumed income only under paragraphs 14 to 27 (para 15), and ignores capital "already taken into account when the applicant is receiving Universal Credit" (Appendix 6). So the council counts capital for these applicants only through the award DWP reduces. Oxford City Council publishes nothing on its practice for Child Benefit or capital beyond the scheme text.
- **Whose income.** Oxford City Council counts "the income of the applicant and, where appropriate, their partner" (Appendix 3). The model counts each person's receipts for the Council Tax Reduction applicant and partner, as `council_tax_reduction_applicable_income` does, so a younger partner's receipts count and a 17-year-old's do not. A household head who applies alone has no award, so the council assesses them under paragraphs 14 to 27 on their own income, without the benefit unit's Child Benefit.
- **Who has an award.** In Appendix 3 Oxford City Council also covers an applicant whose award DWP reduces to nil through deductions or other adjustments. The model puts a family on this route when DWP pays it Universal Credit. It does the same when the family claims Universal Credit and the benefit cap or deductions for debts take its award to nil (`council_tax_reduction_universal_credit_award`, which #1995 added).
- **DWP figures.** The model reads "net earned income (as provided by DWP)" as the earned income DWP uses in the Universal Credit calculation. For a self-employed claimant DWP uses the minimum income floor where it applies (UC Regs 2013 [reg 62](https://www.legislation.gov.uk/uksi/2013/376/regulation/62)), and so does the model.
- **Award before deductions for debts.** Oxford City Council counts "the amount of Universal Credit awarded" and, in Appendix 3's first sentence, names deductions apart from the award. So the model adds back `uc_deductions` (the deductions for debts DWP takes from the payment), and a reform of those deductions does not move Oxford reductions. DWP applies the benefit cap to the award itself, so the model keeps the capped award.
- **One disregard for each element.** £48.15 and £84.46 match the 2026-27 carer premium and disabled child premium. Councils include the carer premium in Housing Benefit "in respect of each person" who meets the carer condition. They include the disabled child premium for "each child or young person" who meets its condition (HB Regs 2006 [Sch 3 para 20(7) and (8)](https://www.legislation.gov.uk/uksi/2006/213/schedule/3)). DWP includes a carer element for each claimant who cares (reg 29) and a disabled child addition for each disabled child (reg 24(2)). So the model ignores up to each amount for each element, taking it off the award but not below nil.

The model treats these receipts as follows:

| Variable | Appendix 3 income | Oxford text |
|---|---|---|
| `child_benefit` | counted | Oxford City Council applies its Appendix 5 disregard only without Universal Credit |
| `maintenance_income` (child maintenance received) | counted | Oxford City Council applies its Appendix 5 disregard only without Universal Credit |
| `spousal_maintenance_income`, `private_pension_income`, `state_pension`, `carers_allowance`, `carer_support_payment`, `jsa_contrib`, `esa_contrib`, `maternity_allowance`, `iidb`, `widowed_parents_allowance`, `incapacity_benefit`, `sda` | counted | "All other unearned income"; the receipts DWP counts as unearned income (reg 66). The council gives its £15 disregards only without Universal Credit (Appendix 5) |
| `scottish_carer_supplement` | counted | "All other unearned income"; Social Security Scotland pays it with the carer support payment, for 13 weeks after a move from Scotland. The model pays 52 weeks (Limits) |
| `bsp`, `afcs`, `war_widows_pension`, `armed_forces_independence_payment`, `ssmg`, `healthy_start_vouchers`, `private_transfer_income` | counted | "All other unearned income"; the council names none of them in Appendix 3, and applies its war pension, Armed Forces Independence Payment and Healthy Start disregards only without Universal Credit. The model reads `bsp` and `afcs` as regular payments |
| `income_support`, `claimant_or_partner_jsa_income`, `claimant_or_partner_esa_income`, `tax_credits`, `pension_credit` | counted | "All other unearned income"; DWP replaces these awards with Universal Credit, so a claimant receives none of them |
| `miscellaneous_income` | in DWP's net earned income | the model's Universal Credit earnings (#1961) |
| `uc_tariff_income`, Oxford's tariff income | out | an assumed yield, not a receipt; para 15 |
| `savings_interest_income`, `other_investment_income`, `tax_free_savings_income`, `dividend_income`, `individual_savings_account_dividend_income`, `property_income`, `capital_gains` | out | para 30 and Annex 7: income derived from capital; the council also ignores rent from sub-tenants and boarders in Appendix 3 |
| `attendance_allowance`, `dla`, `pip`, `housing_benefit`, `council_tax_benefit` | out | Oxford City Council ignores them in Appendix 3 (`council_tax_benefit` holds the reduction itself) |
| `statutory_sick_pay`, `statutory_maternity_pay`, `statutory_paternity_pay` | in DWP's net earned income | reg 55(4) |
| `winter_fuel_allowance`, `winter_fuel_payment`, `cost_of_living_support_payment`, `energy_bills_rebate`, `household_energy_payment`, `epg_subsidy` | out | one-off payments that attach to no period: Oxford City Council names Energy Rebate Scheme 2022 payments and other Government cost-of-living payments, such as the £100 Household Energy Payment, as capital in Appendix 6 |
| `student_loans`, `education_grants`, `student_payments`, `adult_dependants_grant`, `access_fund` | out | Oxford City Council treats them under Annex 8, with its own rules and disregards; the model counts student income in no Council Tax Reduction scheme |
| `adult_ema` | out | Annex 8 keeps an educational maintenance allowance out of "grant", and Appendix 3 does not ignore it, so the council counts one the applicant or partner receives (Limits) |
| `child_ema` | out | a child's receipt; the council counts only the applicant's and partner's income |
| `scottish_child_payment`, `two_child_limit_payment`, `pension_age_winter_heating_payment`, `pawhp`; Guardian's Allowance | out | the model computes the Scottish ones only for households in Scotland; the model has no Guardian's Allowance |

When a lone parent earning £15,600 with two children receives £520 more of a listed source in 2026, DWP's net earned income and the income tax DWP deducts from it stay the same. For each receipt DWP counts, DWP lowers the award by £520, and the Appendix 3 income stays the same. For each other listed source, the award stays the same and the Appendix 3 income rises £520. With Carer's Allowance, the model also adds the carer element (£2,512.08) to the award, and Oxford ignores £2,503.80 of it, so the Appendix 3 income rises £8.28. With the carer support payment, the model adds the carer element and also pays its £608.40 supplement, so other income rises £1,128.40 and the Appendix 3 income £616.68. The carer support payment gives Carer's Allowance's £8.28 only with the supplement held fixed. The model now counts miscellaneous income only in DWP's net earned income: £520 more raises that figure by £416 after income tax, lowers the award by £228.80 and raises the Appendix 3 income by £187.20.

This family shows none of three other routes:
- Where the model computes Carer's Allowance, DWP reduces it by maternity allowance, contributory JSA or ESA, incapacity benefit, severe disablement allowance, Widowed Parent's Allowance or State Pension (Overlapping Benefits Regs 1979 [reg 12](https://www.legislation.gov.uk/uksi/1979/597/regulation/12)). So £520 more of one of them leaves other income, the award and the Appendix 3 income unchanged.
- Where the benefit cap applies, a receipt can lift it. In a capped Oxford family in the South East, the model keeps the cap on with £520 of War Widow's Pension, though reg 83(1)(d) lifts it, so the Appendix 3 income rises £520. With £520 of the Armed Forces Compensation Scheme it lifts the cap, and the Appendix 3 income rises £12,808.84.
- In 2027 a taxable receipt can cut the Pension Tax Allowance, as under Readings.

**Limits.**
- For a disabled applicant, the council also ignores an amount equal to any disability premium payable before the move to Universal Credit. The model holds no record of that earlier award and ignores nothing, so it can overstate such an applicant's income and understate their reduction.
- The council counts students' loans and grants under Annex 8, with its own disregards, and counts an educational maintenance allowance the applicant or partner receives as other income. DWP counts student income in the award (reg 66(1)(e)). The model counts none of them, so it can misstate a student's income and reduction.
- The model counts `bsp` and `afcs` whole, so if a user enters a lump sum there, the model counts it as income.
- The model pays the Scottish Carer Supplement for 52 weeks whenever the carer support payment is positive. An Oxford household receives at most 13 weeks of it (SSI 2023/302 regs 14A and 42), or 25 after a death in the run-on. For a lone parent of two with housing costs of £12,560 and 13 weeks of Carer Support, the model's £608.40 of supplement gives band 3 and £900. The law's 13 weeks, £152.10, give band 2 and £1,350.

### Overlap with other work

Of the 77 open pull requests, one touches this PR's files. **#1966 (draft, `ctr-working-age-shortfall`)** conflicts with this branch in the `council_tax_reduction_pension_contribution_deduction_rate` documentation: keep #1966's Wales and Scotland route and this PR's Oxford sentence. #1966 also conflicts with `main` in three files this PR does not touch.

We merged `main` at `acba5efc1` into this branch, bringing in #1995 and #2822. With #1995 the model ignores capital for Universal Credit and passported applicants under Appendix 6, and looks up `council_tax_reduction_relevant_income_based_benefit` above that rule in `oxford_council_tax_reduction.py`. We kept both in the merge, with this PR's Appendix 3 block below them and no second lookup.

## Invariants

Invariants 1 to 6 and 8 hold for every working-age Oxford family whose applicant has a Universal Credit award, from 2026. Invariant 7 covers earlier years, and invariant 9 families without an award.

1. **Locality.** No reform of Oxford's pension contribution share changes the family's Oxford reduction, while every Oxford family reads the reform's share.
2. **Appendix 3 income.**
   - Other income is the family's Child Benefit at HMRC's rates plus child and spousal maintenance and its other listed receipts, with no interest, dividends, rent or assumed yield.
   - The income is net earned income plus other income plus the award before deductions for debts, less ignored amounts.
   - The ignored amounts are never negative and never exceed the award or the elements. They are at most £48.15 a week for each carer element and £84.46 a week for each disabled child, and nil with no such element.
3. **Bands.** The reduction is the council tax share times the rate Oxford City Council sets in its band table for a fifty-second of the income, less non-dependant deductions.
4. **Pound for pound.** While the award stays above nil after the disregards, no benefit cap applies, and DWP's net earned income and the award's other terms stay the same:
   - £1 more of a receipt DWP deducts from the award (spousal maintenance, a private pension) leaves the income unchanged, because DWP lowers the award by £1;
   - £1 more of Child Benefit or child maintenance raises it by £1;
   - £1 more interest leaves it unchanged;
   - more capital lowers it by the rise in DWP's assumed yield.
5. **Monotonicity.** More pension contributions never lower the reduction of a family that keeps its award.
6. **Differential with the other councils.** Swap Oxford's other income in the Appendix 3 income for Universal Credit's unearned income. For a family with no carer or disabled child element and no capital, the result equals the Universal Credit income behind the awards of Merton, Kingston upon Thames, Newham and Westminster. Those councils, like Oxford, count the award before deductions for debts.
7. **Earlier years.** In model years 2025 and earlier, every family's Oxford reduction equals `origin/main`'s. A family with an award keeps the band of its paragraphs 14 to 27 income less Child Benefit, with no tariff income.
8. **Each receipt once.** More of a receipt Oxford City Council counts as other income, with every other receipt held fixed, raises other income by the whole amount, including a carer support payment above DWP's cap. It leaves DWP's net earned income unchanged while the income tax DWP deducts stays fixed. A receipt DWP takes off Carer's Allowance under the overlapping-benefit rules raises other income by the net amount: nothing, where DWP takes the whole receipt off. The model adds miscellaneous income to DWP's earned-income calculation, where a minimum income floor can absorb it, and leaves other income unchanged. The model leaves interest, dividends and rent out of other income; their effect on DWP's net earned income depends on the income tax DWP deducts. Receipts of anyone but the applicant and partner never change other income.
9. **Differential with `origin/main`.** In 2026, every family not on Universal Credit gets `origin/main`'s Oxford reduction, bit for bit.

## Test plan

- [x] For policy changes: YAML tests whose expected values come from an external source.
  - `oxford_council_tax_reduction_universal_credit.yaml` holds 36 cases, and `oxford_council_tax_reduction_universal_credit_earlier_years.yaml` holds 9. Each case shows hand-worked arithmetic from the scheme text, DWP's and HMRC's rates for the year and the income tax and National Insurance rules, citing the paragraph.
  - The 2026 cases cover the Appendix 3 income with pension contributions, two reforms of the Oxford share and a lone parent before the work allowance. They cover the carer and disabled child disregards (one carer, two carers, the floor at nil, one disregard for each child) and the award before deductions for debts. They also cover Child Benefit, child maintenance, spousal maintenance, a private pension, miscellaneous income, a regular Armed Forces Compensation Scheme payment, interest, dividends, rent, and capital of £11,250 and £16,000.
  - Seven cases test whose receipts count and how. A younger partner's child maintenance counts, and a 17-year-old's private transfers do not. Personal Independence Payment, Attendance Allowance and Disability Living Allowance stay out. A self-employed claimant under the minimum income floor counts the floor's £20,386.03, not the £5,000 they earn. A carer whose Carer's Allowance the model computes, £4,495.40 less £2,600 of Widowed Parent's Allowance, counts the £1,895.40 DWP pays.
  - Two cases follow carers who move from Scotland, and each supplies the supplement. One receives 13 weeks of it with 13 weeks of carer support payment, and one receives a carer support payment above DWP's cap. A household head who applies alone keeps her own income, without the couple's award. Two cases without Universal Credit keep `origin/main`'s results.
  - The earlier-years cases pin 2024 and 2025 to `origin/main`'s results for a single claimant, a parent with Child Benefit and a parent with child maintenance. They also check that reforms of `in_effect` move the route in 2025 and 2026.
  - All 36 and all 9 pass at `aa2f0a579` (39.17 s and 82.37 s), and at `d5403d70a`, whose tests and model match. Every mutant in the table below fails at least one 2026 case, except two that agree with the code on every lawful input.
- [x] Property tests: `test_oxford_council_tax_reduction_universal_credit_properties.py` holds 7 test functions, one for each of invariants 1 to 8 (invariants 2 and 3 share one). Each runs 5 generated populations plus its explicit examples, with Hypothesis derandomised. Every formula and every list entry stand as they did at `290b095e6`. `2343a7861` changes only invariant 6's test: its oracle no longer takes `uc_deductions` off the Appendix 3 income, and it gains an explicit example of a single claimant who repays debts at a quarter of the standard allowance.
  - At `2343a7861`, one `-n 4` run of the whole file: 7 passed in 167.18 s. The locality test took 114.28 s, `test_more_pension_contributions_never_lower_the_reduction` 71.10 s, `test_appendix_3_income_and_band` 43.82 s, `test_pound_for_pound` 37.47 s, `test_appendix_3_income_matches_the_other_councils_universal_credit_income` 36.81 s, `test_each_receipt_counts_once` 33.42 s and `test_earlier_years_keep_the_paragraphs_14_to_27_income` 29.58 s.
  - At `98a2e5755`, before that change, invariant 6's test failed on a generated couple with deductions for debts at 0.15 of the standard allowance: the Merton award implied income £424.38 above the oracle, exactly the family's `uc_deductions`. For the generated parent earning £20,784.92 with two infants, the gap came to £764.83 against `uc_deductions` of £764.82. With only the explicit examples run, the debt example fails under the old oracle (a gap of £1,274.69, its `uc_deductions` of £1,274.70) and passes under the new one. The family keeps its award, and each other council's award falls below its maximum, so the test reads back its income at all four councils.
  - At `aa2f0a579`: `test_each_receipt_counts_once` 1 passed in 432.69 s, and `test_appendix_3_income_matches_the_other_councils_universal_credit_income` 1 passed in 487.40 s. At `d5403d70a`, whose tests and model match, `test_more_pension_contributions_never_lower_the_reduction` 1 passed in 471.62 s.
  - At `290b095e6`: `test_appendix_3_income_and_band` 1 passed in 766 s and `test_pound_for_pound` 1 passed in 437 s. At `7fa10f27e`: `test_earlier_years_keep_the_paragraphs_14_to_27_income` 1 passed in 565 s. The locality test passed at `021bc2847`; at `7fa10f27e` its explicit families at shares 0 and 1 passed in 1,367 s, and the full run did not finish inside a 1,500 s cap.
  - `test_each_receipt_counts_once` supplies each of 31 receipts, written out from the scheme rather than read from the parameter, to the last adult of each generated family and, for person-level receipts, to the first child. With the new test file, it fails at `ae9bbabd1`, this branch before the miscellaneous income and Scottish Carer Supplement changes: the supplement moves other income by £0, not £520. On `origin/main` (`2da212abc`) it fails on its first explicit example: "Variable oxford_council_tax_reduction_universal_credit_other_income does not exist".
  - The generated families give each adult receipt to the last adult, the eldest, who heads the benefit unit, and supply Carer's Allowance and the supplement as inputs. They hold no 16-to-19-year-old, self-employment or disability benefit, so the seven route cases above cover those.
- [x] Mutations: each ran in its own scratch copy of `d5403d70a`, one at a time, under a 2 GB memory cap, against the 36 cases of the 2026 YAML file.

  | Mutant | 2026 YAML (36 cases) | Property test run against it |
  |---|---|---|
  | Other income read from `uc_unearned_income` | 23 failed | `test_appendix_3_income_and_band` fails (`290b095e6`) |
  | One carer disregard for the award | 1 failed: the couple who both care, 26,680.50 instead of 24,176.70 | not run |
  | Benefit unit's awards counted for a head who applies alone | 1 failed: her other income, 28,806.60 instead of 27,400 | not run |
  | DWP's figures and the award counted for a head who applies alone | 1 failed: her Appendix 3 income, 37,387.36 instead of 27,400 | not run |
  | `uc_tariff_income` added to the list | 2 failed: the assumed yield and £16,000 capital cases | not run |
  | `afcs` removed from the list | 1 failed: the Armed Forces Compensation Scheme case, other income 2,337.40 instead of 4,937.40 | `test_each_receipt_counts_once` fails on `afcs` (`290b095e6`) |
  | `carer_support_payment` replaced by DWP's capped `uc_unearned_carer_support_payment` | 1 failed: the carer support payment above DWP's cap, other income 7,441.20 instead of 8,145.80 | `test_each_receipt_counts_once` fails (`290b095e6`) |
  | `miscellaneous_income` put back on the list | 1 failed: the miscellaneous income case, other income 4,937.40 instead of 2,337.40 | `test_each_receipt_counts_once` fails (`290b095e6`) |
  | `scottish_carer_supplement` removed from the list | 2 failed: the two Scottish carer cases | `test_each_receipt_counts_once` fails (`290b095e6`) |
  | Other income counts every member aged 16 or over, not the applicant and partner | 1 failed: the 17-year-old's receipt, other income 4,937.40 instead of 2,337.40 | not run |
  | Other income counts the benefit unit head's receipts alone | 1 failed: the younger partner's maintenance, other income 1,406.60 instead of 4,006.60 | not run |
  | `pip` and `attendance_allowance` added to the list | 2 failed: the two cases, other income 4,937.40 instead of 2,337.40 and 7,600 instead of 5,000 | not run |
  | Appendix 3 reads each claimant's earned income before the minimum income floor | 1 failed: the floor case, Appendix 3 income 11,386.48 instead of 26,772.51 | not run |
  | The supplement counts only beside a carer support payment | 36 passed | `test_each_receipt_counts_once` fails on `scottish_carer_supplement`, which it supplies with no carer support payment (`d5403d70a`) |
  | `tax_credits` taken off the list | 36 passed | `test_each_receipt_counts_once` fails on `tax_credits` (`7fa10f27e`) |

  The miscellaneous income and supplement removal mutants undo this PR's two list changes. Social Security Scotland pays the supplement only in weeks it pays the carer support payment (reg 14A), and no claimant receives tax credits beside Universal Credit. So no lawful YAML case tells the last two mutants from the code.
- [x] Differential against `origin/main` (`2da212abc`), with this branch at `7238eba63`, on 400 generated Oxford households and 497 benefit units, for 2024, 2025 and 2026. `numpy.random.default_rng(2520)` draws one or two adults with earnings, pension contributions, self-employment, spousal maintenance, private pensions and carers. It adds up to two children, some disabled, a non-dependant in a quarter of households, housing costs and savings of 0 to 17,000, and `default_rng(25200)` adds child maintenance and interest.
  - 2024 and 2025: all 497 benefit units get `origin/main`'s Oxford reduction, and all 400 households its Council Tax Reduction, bit for bit.
  - 2026: all 378 benefit units without a Universal Credit award match bit for bit; 123 of them get a reduction. Of the 108 working-age claimant families with an award, 6 rise (+£4,000) and 29 fall (−£19,850), −£15,850 in all and −£146.76 per claimant family. 25 of the 29 that fall receive Child Benefit.
  - Later commits change two list entries (miscellaneous income out, the Scottish Carer Supplement in), tests and documentation, and no formula. The population holds no miscellaneous income, and the model pays no carer support payment or Scottish Carer Supplement in Oxford, so those entries cannot move its results. At `7fa10f27e` its 2026 arrays for the reduction, the award, other income, Appendix 3 income and household Council Tax Reduction match `ae9bbabd1`'s bit for bit.
- [x] Existing tests: `test_parameter_descriptions.py`, 24 passed at `aa2f0a579`. At `ae9bbabd1`, the `policy/baseline/gov/local_authorities` YAML tree passed 403 cases and `test_council_tax_reduction_applicant_properties.py` 2 tests. At `7fa10f27e`, the tree's 113 cases outside `oxford/` that hold an Oxford household passed, and so did `test_council_tax_reduction_assesses_the_liable_head`. At `aa2f0a579`, `test_head_applying_alone_matches_her_own_benefit_unit` 1 passed in 2,188.36 s. No Oxford case outside `oxford/` holds miscellaneous income, a carer support payment or the supplement, so the later list changes cannot reach them. At `2343a7861`, the `policy/baseline/gov/local_authorities` YAML tree passed 429 cases in one `policyengine-core test` run, `test_council_tax_reduction_applicant_properties.py` 2 tests and `code_health` 3,150 tests.
- [x] At `2343a7861`: `ruff format --check .`, `ruff check .` and `ruff check --select F811,F821 policyengine_uk` (ruff 0.17.2) and `git diff --check 98a2e5755..2343a7861` clean; `git merge-tree` against `origin/main` (`9dd44e142`) merges without conflict.
- [x] `ruff format --check`, `ruff check` and `ruff check --select F811,F821 policyengine_uk` on the 5 changed Python files, and `git diff --check`: clean at `aa2f0a579`.
- [x] Changelog fragment `changelog.d/2520.fixed.md`.
- [x] `19378b97f` rewrites one variable's documentation and changes no code: its syntax tree, with `documentation` removed, matches `aa2f0a579`'s.

No survey data: every simulation uses hand-built situations.

Follow-ups: #2789 (Oxford's route before April 2026), #2790 (student income), #2791 (Scottish Carer Supplement weeks), #2792 (War Widow's Pension and the benefit cap) and #2793 (the ESA support component and the benefit cap).

## Reproducer

Reproducer: policyengine_uk/tests/test_oxford_council_tax_reduction_universal_credit_properties.py::test_each_receipt_counts_once; policyengine_uk/tests/policy/baseline/gov/local_authorities/oxford/council_tax_reduction/oxford_council_tax_reduction_universal_credit.yaml; policyengine_uk/tests/policy/baseline/gov/local_authorities/oxford/council_tax_reduction/oxford_council_tax_reduction_universal_credit_earlier_years.yaml

axiom: TheAxiomFoundation/rulespec-uk#513 queued

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Generated by Claude Code

@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Ready for hub review

Head: 2343a786174659e9e52a834af44808bdb4170e78 on branch claude/invariant-6-oracle-fix-phcnxv, one commit on 98a2e5755. It changes the test file only, with no formula, parameter or list entry. I have not pushed to #2794's branch.

Finding C1 (invariant 6 fails at 98a2e5755). It reproduces: test_appendix_3_income_matches_the_other_councils_universal_credit_income 1 failed in 352.61 s at 98a2e5755. Hypothesis shrank to a couple (47, and 50 earning £13,900.91), no children, no housing costs, deduction rate 0.15. The Merton readback gave £14,204.75 against the oracle's £13,780.37, a gap of £424.38. That family's uc_deductions comes to £424.38. 0.15 of its standard allowance (£8,003.64) would be £1,200.55, but the award before deductions comes to only £424.50, so the deduction leaves £0.12. In the review's case (a 25-year-old parent earning £20,784.920404, two infants) the readback gave £25,397.50 against the old oracle's £24,632.67, a gap of £764.83. That case's uc_deductions comes to £764.82 = 0.15 × £5,098.80, which confirms the £424.90 a month. So the gap equals uc_deductions in both cases, and #2822 causes it as the hub read it.

  • Oracle (policyengine_uk/tests/test_oxford_council_tax_reduction_universal_credit_properties.py:646-654): I dropped - values["uc_deductions"][i] from council_income and rewrote the comment above it: those councils, like Oxford, count the award before deductions for debts. I rewrote invariant 6 in the module docstring (lines 50-55), whose closing parenthesis now reads "(they, like Oxford, count the award before deductions for debts)". uc_deductions stays in INCOME_VARIABLES because invariants 2 and 4 read it.
  • Regression (line 597): @example(units=couple_and_debt_families()[1:]), deduction rate 0.25. has_award holds (Universal Credit £7,612.32, deductions £1,274.70). Each other council's award falls below its maximum: Merton, Kingston upon Thames and Westminster £48,574.44 of £50,000, Newham £33,218.05 of £35,000. So the readback branch runs at all four. The old oracle would miss by £1,274.69, the new one by £0.006.
  • Revert check: I ran scratch copies of the test file with phases=[Phase.explicit], outside the repository and so without its conftest. With the old oracle and the new example: 1 failed in 16.80 s, assert 1274.694091796875 < 0.25 on the debt example. With the new oracle: 1 passed in 16.06 s.
  • Other readers of uc_deductions: test_appendix_3_income_and_band (line 422) and test_pound_for_pound (line 514) read it for Oxford's own award. Both pass at the head (below).

Runs at 2343a7861 (clean runs after uv sync --frozen --extra dev):

  • The property file with -n 4: 7 passed in 167.18 s. Durations: locality 114.28 s, monotonicity 71.10 s, test_appendix_3_income_and_band 43.82 s, test_pound_for_pound 37.47 s, invariant 6 36.81 s, test_each_receipt_counts_once 33.42 s, test_earlier_years_keep_the_paragraphs_14_to_27_income 29.58 s. These run faster than the body's earlier figures; this container runs quicker, and the locality test finished well inside the old 1,500 s cap.
  • policyengine-core test policyengine_uk/tests/policy/baseline/gov/local_authorities -c policyengine_uk: 429 passed in 67.61 s.
  • test_council_tax_reduction_applicant_properties.py with -n 4: 2 passed in 101.16 s. policyengine_uk/tests/code_health with -n 4: 3,150 passed in 180.25 s.
  • .github/check_fix_pr.py on the live title, no labels, the new body and the merge-base diff, as pr_fix_evidence.yaml builds them: PASS, "Changed executable tests: 3".
  • uvx ruff@0.17.2 format --check . (2,213 files already formatted), check . and check --select F811,F821 policyengine_uk: clean. git diff --check 98a2e5755..HEAD: clean.
  • git merge-tree --write-tree --name-only HEAD origin/main (origin/main at 9dd44e142): exit 0, tree 430ed54a6, no conflicts, so I merged nothing from main.

Skipped: nothing on the brief's list. No test needed survey data.

Judgment calls:

  • 98a2e5755 landed at 12:38Z, under 6 hours before I started (13:35Z). I treated it as the base the brief names, not another writer. The 13:29Z review restates C1 and asks for nothing more.
  • The body said "The test file, every formula and every list entry stand as they did at 290b095e6", which no longer holds for the test file. I rewrote it to say the formulas and list entries stand and 2343a7861 changes only invariant 6's test. I added the head's runs and the revert result as two sub-bullets under Property tests, and a line for the head's YAML, applicant, code_health, ruff and merge-tree runs. I left the text on Count the UC award before debt deductions in four councils' CTR #2822, "Who has an award", the overlap section, the merge note and the Fixes, Reproducer: and axiom: lines alone. The be-verb grep's one hit falls inside quoted law.
  • The new example deducts at 0.25, a rate families() never draws (it draws 0, 0 or 0.15).

I posted PR_BODY.md in full in the comment above. The hub posts REPLY.md:

REPLY.md

Thanks: C1 reproduces, and the cause sits in the test's oracle, not in either council's assessment.

**Cause.** #2822 made `legacy_council_tax_reduction` count `universal_credit` plus `uc_deductions`, the award before deductions for debts, for Merton, Kingston upon Thames, Newham and Westminster. Invariant 6's oracle still took `uc_deductions` off Oxford's Appendix 3 income, as if those councils counted the award after deductions. At `98a2e5755` the gap between the Merton readback and the oracle equals the family's `uc_deductions` every time: £764.83 against £764.82 (0.15 × £5,098.80) for your parent earning £20,784.92 with two infants, and £424.38 against £424.38 for the couple Hypothesis shrank to on my run.

**Change** (`2343a7861`, test only, no formula). The oracle in `test_appendix_3_income_matches_the_other_councils_universal_credit_income` no longer subtracts `uc_deductions`, and the comment above it and invariant 6 in the module docstring now say both routes count the award before deductions for debts.

**Regression.** The test gains `@example(units=couple_and_debt_families()[1:])`, a single claimant repaying debts at 0.25 of the standard allowance. The family keeps its award and each other council's award falls below its maximum, so the test reads back the income at all four councils. With only explicit examples run, the old oracle fails on it (gap £1,274.69, its `uc_deductions` £1,274.70) and the new one passes.

**Runs at `2343a7861`.** The whole property file with `-n 4`: 7 passed in 167.18 s (invariant 6's test 36.81 s). `test_appendix_3_income_and_band` and `test_pound_for_pound`, which read `uc_deductions` for Oxford's own award, pass. The `local_authorities` YAML tree: 429 passed. `test_council_tax_reduction_applicant_properties.py`: 2 passed. `code_health`: 3,150 passed. Ruff, `git diff --check` and the fix-evidence check pass, and the branch merges cleanly with `main` at `9dd44e142`.

PR_BODY.md (the same text as the comment above)

Fixes #2520

## What and why

In its [Council Tax Reduction Scheme 2026 to 2027](https://www.oxford.gov.uk/council-tax-reduction/council-tax-reduction-scheme-2026-27), Oxford City Council divides working-age applicants into two groups and bands each on weekly income (Part 1 para 9).
- For an applicant without Universal Credit, the council calculates income "in accordance with paragraphs 14-27" and deducts "50% of contributions to occupational or personal pension schemes" from earnings (para 18). In the heading before para 14 it limits paragraphs 14 to 27 and Annexes 5 and 6 to pensioners and working-age applicants without Universal Credit.
- For an applicant with Universal Credit, the council sets the income in [Appendix 3](https://www.oxford.gov.uk/council-tax-reduction/council-tax-reduction-scheme-2026-27/4). It adds "their net earned income (as provided by DWP) to the amount of Universal Credit awarded", ignores any transitional element and counts other (unearned) income weekly. It ignores "£48.15 of the Universal Credit carer element" and "£84.46 of the Universal Credit disabled child element". DWP deducts "any relievable pension contributions" in full when it calculates net earned income (UC Regs 2013 [reg 55(5)(a)](https://www.legislation.gov.uk/uksi/2013/376/regulation/55)).

In `oxford_council_tax_reduction` the model banded every working-age applicant on `council_tax_reduction_applicable_income`, the paragraphs 14 to 27 income with Oxford's 50% share. So the model deducted half of a Universal Credit claimant's pension contributions instead of all of them, and left out their Child Benefit and child maintenance. A reform of Oxford's pension contribution share also moved their reduction.

This PR makes five changes.
- **Appendix 3 income.** The model adds three amounts in a new variable, `oxford_council_tax_reduction_universal_credit_income`:
  - `uc_earned_income_before_work_allowance`, DWP's net earned income after tax, National Insurance and relievable pension contributions, before the work allowance;
  - `oxford_council_tax_reduction_universal_credit_other_income`, a new variable in which the model sums the applicant's and partner's receipts that it lists in a new parameter (below);
  - the award: `universal_credit` plus `uc_deductions`, the amount DWP awards before it takes deductions for debts out of the payment, less the element disregards and not below nil.

  For the four other councils (`_legacy.py`), the model counts Universal Credit's own unearned income and, since #2822, the award before deductions for debts. This PR leaves `_legacy.py` alone.
- **Other income.** The model lists its variables one by one in `gov.local_authorities.oxford.council_tax_reduction.universal_credit.other_income_sources`, with the reason for each in the file.
- **Disregards.** The model holds the weekly amounts from 1 April 2026 in two Oxford parameters: `universal_credit.carer_element_disregard` (£48.15) and `universal_credit.disabled_child_element_disregard` (£84.46).
- **Start date.** The model switches the route on from 1 April 2026 through `universal_credit.in_effect`, which is false from 2015. The model reads each year's parameters at 30 April. So the Appendix 3 route starts in model year 2026, and in model years 2025 and earlier `oxford_council_tax_reduction` gives the results it gave before. A user can move the route with a reform of `in_effect`. The model gates only the route this way. The list and the two disregards start on 1 April 2026, and the model carries them back to 2015 like its other Oxford parameters. So the two new variables still return Appendix 3 amounts for earlier years, though the reduction does not read them. In 2025, the new variables give a lone parent earning £15,600 with two children and £2,600 of child maintenance other income of £4,851.60 and Appendix 3 income of £27,833.34. Paragraphs 14 to 27 still set their reduction, £1,800.
- **Banding and docs.** In `oxford_council_tax_reduction` the model bands a Universal Credit applicant on a fifty-second of the Appendix 3 income. An applicant without Universal Credit keeps the same arithmetic, bit for bit, and the model still adds Oxford's tariff income only for them. This PR also rewrites the pension contribution share's variable and parameter documentation to name the applicants the share reaches.

The model builds the award's maximum amount (`uc_maximum_amount`) from the standard allowance and the child, disability, carer, housing and childcare elements, and nothing else. So the award holds no transitional element to remove.

**Earlier schemes.** In its [2025-26 scheme](https://www.oxford.gov.uk/council-tax-reduction/council-tax-reduction-scheme-2025-26/4) Oxford City Council sets an Appendix 3 with the same income rule. It tops the bands at £500, £575, £650 and £700, ignores £46.40 of Carer's Allowance in place of the two element disregards, and includes no transitional-element sentence. The model applies the 2026-27 parameters to every earlier year, so this PR keeps earlier years on their previous results and does not model 2025-26. The council's 2024-25 scheme pages at the same address return 404.

### Readings

- **Other income.** In Appendix 3 Oxford City Council lists the income it ignores and says "All other unearned income is taken into account". It ignores Child Benefit and child maintenance in Appendix 5, which "applies to pensioners and working-age applicants who do not receive Universal Credit". In Appendix 3 it repeats several items from that list, Attendance Allowance, Disability Living Allowance, Personal Independence Payment, Discretionary Housing Payments and Housing Benefit among them, but not those two. So the council counts Child Benefit and child maintenance for these applicants, along with the receipts DWP counts, and so does the model. For a receipt DWP counts, DWP takes each pound off the award and Oxford adds it back as other income. The two effects cancel while DWP's net earned income and the award's other terms stay fixed, no benefit cap applies and the award stays above nil after the disregards. A taxable receipt can break the first condition. In 2027, a 70-year-old earning £13,036.40, in a couple with a 60-year-old, loses £93.28 of Pension Tax Allowance when they receive £520 of private pension. DWP's net earned income then falls £93.28, the award £468.70 and the Appendix 3 income £41.98.
- **Miscellaneous income.** The model counts miscellaneous income in DWP's net earned income (`uc_individual_earned_income_before_mif`) and leaves it off the list, so it counts the income once. DWP counts miscellaneous income as unearned income (reg 66(1)(m)). If #1961 moves the model's figure there, the model will take it off the award pound for pound, as DWP does, and must add it back to the list.
- **Carer Support from Scotland.** Social Security Scotland keeps paying Carer Support for 13 weeks after a carer moves to another part of the United Kingdom ([SSI 2023/302 reg 42](https://www.legislation.gov.uk/ssi/2023/302/regulation/42)). It pays the Scottish Carer Supplement for each week it pays the carer support payment ([reg 14A](https://www.legislation.gov.uk/ssi/2023/302/regulation/14A)). DWP counts the carer support payment only up to a year of Carer's Allowance ([reg 66(1)(b)(iiia)](https://www.legislation.gov.uk/uksi/2013/376/regulation/66)) and does not count the supplement. Oxford City Council ignores the part above Carer's Allowance only in Appendix 5, so the model counts both payments whole.
- **One-off receipts.** In Appendix 6 Oxford City Council names some one-off payments as capital: the first month's Bereavement Support Payment, Energy Rebate Scheme 2022 payments, "any other payments made by the Government to help with the cost of living" and payments for a personal injury. The model reads the council's capital and income lists together. It keeps out of Appendix 3 income a one-off payment that attaches to no period and that the council names in Appendix 6. It counts regular Bereavement Support Payment and Armed Forces Compensation Scheme payments, Guaranteed Income Payments included: the model reads `bsp_reported` and `afcs_reported` as regular payments and counts `bsp` and `afcs` whole. If a user enters a lump sum in either input, the model counts it as income.
- **Capital.** Oxford City Council treats "any income derived from capital" as capital (para 30 and Annex 7) and sets no other rule for it in Appendix 3, so the model leaves out interest, dividends and rent. DWP deems an assumed yield from capital (`uc_tariff_income`, reg 72) and takes it off the award, but nobody receives it, so the model does not add it back. The council adds its own assumed income only under paragraphs 14 to 27 (para 15), and ignores capital "already taken into account when the applicant is receiving Universal Credit" (Appendix 6). So the council counts capital for these applicants only through the award DWP reduces. Oxford City Council publishes nothing on its practice for Child Benefit or capital beyond the scheme text.
- **Whose income.** Oxford City Council counts "the income of the applicant and, where appropriate, their partner" (Appendix 3). The model counts each person's receipts for the Council Tax Reduction applicant and partner, as `council_tax_reduction_applicable_income` does, so a younger partner's receipts count and a 17-year-old's do not. A household head who applies alone has no award, so the council assesses them under paragraphs 14 to 27 on their own income, without the benefit unit's Child Benefit.
- **Who has an award.** In Appendix 3 Oxford City Council also covers an applicant whose award DWP reduces to nil through deductions or other adjustments. The model puts a family on this route when DWP pays it Universal Credit. It does the same when the family claims Universal Credit and the benefit cap or deductions for debts take its award to nil (`council_tax_reduction_universal_credit_award`, which #1995 added).
- **DWP figures.** The model reads "net earned income (as provided by DWP)" as the earned income DWP uses in the Universal Credit calculation. For a self-employed claimant DWP uses the minimum income floor where it applies (UC Regs 2013 [reg 62](https://www.legislation.gov.uk/uksi/2013/376/regulation/62)), and so does the model.
- **Award before deductions for debts.** Oxford City Council counts "the amount of Universal Credit awarded" and, in Appendix 3's first sentence, names deductions apart from the award. So the model adds back `uc_deductions` (the deductions for debts DWP takes from the payment), and a reform of those deductions does not move Oxford reductions. DWP applies the benefit cap to the award itself, so the model keeps the capped award.
- **One disregard for each element.** £48.15 and £84.46 match the 2026-27 carer premium and disabled child premium. Councils include the carer premium in Housing Benefit "in respect of each person" who meets the carer condition. They include the disabled child premium for "each child or young person" who meets its condition (HB Regs 2006 [Sch 3 para 20(7) and (8)](https://www.legislation.gov.uk/uksi/2006/213/schedule/3)). DWP includes a carer element for each claimant who cares (reg 29) and a disabled child addition for each disabled child (reg 24(2)). So the model ignores up to each amount for each element, taking it off the award but not below nil.

The model treats these receipts as follows:

| Variable | Appendix 3 income | Oxford text |
|---|---|---|
| `child_benefit` | counted | Oxford City Council applies its Appendix 5 disregard only without Universal Credit |
| `maintenance_income` (child maintenance received) | counted | Oxford City Council applies its Appendix 5 disregard only without Universal Credit |
| `spousal_maintenance_income`, `private_pension_income`, `state_pension`, `carers_allowance`, `carer_support_payment`, `jsa_contrib`, `esa_contrib`, `maternity_allowance`, `iidb`, `widowed_parents_allowance`, `incapacity_benefit`, `sda` | counted | "All other unearned income"; the receipts DWP counts as unearned income (reg 66). The council gives its £15 disregards only without Universal Credit (Appendix 5) |
| `scottish_carer_supplement` | counted | "All other unearned income"; Social Security Scotland pays it with the carer support payment, for 13 weeks after a move from Scotland. The model pays 52 weeks (Limits) |
| `bsp`, `afcs`, `war_widows_pension`, `armed_forces_independence_payment`, `ssmg`, `healthy_start_vouchers`, `private_transfer_income` | counted | "All other unearned income"; the council names none of them in Appendix 3, and applies its war pension, Armed Forces Independence Payment and Healthy Start disregards only without Universal Credit. The model reads `bsp` and `afcs` as regular payments |
| `income_support`, `claimant_or_partner_jsa_income`, `claimant_or_partner_esa_income`, `tax_credits`, `pension_credit` | counted | "All other unearned income"; DWP replaces these awards with Universal Credit, so a claimant receives none of them |
| `miscellaneous_income` | in DWP's net earned income | the model's Universal Credit earnings (#1961) |
| `uc_tariff_income`, Oxford's tariff income | out | an assumed yield, not a receipt; para 15 |
| `savings_interest_income`, `other_investment_income`, `tax_free_savings_income`, `dividend_income`, `individual_savings_account_dividend_income`, `property_income`, `capital_gains` | out | para 30 and Annex 7: income derived from capital; the council also ignores rent from sub-tenants and boarders in Appendix 3 |
| `attendance_allowance`, `dla`, `pip`, `housing_benefit`, `council_tax_benefit` | out | Oxford City Council ignores them in Appendix 3 (`council_tax_benefit` holds the reduction itself) |
| `statutory_sick_pay`, `statutory_maternity_pay`, `statutory_paternity_pay` | in DWP's net earned income | reg 55(4) |
| `winter_fuel_allowance`, `winter_fuel_payment`, `cost_of_living_support_payment`, `energy_bills_rebate`, `household_energy_payment`, `epg_subsidy` | out | one-off payments that attach to no period: Oxford City Council names Energy Rebate Scheme 2022 payments and other Government cost-of-living payments, such as the £100 Household Energy Payment, as capital in Appendix 6 |
| `student_loans`, `education_grants`, `student_payments`, `adult_dependants_grant`, `access_fund` | out | Oxford City Council treats them under Annex 8, with its own rules and disregards; the model counts student income in no Council Tax Reduction scheme |
| `adult_ema` | out | Annex 8 keeps an educational maintenance allowance out of "grant", and Appendix 3 does not ignore it, so the council counts one the applicant or partner receives (Limits) |
| `child_ema` | out | a child's receipt; the council counts only the applicant's and partner's income |
| `scottish_child_payment`, `two_child_limit_payment`, `pension_age_winter_heating_payment`, `pawhp`; Guardian's Allowance | out | the model computes the Scottish ones only for households in Scotland; the model has no Guardian's Allowance |

When a lone parent earning £15,600 with two children receives £520 more of a listed source in 2026, DWP's net earned income and the income tax DWP deducts from it stay the same. For each receipt DWP counts, DWP lowers the award by £520, and the Appendix 3 income stays the same. For each other listed source, the award stays the same and the Appendix 3 income rises £520. With Carer's Allowance, the model also adds the carer element (£2,512.08) to the award, and Oxford ignores £2,503.80 of it, so the Appendix 3 income rises £8.28. With the carer support payment, the model adds the carer element and also pays its £608.40 supplement, so other income rises £1,128.40 and the Appendix 3 income £616.68. The carer support payment gives Carer's Allowance's £8.28 only with the supplement held fixed. The model now counts miscellaneous income only in DWP's net earned income: £520 more raises that figure by £416 after income tax, lowers the award by £228.80 and raises the Appendix 3 income by £187.20.

This family shows none of three other routes:
- Where the model computes Carer's Allowance, DWP reduces it by maternity allowance, contributory JSA or ESA, incapacity benefit, severe disablement allowance, Widowed Parent's Allowance or State Pension (Overlapping Benefits Regs 1979 [reg 12](https://www.legislation.gov.uk/uksi/1979/597/regulation/12)). So £520 more of one of them leaves other income, the award and the Appendix 3 income unchanged.
- Where the benefit cap applies, a receipt can lift it. In a capped Oxford family in the South East, the model keeps the cap on with £520 of War Widow's Pension, though reg 83(1)(d) lifts it, so the Appendix 3 income rises £520. With £520 of the Armed Forces Compensation Scheme it lifts the cap, and the Appendix 3 income rises £12,808.84.
- In 2027 a taxable receipt can cut the Pension Tax Allowance, as under Readings.

**Limits.**
- For a disabled applicant, the council also ignores an amount equal to any disability premium payable before the move to Universal Credit. The model holds no record of that earlier award and ignores nothing, so it can overstate such an applicant's income and understate their reduction.
- The council counts students' loans and grants under Annex 8, with its own disregards, and counts an educational maintenance allowance the applicant or partner receives as other income. DWP counts student income in the award (reg 66(1)(e)). The model counts none of them, so it can misstate a student's income and reduction.
- The model counts `bsp` and `afcs` whole, so if a user enters a lump sum there, the model counts it as income.
- The model pays the Scottish Carer Supplement for 52 weeks whenever the carer support payment is positive. An Oxford household receives at most 13 weeks of it (SSI 2023/302 regs 14A and 42), or 25 after a death in the run-on. For a lone parent of two with housing costs of £12,560 and 13 weeks of Carer Support, the model's £608.40 of supplement gives band 3 and £900. The law's 13 weeks, £152.10, give band 2 and £1,350.

### Overlap with other work

Of the 77 open pull requests, one touches this PR's files. **#1966 (draft, `ctr-working-age-shortfall`)** conflicts with this branch in the `council_tax_reduction_pension_contribution_deduction_rate` documentation: keep #1966's Wales and Scotland route and this PR's Oxford sentence. #1966 also conflicts with `main` in three files this PR does not touch.

We merged `main` at `acba5efc1` into this branch, bringing in #1995 and #2822. With #1995 the model ignores capital for Universal Credit and passported applicants under Appendix 6, and looks up `council_tax_reduction_relevant_income_based_benefit` above that rule in `oxford_council_tax_reduction.py`. We kept both in the merge, with this PR's Appendix 3 block below them and no second lookup.

## Invariants

Invariants 1 to 6 and 8 hold for every working-age Oxford family whose applicant has a Universal Credit award, from 2026. Invariant 7 covers earlier years, and invariant 9 families without an award.

1. **Locality.** No reform of Oxford's pension contribution share changes the family's Oxford reduction, while every Oxford family reads the reform's share.
2. **Appendix 3 income.**
   - Other income is the family's Child Benefit at HMRC's rates plus child and spousal maintenance and its other listed receipts, with no interest, dividends, rent or assumed yield.
   - The income is net earned income plus other income plus the award before deductions for debts, less ignored amounts.
   - The ignored amounts are never negative and never exceed the award or the elements. They are at most £48.15 a week for each carer element and £84.46 a week for each disabled child, and nil with no such element.
3. **Bands.** The reduction is the council tax share times the rate Oxford City Council sets in its band table for a fifty-second of the income, less non-dependant deductions.
4. **Pound for pound.** While the award stays above nil after the disregards, no benefit cap applies, and DWP's net earned income and the award's other terms stay the same:
   - £1 more of a receipt DWP deducts from the award (spousal maintenance, a private pension) leaves the income unchanged, because DWP lowers the award by £1;
   - £1 more of Child Benefit or child maintenance raises it by £1;
   - £1 more interest leaves it unchanged;
   - more capital lowers it by the rise in DWP's assumed yield.
5. **Monotonicity.** More pension contributions never lower the reduction of a family that keeps its award.
6. **Differential with the other councils.** Swap Oxford's other income in the Appendix 3 income for Universal Credit's unearned income. For a family with no carer or disabled child element and no capital, the result equals the Universal Credit income behind the awards of Merton, Kingston upon Thames, Newham and Westminster. Those councils, like Oxford, count the award before deductions for debts.
7. **Earlier years.** In model years 2025 and earlier, every family's Oxford reduction equals `origin/main`'s. A family with an award keeps the band of its paragraphs 14 to 27 income less Child Benefit, with no tariff income.
8. **Each receipt once.** More of a receipt Oxford City Council counts as other income, with every other receipt held fixed, raises other income by the whole amount, including a carer support payment above DWP's cap. It leaves DWP's net earned income unchanged while the income tax DWP deducts stays fixed. A receipt DWP takes off Carer's Allowance under the overlapping-benefit rules raises other income by the net amount: nothing, where DWP takes the whole receipt off. The model adds miscellaneous income to DWP's earned-income calculation, where a minimum income floor can absorb it, and leaves other income unchanged. The model leaves interest, dividends and rent out of other income; their effect on DWP's net earned income depends on the income tax DWP deducts. Receipts of anyone but the applicant and partner never change other income.
9. **Differential with `origin/main`.** In 2026, every family not on Universal Credit gets `origin/main`'s Oxford reduction, bit for bit.

## Test plan

- [x] For policy changes: YAML tests whose expected values come from an external source.
  - `oxford_council_tax_reduction_universal_credit.yaml` holds 36 cases, and `oxford_council_tax_reduction_universal_credit_earlier_years.yaml` holds 9. Each case shows hand-worked arithmetic from the scheme text, DWP's and HMRC's rates for the year and the income tax and National Insurance rules, citing the paragraph.
  - The 2026 cases cover the Appendix 3 income with pension contributions, two reforms of the Oxford share and a lone parent before the work allowance. They cover the carer and disabled child disregards (one carer, two carers, the floor at nil, one disregard for each child) and the award before deductions for debts. They also cover Child Benefit, child maintenance, spousal maintenance, a private pension, miscellaneous income, a regular Armed Forces Compensation Scheme payment, interest, dividends, rent, and capital of £11,250 and £16,000.
  - Seven cases test whose receipts count and how. A younger partner's child maintenance counts, and a 17-year-old's private transfers do not. Personal Independence Payment, Attendance Allowance and Disability Living Allowance stay out. A self-employed claimant under the minimum income floor counts the floor's £20,386.03, not the £5,000 they earn. A carer whose Carer's Allowance the model computes, £4,495.40 less £2,600 of Widowed Parent's Allowance, counts the £1,895.40 DWP pays.
  - Two cases follow carers who move from Scotland, and each supplies the supplement. One receives 13 weeks of it with 13 weeks of carer support payment, and one receives a carer support payment above DWP's cap. A household head who applies alone keeps her own income, without the couple's award. Two cases without Universal Credit keep `origin/main`'s results.
  - The earlier-years cases pin 2024 and 2025 to `origin/main`'s results for a single claimant, a parent with Child Benefit and a parent with child maintenance. They also check that reforms of `in_effect` move the route in 2025 and 2026.
  - All 36 and all 9 pass at `aa2f0a579` (39.17 s and 82.37 s), and at `d5403d70a`, whose tests and model match. Every mutant in the table below fails at least one 2026 case, except two that agree with the code on every lawful input.
- [x] Property tests: `test_oxford_council_tax_reduction_universal_credit_properties.py` holds 7 test functions, one for each of invariants 1 to 8 (invariants 2 and 3 share one). Each runs 5 generated populations plus its explicit examples, with Hypothesis derandomised. Every formula and every list entry stand as they did at `290b095e6`. `2343a7861` changes only invariant 6's test: its oracle no longer takes `uc_deductions` off the Appendix 3 income, and it gains an explicit example of a single claimant who repays debts at a quarter of the standard allowance.
  - At `2343a7861`, one `-n 4` run of the whole file: 7 passed in 167.18 s. The locality test took 114.28 s, `test_more_pension_contributions_never_lower_the_reduction` 71.10 s, `test_appendix_3_income_and_band` 43.82 s, `test_pound_for_pound` 37.47 s, `test_appendix_3_income_matches_the_other_councils_universal_credit_income` 36.81 s, `test_each_receipt_counts_once` 33.42 s and `test_earlier_years_keep_the_paragraphs_14_to_27_income` 29.58 s.
  - At `98a2e5755`, before that change, invariant 6's test failed on a generated couple with deductions for debts at 0.15 of the standard allowance: the Merton award implied income £424.38 above the oracle, exactly the family's `uc_deductions`. For the generated parent earning £20,784.92 with two infants, the gap came to £764.83 against `uc_deductions` of £764.82. With only the explicit examples run, the debt example fails under the old oracle (a gap of £1,274.69, its `uc_deductions` of £1,274.70) and passes under the new one. The family keeps its award, and each other council's award falls below its maximum, so the test reads back its income at all four councils.
  - At `aa2f0a579`: `test_each_receipt_counts_once` 1 passed in 432.69 s, and `test_appendix_3_income_matches_the_other_councils_universal_credit_income` 1 passed in 487.40 s. At `d5403d70a`, whose tests and model match, `test_more_pension_contributions_never_lower_the_reduction` 1 passed in 471.62 s.
  - At `290b095e6`: `test_appendix_3_income_and_band` 1 passed in 766 s and `test_pound_for_pound` 1 passed in 437 s. At `7fa10f27e`: `test_earlier_years_keep_the_paragraphs_14_to_27_income` 1 passed in 565 s. The locality test passed at `021bc2847`; at `7fa10f27e` its explicit families at shares 0 and 1 passed in 1,367 s, and the full run did not finish inside a 1,500 s cap.
  - `test_each_receipt_counts_once` supplies each of 31 receipts, written out from the scheme rather than read from the parameter, to the last adult of each generated family and, for person-level receipts, to the first child. With the new test file, it fails at `ae9bbabd1`, this branch before the miscellaneous income and Scottish Carer Supplement changes: the supplement moves other income by £0, not £520. On `origin/main` (`2da212abc`) it fails on its first explicit example: "Variable oxford_council_tax_reduction_universal_credit_other_income does not exist".
  - The generated families give each adult receipt to the last adult, the eldest, who heads the benefit unit, and supply Carer's Allowance and the supplement as inputs. They hold no 16-to-19-year-old, self-employment or disability benefit, so the seven route cases above cover those.
- [x] Mutations: each ran in its own scratch copy of `d5403d70a`, one at a time, under a 2 GB memory cap, against the 36 cases of the 2026 YAML file.

  | Mutant | 2026 YAML (36 cases) | Property test run against it |
  |---|---|---|
  | Other income read from `uc_unearned_income` | 23 failed | `test_appendix_3_income_and_band` fails (`290b095e6`) |
  | One carer disregard for the award | 1 failed: the couple who both care, 26,680.50 instead of 24,176.70 | not run |
  | Benefit unit's awards counted for a head who applies alone | 1 failed: her other income, 28,806.60 instead of 27,400 | not run |
  | DWP's figures and the award counted for a head who applies alone | 1 failed: her Appendix 3 income, 37,387.36 instead of 27,400 | not run |
  | `uc_tariff_income` added to the list | 2 failed: the assumed yield and £16,000 capital cases | not run |
  | `afcs` removed from the list | 1 failed: the Armed Forces Compensation Scheme case, other income 2,337.40 instead of 4,937.40 | `test_each_receipt_counts_once` fails on `afcs` (`290b095e6`) |
  | `carer_support_payment` replaced by DWP's capped `uc_unearned_carer_support_payment` | 1 failed: the carer support payment above DWP's cap, other income 7,441.20 instead of 8,145.80 | `test_each_receipt_counts_once` fails (`290b095e6`) |
  | `miscellaneous_income` put back on the list | 1 failed: the miscellaneous income case, other income 4,937.40 instead of 2,337.40 | `test_each_receipt_counts_once` fails (`290b095e6`) |
  | `scottish_carer_supplement` removed from the list | 2 failed: the two Scottish carer cases | `test_each_receipt_counts_once` fails (`290b095e6`) |
  | Other income counts every member aged 16 or over, not the applicant and partner | 1 failed: the 17-year-old's receipt, other income 4,937.40 instead of 2,337.40 | not run |
  | Other income counts the benefit unit head's receipts alone | 1 failed: the younger partner's maintenance, other income 1,406.60 instead of 4,006.60 | not run |
  | `pip` and `attendance_allowance` added to the list | 2 failed: the two cases, other income 4,937.40 instead of 2,337.40 and 7,600 instead of 5,000 | not run |
  | Appendix 3 reads each claimant's earned income before the minimum income floor | 1 failed: the floor case, Appendix 3 income 11,386.48 instead of 26,772.51 | not run |
  | The supplement counts only beside a carer support payment | 36 passed | `test_each_receipt_counts_once` fails on `scottish_carer_supplement`, which it supplies with no carer support payment (`d5403d70a`) |
  | `tax_credits` taken off the list | 36 passed | `test_each_receipt_counts_once` fails on `tax_credits` (`7fa10f27e`) |

  The miscellaneous income and supplement removal mutants undo this PR's two list changes. Social Security Scotland pays the supplement only in weeks it pays the carer support payment (reg 14A), and no claimant receives tax credits beside Universal Credit. So no lawful YAML case tells the last two mutants from the code.
- [x] Differential against `origin/main` (`2da212abc`), with this branch at `7238eba63`, on 400 generated Oxford households and 497 benefit units, for 2024, 2025 and 2026. `numpy.random.default_rng(2520)` draws one or two adults with earnings, pension contributions, self-employment, spousal maintenance, private pensions and carers. It adds up to two children, some disabled, a non-dependant in a quarter of households, housing costs and savings of 0 to 17,000, and `default_rng(25200)` adds child maintenance and interest.
  - 2024 and 2025: all 497 benefit units get `origin/main`'s Oxford reduction, and all 400 households its Council Tax Reduction, bit for bit.
  - 2026: all 378 benefit units without a Universal Credit award match bit for bit; 123 of them get a reduction. Of the 108 working-age claimant families with an award, 6 rise (+£4,000) and 29 fall (−£19,850), −£15,850 in all and −£146.76 per claimant family. 25 of the 29 that fall receive Child Benefit.
  - Later commits change two list entries (miscellaneous income out, the Scottish Carer Supplement in), tests and documentation, and no formula. The population holds no miscellaneous income, and the model pays no carer support payment or Scottish Carer Supplement in Oxford, so those entries cannot move its results. At `7fa10f27e` its 2026 arrays for the reduction, the award, other income, Appendix 3 income and household Council Tax Reduction match `ae9bbabd1`'s bit for bit.
- [x] Existing tests: `test_parameter_descriptions.py`, 24 passed at `aa2f0a579`. At `ae9bbabd1`, the `policy/baseline/gov/local_authorities` YAML tree passed 403 cases and `test_council_tax_reduction_applicant_properties.py` 2 tests. At `7fa10f27e`, the tree's 113 cases outside `oxford/` that hold an Oxford household passed, and so did `test_council_tax_reduction_assesses_the_liable_head`. At `aa2f0a579`, `test_head_applying_alone_matches_her_own_benefit_unit` 1 passed in 2,188.36 s. No Oxford case outside `oxford/` holds miscellaneous income, a carer support payment or the supplement, so the later list changes cannot reach them. At `2343a7861`, the `policy/baseline/gov/local_authorities` YAML tree passed 429 cases in one `policyengine-core test` run, `test_council_tax_reduction_applicant_properties.py` 2 tests and `code_health` 3,150 tests.
- [x] At `2343a7861`: `ruff format --check .`, `ruff check .` and `ruff check --select F811,F821 policyengine_uk` (ruff 0.17.2) and `git diff --check 98a2e5755..2343a7861` clean; `git merge-tree` against `origin/main` (`9dd44e142`) merges without conflict.
- [x] `ruff format --check`, `ruff check` and `ruff check --select F811,F821 policyengine_uk` on the 5 changed Python files, and `git diff --check`: clean at `aa2f0a579`.
- [x] Changelog fragment `changelog.d/2520.fixed.md`.
- [x] `19378b97f` rewrites one variable's documentation and changes no code: its syntax tree, with `documentation` removed, matches `aa2f0a579`'s.

No survey data: every simulation uses hand-built situations.

Follow-ups: #2789 (Oxford's route before April 2026), #2790 (student income), #2791 (Scottish Carer Supplement weeks), #2792 (War Widow's Pension and the benefit cap) and #2793 (the ESA support component and the benefit cap).

## Reproducer

Reproducer: policyengine_uk/tests/test_oxford_council_tax_reduction_universal_credit_properties.py::test_each_receipt_counts_once; policyengine_uk/tests/policy/baseline/gov/local_authorities/oxford/council_tax_reduction/oxford_council_tax_reduction_universal_credit.yaml; policyengine_uk/tests/policy/baseline/gov/local_authorities/oxford/council_tax_reduction/oxford_council_tax_reduction_universal_credit_earlier_years.yaml

axiom: TheAxiomFoundation/rulespec-uk#513 queued

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Generated by Claude Code

@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Thanks for the re-review. C1 reproduces, and we fixed the test's oracle, with no change to any formula.

Since #2822, legacy_council_tax_reduction counts universal_credit plus uc_deductions for Merton, Kingston upon Thames, Newham and Westminster: the award before deductions for debts, as Oxford City Council does under Appendix 3. Invariant 6's oracle still took uc_deductions off Oxford's Appendix 3 income, as if those councils counted the award after deductions. At 98a2e5755, the gap between the Merton readback and the oracle matched the family's uc_deductions in both failures we saw. For your parent earning £20,784.92 with two infants, the gap came to £764.83 against uc_deductions of £764.82 (0.15 × £5,098.80). For the couple Hypothesis shrank to on our run, both came to £424.38.

In 2343a7861, which changes only the test file, the oracle in test_appendix_3_income_matches_the_other_councils_universal_credit_income no longer subtracts uc_deductions. The comment above it and invariant 6 in the module docstring now say that those councils, like Oxford, count the award before deductions for debts. The test also gains @example(units=couple_and_debt_families()[1:]), a single claimant who repays debts at a quarter of the standard allowance. The family keeps its award, and each other council's award falls below its maximum, so the test reads back the income at all four councils. With only the explicit examples run, the old oracle fails on it by £1,274.69, against uc_deductions of £1,274.70, and the new one passes.

At 2343a7861, one -n 4 run of the property file passes all 7 tests in 167 s, among them test_appendix_3_income_and_band and test_pound_for_pound, which read uc_deductions for Oxford's own award. The local_authorities YAML tree passes 429 cases, test_council_tax_reduction_applicant_properties.py 2 tests and code_health 3,150. The branch merges with main at af9361114 without conflicts. Could you take another look?

@MaxGhenis
MaxGhenis requested a review from juaristi22 November 4, 2026 14:35

@juaristi22 juaristi22 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.

Re-reviewed adopted head 2343a786174659e9e52a834af44808bdb4170e78. COMPLETE — C1 resolved; no open findings or material gaps.

The corrected property now compares the UC award before debt deductions on both sides, matching the unchanged production helpers. The changed property passed, including its added explicit debt example and existing generated examples. The explicit example reaches positive, uncapped readback assertions in all four councils: the corrected oracle misses by less than a penny, while the former subtraction would miss by about £1,274.69.

No formula, parameter or dependency changed. Unchanged passing cases and final-household evidence were retained; other property/council suites were not repeated. Approval awaits the remaining exact-head CI.

@juaristi22 juaristi22 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.

Approved current head 2343a786174659e9e52a834af44808bdb4170e78. COMPLETE — C1 remains resolved; no findings or material evidence gaps. Applicable current-head checks have passed.

The completed review of the adopted cross-council test correction is retained. Its fixed property passed with explicit and generated examples, including four positive CTR awards below their caps. The current passing result, prior production/final-result evidence and 11 original/source-extract pairs were integrity-checked. The earlier debt-subtraction oracle failure remains separately preserved as historical and resolved by the adopted correction.

No tests or calculations were repeated for this CI-only approval. The actual Axiom #513 record and the declared scope remain unchanged.

@juaristi22
juaristi22 added this pull request to the merge queue Nov 4, 2026
Merged via the queue into main with commit f17bc42 Nov 5, 2026
20 of 21 checks passed
@juaristi22
juaristi22 deleted the fix-2520-oxford-ctr-uc-income branch November 5, 2026 00:12
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.

Oxford Council Tax Reduction assesses Universal Credit claimants on legacy income, not Appendix 3

3 participants