Skip to content

Charge in-unit non-dependants in the local Council Tax Reduction schemes, and exclude a lodger personally only outside the head's family - #2077

Open
MaxGhenis wants to merge 211 commits into
in-unit-non-dep-deductionsfrom
local-ctr-in-unit-non-deps
Open

MaxGhenis wants to merge 211 commits into
in-unit-non-dep-deductionsfrom
local-ctr-in-unit-non-deps

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

Stacked on #2017 (in-unit-non-dep-deductions), which is stacked on #2007 (hb-ctr-non-dep-exemptions), for issue #2014. #2017 charges non-dependants inside the claimant's own benefit unit in UC, HB and the national CTR schemes, and kept the five English working-age local schemes on their old aggregation behind a mask. This PR brings those schemes (Merton, Kingston upon Thames, Newham, Westminster, Oxford) into line with the law and with #2017's national variable. It also narrows who the shared eligibility variable excludes personally, which touches the national schemes too.

Status (UK hub build sprint-2077b, 22 Oct)

The law

Each council's 2026-27 scheme reproduces the Default Scheme's (SI 2012/2886) definitions:

  • Merton, Kingston upon Thames and Newham: paras 4, 6 and 9 and the working-age deduction paragraph (30, 30A, 30B).
  • Westminster's summary says "The Council Tax Reduction Schemes (Default Scheme) Regulations 2012 form the basis of Westminster's local working age reduction scheme", and its Appendix A gives the 2026-27 scale. It publishes nothing else on non-dependants.
  • Oxford: paras 42-47 and the Annex 1 glossary.

What follows from the texts:

  • Who is a non-dependant (para 9). Anyone who normally resides with the applicant, except a member of the applicant's family (para 6), a person jointly and severally liable with the applicant (9(2)(d)), a person liable to pay the applicant on a commercial basis (9(2)(e)) and a charity-engaged carer. Para 9(3)(a) brings back as a non-dependant someone who pays "a close relative of his or his partner", or pays under an agreement "other than on a commercial basis". So an adult in the applicant's own benefit unit who is not the partner, a child or a qualifying young person is a non-dependant, and so is each adult in another family.
  • Banding (para 30(1)-(2), para 10). A non-dependant in remunerative work, on their own hours, is banded on their normal gross weekly income. For a couple the income is joint (para 30(4); Oxford para 44).
  • Couples (para 30(3)). "Only one deduction is to be made ... in respect of a couple ... (other than where there is an award of universal credit)", the higher. Merton and Kingston upon Thames reproduce the exception. Newham's 30B(3) and Oxford's para 44 have none. Westminster follows the Default Scheme, so it keeps the exception (see Readings).
  • Joint occupiers (para 30(5)). A non-dependant of two or more liable persons is apportioned equally between them.
  • Exemptions (para 30(8)). No deduction for a non-dependant "who is on income support, state pension credit, an income-based jobseeker's allowance or an income-related employment and support allowance". Merton's, Kingston upon Thames's and Newham's texts add one "entitled to an award of universal credit where the award is calculated on the basis that the person does not have any earned income", and Westminster's Appendix A has "In receipt of universal credit with no earned income: nil". Oxford applies its exemptions to pensioner applicants only (para 47).

Changes

_legacy.py:

council_tax_reduction_individual_non_dep_deduction_eligible (shared with the national schemes) is (other family | in-unit) & ~personally excluded. The personal exclusions are:

  • a joint tenant (is_liable_for_household_rent) who is not their benefit unit's claimant or partner;
  • anyone outside the household head's family who pays the householder for their own board or lodging (9(2)(e)), even where the rest of their family pays nothing.

A member of the head's own family who pays board is taken to be a close relative (9(3)(a)(i)) and stays a non-dependant. The model has no relationship input, so a close relative in another family who pays is still treated as a commercial lodger. That gap is documented in the variable and is #2559. The raw is_household_head read is gone.

westminster_council_tax_reduction_non_dep_deductions deducts for each member of a non-dependant couple with Universal Credit, as the Default Scheme's para 30(3) does.

Review responses

Sol review r1 (REQUEST_CHANGES at 663a5b7):

  1. UC exemption interpretation. Read on each person's own earnings, as Apply Housing Benefit and national Council Tax Reduction non-dependant deductions as legislated #2007 reads the same words for the national schemes and HB (Readings 1). One-earner couple cases pin it in Merton (each member deducted: the worker's £13.30, the partner nil) and Newham (one deduction: the worker's).
  2. Payment alone does not exclude. Fixed as above. Regression cases cover the England pensioner, Scottish, Welsh and Merton schemes: a son who pays his mother board stays her non-dependant. A further case covers a lodger's son who pays the householder himself, in Scotland. The relationship gap is Treat a close relative who pays board as a non-dependant (reg 9(3)(a)) once the model has a relationship input #2559.
  3. Integrate main. Done: Assess each Council Tax Reduction claim under its own family's scheme and exemption #2015's per-applicant exemption, Count only the claimant's and partner's legacy awards in means tests and passports #2027's payee predicates and Means-test the Council Tax Reduction applicant and partner, not the benefit unit's claimant #2078's applicant identity are all kept (resolutions below). The oracle's household exemption is now per applicant.
  4. Westminster UC couple. Westminster's summary names the Default Scheme as its basis and is silent on couples. The Default Scheme's para 30(3) keeps the UC exception, so Westminster now deducts for each member (Readings 2). A YAML case pins it: £15.95 + £5.20 a week.
  5. Conservation. The joint-liability share follows the regulations' per-person wording (main's documented reading), so shares need not sum to one: a couple jointly liable with a lone sharer leaves the partner's third unborne, for the liability and the deduction alike. The invariant is restated that way, and property 5 asserts it. In every household with no exempt applicant, the claiming families bear the pool times the sum of their shares, which is the whole pool, each non-dependant once, wherever the shares sum to one.
  6. Main-versus-head impact. Two certified-data runs (below).

Maintainer review (vahid-ahmadi, 5 Oct):

  1. Rebase: done (merges above).
  2. Count only the claimant's and partner's legacy awards in means tests and passports #2027: is_on_* for IS, JSA and ESA, and is_on_pension_credit for State Pension Credit, because para 30(8)(a) uses one "who is on" for all four (Readings 3). Count only the claimant's and partner's legacy awards in means tests and passports #2027's Merton case ("A non-dependant couple on ESA with a working partner pays the partner's deduction on their joint income") is on main and passes here.
  3. Grandmother cases: both the pool and eligibility now key on the CTR applicant.
  4. Eligibility keeps (other_family | in_unit) & ~personally_excluded, with Assess each Council Tax Reduction claim under its own family's scheme and exemption #2015's claimant-family test inside other_family.
  5. The changelog now names the national change. The survey household counts are gone from the body.
  6. Close relatives who pay board: handled where the data allow, otherwise documented, and the follow-up issue is Treat a close relative who pays board as a non-dependant (reg 9(3)(a)) once the model has a relationship input #2559.

Max's comment (6 Oct, resolved head): no formula here reads is_household_head.

Readings (d1398, parked)

Under Max's 20 Oct delegation (single readings are the session's call, logged in source-conflicts/RULINGS.md; rows handed to the hub to append):

  1. UC exemption, own earnings. "The person does not have any earned income" is tested on the person's own earnings. Both joint claimants are entitled to the award. This is Apply Housing Benefit and national Council Tax Reduction non-dependant deductions as legislated #2007's reading for the national schemes and HB, so one meaning holds across schemes. It binds only for a non-dependant UC couple where exactly one member earns.
  2. Westminster, the Default Scheme's para 30(3) exception. The scheme's stated basis governs where its own published text is silent. Recheck if Westminster's full scheme text is obtained.
  3. "On" State Pension Credit means payable to them, as for the other three benefits in the same limb (Apply Housing Benefit and national Council Tax Reduction non-dependant deductions as legislated #2007 reads PC by payee too).
  4. Close-relative presumption for a board-payer in the household head's own benefit unit (data approximation, Treat a close relative who pays board as a non-dependant (reg 9(3)(a)) once the model has a relationship input #2559).

Invariants

For every input:

  1. Oracle (property 5). Each council's individual and family deductions equal an independent calculation from its 2026-27 scale and the generated structure. Every other council's variables are zero. Who claims and each claim's share are derived from the structure and asserted against the model. Who is on each award is read from the model.
  2. Conservation (property 5). Without an exempt applicant, a household's claiming families bear its pool times the sum of their shares. That is the whole pool, each non-dependant once, wherever the shares sum to one.
  3. Independence (property 6). The earnings of an adult who is not a claimant or partner change no one else's deduction.
  4. No self-charge. A claiming family is never charged for its own applicant, partner or children (Charge non-dependant deductions for non-dependants within the claimant's benefit unit #2017's eligibility property and the oracle's own-family subtraction).
  5. National properties 1-4 (Charge non-dependant deductions for non-dependants within the claimant's benefit unit #2017) still hold with the narrowed exclusions.

Tests

  • YAML, every file that touches CTR or non-dependants (64 files): 874 passed, 0 failed, at the final model code (policyengine-core test, single process). This includes local_scheme_non_dependants.yaml (25 cases, every expectation hand-computed from the scheme text). benefit_unit_non_dependants.yaml gains 5 cases, and the renamed Newham case replaces Charge non-dependant deductions for non-dependants within the claimant's benefit unit #2017's mask-pinning one.
  • The changes bind. Against a git archive export of the parent (Charge non-dependant deductions for non-dependants within the claimant's benefit unit #2017 at 3efa8bd60 merged with main, 7ba613fb9), 21 of this head's cases in the three PR YAML files fail, including all three reproducers. The national close-relative cases pass there too. They guard against the previous head's wholesale lodger exclusion.
  • Property tests (-n 4): the four core files, test_benefit_unit_non_dependant_properties.py (including local properties 5-6), test_household_head_agreement_properties.py, test_non_dependant_deduction_properties.py and test_council_tax_reduction_claimant_family_scheme_properties.py: 17 passed. A second batch of eight CTR property files (applicant, claimant, legacy award readers, sharers/boarders/lodgers, young person, Child Benefit, UC non-dependant Pension Credit, prescribed benefits): 45 passed. That makes 62 of 62.
  • Lint: uvx ruff@latest (0.17.1, CI's unpinned version): format --check ., check . and check --select F811,F821 policyengine_uk are all clean.

Impact

Two workflow_dispatch runs of the Aggregate impact workflow, on the certified enhanced_frs_2024_25.h5 (policyengine-uk-data 1.58.1, sha256 056e80fd8e91, verified on both sides), fiscal years 2025-26 to 2031-32, at head aaf01f968. The later commits change only tests and a code comment.

1. This PR's own change (run 39732669012). The base is #2017 at 3efa8bd60 merged with main at 9d81a5dfa (7ba613fb9, pushed as wip/sprint-2077b-impact-base for the run):

  • no household's net income changes in any year;
  • 0 checks broken and no moves flagged; the one check failing on both sides is main's sign:vat.

So on survey data the local-scheme, Westminster and eligibility changes move no aggregate. They change household calculations in the five councils, and for board-payers outside the head's family and joint tenants entered as inputs.

2. The whole stack (#2007 + #2017 + this) against main at 9d81a5dfa (run 39732671972). 0 checks broken. All of this comes from #2007 and #2017; run 1 shows this PR adds nothing.

Measure 2025-26 2026-27 2027-28 2028-29 2029-30 2030-31 2031-32
Universal Credit +£57.5m +£59.9m +£59.0m +£60.4m +£61.9m +£63.4m +£65.0m
Housing Benefit +£17.3m +£18.0m +£18.5m +£19.0m +£19.5m +£20.0m +£20.4m
Council Tax Reduction +£6.3m +£6.8m +£7.2m +£7.7m +£9.1m +£9.6m +£10.2m
Government spending +£81.1m +£84.7m +£84.6m +£87.1m +£90.5m +£93.0m +£95.7m
Absolute poverty AHC, everyone -7.2k -11.7k -11.5k -11.6k -5.3k -5.4k -5.5k

The run flags 11 moves: decile means of up to ±£260 (2028-29 to 2031-32), and child relative poverty of +0.16pp (+24.2k AHC in 2029-30 and +23.9k BHC in 2031-32). They come from the base PRs (run 1 flags none). Each relative-poverty flag is a single-year jump between years of small falls. #2007's report explains its own 2027-28 flag by the line comparison.

Axiom

axiom: TheAxiomFoundation/rulespec-uk#426 queued. The Kingston upon Thames, Merton and Newham modules derive each non-dependant's deduction from their own income and hours, which is encoded-correct given its inputs. They take who is a non-dependant, the exemption and the household total as inputs. Westminster defers Appendix A, and Oxford has no module.

Coordination

Reproducer: policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/local_scheme_non_dependants.yaml::Merton charges the applicant's own non-dependant son for his own earnings
Reproducer: policyengine_uk/tests/policy/baseline/gov/local_authorities/council_tax_reduction/local_scheme_non_dependants.yaml::Westminster deducts for each member of a Universal Credit couple, as the Default Scheme does
Reproducer: policyengine_uk/tests/policy/baseline/finance/benefit/family/benefit_unit_non_dependants.yaml::CTR (Scotland), a lodger's adult son who pays the householder himself is not a non-dependant

🤖 Generated with Claude Code

MaxGhenis and others added 4 commits October 2, 2026 09:32
The five English working-age local schemes (Merton, Kingston upon Thames,
Newham, Westminster, Oxford) reproduce the Default Scheme's para 9: an adult
in the applicant's benefit unit who is not the claimant, partner, child or
young person is a non-dependant. local_non_dep_deductions now charges the
claiming family the household pool (claims x pool x share, as the national
variable), counting the higher of each non-dependant couple (each member in
Merton and Kingston where the couple has UC) and every other adult
separately. normal_gross_income_non_dep_deduction bands a claimant/partner
on the couple's joint income and anyone else on their own, uses each
person's own hours, and gates the IS/JSA/ESA/PC/UC exemptions to the
award's claimant and partner.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
20 pounds a week for a lone parent (para 1), a carer satisfying Sch I para 4
(para 3), or a claimant or partner on a listed disability benefit or
certified blind (para 4(1)); otherwise 5 pounds single and 10 pounds couple
(para 5); at most 20 pounds (para 4A), never more than the earnings.

Refs #1954.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ncil's scale

Hypothesis properties 6 and 7: each council's individual and family
deductions equal an independent calculation from its 2026-27 scale, and an
adult who is not a claimant or partner changes no one else's deduction
through their earnings (both fail on the previous aggregation). A Merton case
for a 19-year-old who has left education, and #2017's Newham case now
apportions the head's own son between the jointly liable families (para
30(5)).

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

Reg 17(9) disregards the Sch VI sums in calculating the claimant's earnings,
which are net of income tax and NI (reg 17(10)) and of half of pension
contributions (reg 17A(4A)). Capping at gross earnings let a taxpayer's
first pounds of earnings raise Pension Credit. Income tax on earnings is the
lesser of the person's income tax and the basic rate on their earnings.

Also: the carer condition reads the claimant's or partner's
is_carer_for_benefits (Sch I para 4), not the carer addition, which counts
dependants; is_claimant_or_partner after #1896; property tests compute net
earnings independently, include dependants' DLA and caring, and add that
earning more never raises Pension Credit; parameter description and test
comment fixes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 3 commits October 3, 2026 07:34
…amily

Review r1 of #2077: an in-unit adult who personally pays the householder as a
boarder or lodger, or is personally liable for the rent, was still a
non-dependant, and a household head whom the inference left outside his
benefit unit's couple was charged as his own non-dependant. The household
head (the person liable for the council tax), anyone liable for the
household's rent and anyone paying rent as a boarder or lodger is now nobody's
non-dependant, in the national and local schemes alike. Property 6's oracle
now derives who claims and each claim's share from the generated structure
and checks the model's against them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ment (review of #2019)

- Income tax on earnings is now the tax on them as the top slice of taxable
  non-savings income on the person's own Scottish or rest-of-UK schedule,
  capped at their income tax. The 20% cap let earnings crossing Scottish
  bands raise Pension Credit (reviewer's couple: +2.89).
- The para 3 carer condition reads is_entitled_to_carer_benefit, the carer
  addition's own Sch I para 4 test; caring hours alone no longer qualify
  (reviewer's case overpaid 780 a year).
- Tests: Scottish couple pair (income flat with and without earnings),
  hours-only vs entitled carer cases; the property test adds Scottish
  households, carer entitlement, care hours and pension contributions, and
  measures tax on earnings independently by rerunning without them.

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

@vahid-ahmadi vahid-ahmadi 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.

Thanks Max. The rules applied match each scheme:

  • Who is a non-dependant: charging in-unit adults follows para 9 ("any person ... who normally resides with an applicant", except "any member of the applicant's family").
  • Couples: one deduction, the higher, on joint income follows para 30(3)-(4).
  • Joint liability: the apportionment follows para 30(5).
  • Merton and Kingston: the per-member UC deduction matches the Default Scheme's own "(other than where there is an award of universal credit)".

Verified at 663a5b7:

  • Tests: the local_authorities YAML passes 67/67, benefit_unit_non_dependants 28/28 and properties 6/6.
  • Probe for Newham, 2026:
    • The household: a grandmother aged 55 applies alone. A 19-year-old couple live with her as another family; the father earns £30,000 and works 37.5 hours.
    • The deduction is £1,175.72 (£22.61 × 52 on joint income of £576.92 a week). The mother's own deduction, £392.08, is the lower, so it is not taken.
    • CTR is £84.28.
  1. Blocking: needs a rebase. #2017 conflicts with main in 6 files, and this PR adds a seventh, _legacy.py (from #2009, merged 4 Oct). This is the same standard as #2015 and #2078. #2030 is also stacked on #2017.
  2. Should fix: #2027 is missing from Coordination, and the conflict at _legacy.py:175-179 changes amounts.
    • The case: Merton, a non-dependant couple. One reports £5,000 of income-related ESA; the other works 20 hours on £15,000.
    • Here: no deduction, CTR £1,800.
    • With #2027's is_on_*: £551.20 deducted, CTR £1,248.80.
    • Default Scheme para 2(4) ("payable to him") with para 30(3) supports #2027.
    • Take #2027's is_on_* there, keep your claimant-or-partner gate on the Pension Credit (:179) and UC limbs, and add the case.
  3. Should fix: this does not fix the #2078 grandmother cases.
    • Both own_family_member (_legacy.py:114) and in_unit (council_tax_reduction_individual_non_dep_deduction_eligible.py:40) key on is_claimant_or_partner.
    • So when the head applies alone and the inference makes the 19-year-olds the unit's couple, they count as neither her family nor her non-dependants.
    • Put my probe household in one benefit unit and this PR gives a £0 deduction. Under paras 6 and 9 it should be £1,175.72, giving CTR of £84.28.
    • Whichever PR lands second should key both on is_council_tax_reduction_applicant_or_partner from #2015/#2078.
    • #2078's Newham and Kingston grandmother cases also need explicit inputs:
      • set the young father's weekly_hours, so the hours band applies;
      • set current_education for the 19-year-olds, who otherwise default to tertiary education and fall under the full-time student exemption (para 30(7)(c)).
      • Without these, those cases give a £0 deduction whatever the non-dependant logic does.
  4. Should fix: the agreed #2015 resolution covers _legacy.py but not the eligibility file.
    • #2015 rewrites that test as ~claimant_benunit & ~benunit_is_rent_liable, which drops in_unit.
    • Keep (other_family | in_unit) & ~personally_excluded, and put #2015's claimant-benefit-unit test inside other_family.
  5. Should fix: the review-1 fix changes council_tax_reduction_individual_non_dep_deduction_eligible, which the national schemes share. That is the body's −£3.4bn on the intermediate.
    • Say so in the title and changelog: changelog.d/2014-local.fixed.md mentions only the local schemes.
    • Also remove the survey household counts ("135 survey households", "134", "54").
  6. Nit: close relatives who pay board are non-dependants.
    • Para 9(3)(a)(i) makes someone who pays a close relative a non-dependant again: "that person is a close relative of his or his partner".
    • council_tax_reduction_individual_non_dep_deduction_eligible.py:47-51 excludes every boarder and lodger, for example an adult son paying his mother board. Main does the same through in_other_non_liable_family.
    • There is no relationship input, so document the gap in the variable and open a follow-up issue.

@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

#2062 is now on main (merge commit c4659aa). main has one resolved household head: is_resolved_household_head (Person: the eldest member the is_household_head input flags, else the eldest member) and benunit_contains_household_head (BenUnit, defined from it). No formula outside is_resolved_household_head reads is_household_head, and test_only_the_resolved_head_reads_the_flag in policyengine_uk/tests/test_household_head_agreement_properties.py enforces that.

This PR still adds formulas that read the raw flag:

  • policyengine_uk/variables/gov/local_authorities/council_tax_reduction/council_tax_reduction_individual_non_dep_deduction_eligible.py: person("is_household_head", period)

Each needs to read the resolved head instead:

  • family level: benunit.any(person("is_household_head", period)) becomes benunit("benunit_contains_household_head", period), and person.benunit.any(person("is_household_head", period)) becomes person.benunit("benunit_contains_household_head", period);
  • person level, only where the formula needs the head as a person: person("is_household_head", period) becomes person("is_resolved_household_head", period).

test_only_the_resolved_head_reads_the_flag fails until every such read is moved. Please also add each variable you move to OUTPUTS in that test file, so its metamorphic test (flags matter only through the resolved head) computes it. Test inputs that set is_household_head are fine as they are.

vahid-ahmadi and others added 5 commits October 7, 2026 10:32
Add council_tax_band_d_amount (LA Band D amount, from a new LA-keyed
parameter following the domestic_rates/rates.yaml precedent) and
simulated_council_tax (Band D amount x statutory band ratio).

Band ratios are added per country: England and Wales use the section 5
proportions 6:7:8:9:11:13:15:18 relative to Band D = 9, Wales adding
band I at 21/9 from April 2005; Scotland uses the raised E-H
multipliers (473/360, 585/360, 705/360, 882/360) from April 2017.

The existing council_tax input variable is left untouched so the two
can be compared. council_tax_band_d_amount also fills a dangling
reference from policyengine-uk-data's la_council_tax target source.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…levels

Review follow-up on the four data-coverage items.

Enum coverage: add the six April 2023 unitary authorities (Cumberland,
North Northamptonshire, North Yorkshire, Somerset, West Northamptonshire,
Westmorland and Furness) to LocalAuthority. All 350 Band D rows now load,
up from 344.

Vintages: carry fiscal 2025 and 2026 for England, Wales and Scotland.
England comes from MHCLG Table 10 line 17 in both the 2026-27 and the
revised 2025-26 releases; the 2025-26 release's current-year column
reproduces the 2026-27 release's previous-year column, and every England
and Wales 2026 value reproduces the figures already in the file. Wales
comes from the Welsh Government council tax levels data tables, Table 1
"Overall average band D". Scotland comes from the Scottish Government
Band D council tax 1996-97 to 2026-27 dataset, whose 2025-26 column
reproduces the Scottish values already in the file.

References: cite the specific workbooks rather than the statistics
collection page, and state the basis. For England and Wales this is the
area figure, so it includes the county, police, fire, combined authority
and parish or community council precepts; for Scotland it excludes the
separately billed water and waste water charges. The variable
documentation and the stale "six authorities absent from the enum"
comment are corrected to match.

Scotland ratios: SSI 2016/368 (not 2016/123, which is the capital finance
regulations and was cited in error) substitutes 240:280:320:360:473:585:
705:882 into section 74(1) for financial years from 1 April 2017. Bands A
to D are unchanged from the original 6:7:8:9 proportion, so they are dated
from 1993-04-01; bands E to H keep the 2017 step and gain their original
11/9, 13/9, 15/9 and 18/9 values from 1993-04-01, so no band is undefined
before 2017.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…land, an abolished district and the missing-authority default; document the authority context

Main already added the six unitaries (52f4281), so composing this branch with
it defined CUMBERLAND and WEST_NORTHAMPTONSHIRE twice and the package failed to
import (TypeError: 'CUMBERLAND' already defined). Every Band D row still resolves
to an enum member (350 of 350).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Encode the Schedule 1 Part 2/3 points thresholds as parameters and add
`pip_dl_points` / `pip_m_points` person-level inputs. The existing
`pip_dl_category` and `pip_m_category` enums now have formulas that derive
the award category from points; data-set-supplied categories continue to
win because OpenFisca treats inputs as authoritative over formulas.

This is the first slice toward the full points system. Per-activity
descriptor inputs and an FRS imputation step are intentionally left for
follow-up PRs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Cross-reference from #2027 (a maintainer review there, 5 October, raised this household).

#2027 (head 360aef868) changes _legacy.py's non-dependant exemption for Income Support, income-based JSA and income-related ESA from the benefit unit's totals to is_on_income_support / is_on_income_based_jsa / is_on_income_related_esa. A person is on the award when it is payable to them (Default Scheme Sch para 2(3)-(4)); of a couple, only the payee is.

The household: Merton, a non-dependant couple. One reports £5,000 of income-related ESA; the other works 20 hours on £15,000.

The resolution the reviewer proposed: when this PR merges main after #2027, read is_on_* for the IS, JSA and ESA limbs, and keep this PR's claimant-or-partner gate on the Pension Credit and UC limbs. The conflict will be at _legacy.py around the income_based_benefit block.

vahid-ahmadi and others added 4 commits October 9, 2026 18:02
…(review: typed fragment)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The part of a reported State Pension above the type's full rate (additional
pension for the basic State Pension, protected payments for the new) was
uprated by the full rate's own triple-lock rise. Each Up-rating Order raises
it by September CPI instead (SSAA 1992 ss.150(1)(c), 151 and 151A; SI
2026/148 arts 4(3) and 6(3)(b): 3.8% against 4.8% for the full rates; SI
2025/295: 1.7% against 4.1%). Uprate it by
gov.economic_assumptions.indices.september_cpi_uprating from the data year,
read from the simulation's own parameters, so a reform to the full rates or
the triple lock no longer moves it and a price scenario does.

Fixes #1941.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rms as a reform

CI found two test faults (run 38161065391): the differential against main's
formula compared the model's float32 arrays with a float64 reference at
rtol 1e-12, which fails for any reported amount float32 cannot hold exactly
(e.g. £169.00 a week, aged 98); and a Scenario cannot take the reform
dictionary's "2026-01-01.2100-12-31" period, so that case passes it as a
reform.

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

At 5% September CPI the triple lock also rose 5%, so the scenario test passed
on main. At 1%, below the triple lock's 2.5% floor, the add-on rises 1% and
the full rates at least 2.5%. The docs record the change in the model's State
Pension against DWP's forecast, from full runs on the certified dataset.

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

MaxGhenis commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator Author

Independent review (GPT-6.1 Sol, UK hub sweep, 2026-10-12): REQUEST_CHANGES at 663a5b733. Blockers 1 and 4 are local-scheme readings the texts leave open; they're queued for Max as d1398. This PR has no live owner session. The hub defers it until #2007 lands (same non-dependant code), then adopts it as a Subfleet build with Max's ruling.

VERDICT: REQUEST_CHANGES
Head reviewed: 663a5b7

  1. [blocker] Resolve the UC exemption interpretation. _legacy.py:184 uses the couple’s combined earnings for both members’ exemptions. Merton paragraph 30(8)(c) refers to the person’s earnings within an award-calculation condition. The PR body explicitly acknowledges the competing personal-income reading. Fix: obtain Max’s methodology decision, reconcile it with Apply Housing Benefit and national Council Tax Reduction non-dependant deductions as legislated #2007, and pin the chosen treatment with one-earner couple tests.

  2. [blocker] Payment alone does not exclude a non-dependant. council_tax_reduction_individual_non_dep_deduction_eligible.py:50 excludes everyone reporting boarder or lodger payments. However, Merton paragraph 9(3)(a) retains non-dependant status when the payment recipient is a close relative or the agreement is noncommercial. Fix: apply those exceptions explicitly, or obtain Max’s decision on the missing relationship information. Add regression coverage across the national and devolved schemes because this eligibility variable is shared.

  3. [blocker] Integrate current main’s overlapping corrections. The three-reference merge-tree reports conflicts in both changed production files against main 3f174d07ec03a9d05ca626939442442ddc23c87e. _legacy.py:169 still references the household exemption deleted by merged Assess each Council Tax Reduction claim under its own family's scheme and exemption #2015; its aggregation lacks main’s per-applicant exemption guard. It also retains couple-wide legacy-benefit receipt, while eligibility:48 newly reads the raw household-head flag. Fix: rebase while preserving main’s claimant-specific scheme/exemption, individual payee predicates, and resolved-head semantics. Update the oracle’s household exemption:608 accordingly.

  4. [blocker] Westminster’s UC couple rule lacks decisive support. The new oracle:473 assumes one deduction for a UC couple. Westminster’s published summary identifies the Default Scheme as its basis but does not specify this departure; Default Scheme paragraph 30(3) contains a UC exception. Fix: establish the operative Westminster provision and obtain Max’s decision before asserting that no exception applies.

  5. [should-fix] The oracle does not establish the claimed conservation. test_benefit_unit_non_dependant_properties.py:703 counts every liable person but assigns one share per benefit unit. A claimant couple plus a lone sharer produces shares [1/3, 1/3]: a £691.60 deduction becomes £461.07 across the claims. Fix: reconcile the partner treatment with each council’s provisions, including Oxford paragraphs 41 and 45, then add an explicit conservation assertion or qualify the PR’s invariant.

  6. [should-fix] Supply a main-versus-final-head impact run. For the changes at _legacy.py:84, the impact section reports real enhanced-FRS runs, but compares stacked parent 270412d with intermediate head 570f163, followed by a separate revision comparison. Fix: after integration, provide current-main versus final-head Microsimulation results, full SHAs, dataset identity/checksum, and reproducible commands and outputs.

Validation: 51 focused YAML cases passed serially after checking compressor usage below 30 GB. Python property tests could not collect because Hypothesis was unavailable; xdist was also unavailable. Ruff lint and formatting checks passed. No tests were weakened, skipped or xfailed by this PR, and no protected infrastructure files changed. Both requested gh reads failed to connect; the PR body and file list were retrieved through the browser.

MaxGhenis and others added 3 commits October 11, 2026 21:25
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep the September CPI uprating in additional_state_pension: main's
np.divide guard (00c07d6) was on the full-rate ratio this branch replaces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 10 commits October 21, 2026 22:50
…rectness

Correct participation periods, spillover groups and seeded draws
…unterfactual

Fix the inactive Universal Credit health-element counterfactual
…defects

Pin benefit cap exemption rules with regression tests and legal references (#1818)
Scope legacy-benefit closure to each award's owners
…meters

Store marginal National Insurance schedules as scales
…-followup

Expand Savings Credit gate regression coverage and metadata
…enses

Disregard allowable employment expenses in Universal Credit earnings
Apply the Carer Support Payment earnings limit
…lity

Compute gross council tax from LA Band D amounts and statutory band ratios
@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

UK hub takeover for the Budget fix sprint (Max, 21 Oct). The owner session local_300ba566 has been idle since mid-October. The hub woke it on 21 Oct at 23:58Z, and it did not start. To land this before the Budget model locks (the first pe-uk release cut by about 12:00Z Thu 22 Oct), the hub has taken it over as build 20261021-211255-sprint-2077, which merges main, re-tests, pushes as a fast-forward and marks it ready. The hub then reviews it and lands it through the merge queue.

If the owner session wakes, please don't push to this branch; comment here instead, so there's only one writer.

🤖 Generated with Claude Code

github-actions Bot and others added 10 commits October 22, 2026 01:18
Fix historical income-tax bands and Marriage Allowance eligibility
Apply minimum ages to computed carer and DLA mobility awards
…ain's per-applicant exemption

Resolutions in the PR's hand-off. The local schemes now take the shape of
#2017's national aggregator (deduction_per_family over the CTR applicant's
in-unit set), main's is_on_* payee tests for every para 30(8)(a) benefit,
and the person's own earnings for the Universal Credit limb.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…gs, and #2017's head-alone couple

Para 30(8)(c) of each local scheme exempts a non-dependant entitled to
Universal Credit "calculated on the basis that the person does not have any
earned income". The merge reads it on the person's own earnings, as #2007's
national schemes read the same words, so the non-earning member of a UC
couple is exempt: Merton's couple pays 691.60, not 962 (CTR 1,108.40), and
Newham's partner's own deduction is nil (the couple's one deduction, the
worker's, is unchanged).

Main's IIDB case for a grandmother who applies alone noted that the model
charged nothing for the couple in her benefit unit until #2017. With #2017
they are her non-dependants: one deduction, the lowest (5.20 a week), so
council_tax_benefit is 1,195.968.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… outside the head's family

Reg 9(2)(d)-(e) exclude the person, but reg 9(3)(a) keeps as a non-dependant
anyone who pays a close relative of the applicant or partner, or pays on a
non-commercial basis. The model has no relationship input, so a member of the
household head's own family who pays board is taken to be a close relative
and stays a non-dependant; anyone else who pays the householder is excluded
(Sol review r1 finding 2, maintainer point 6). The gap for a close relative
in another family is documented in the variable.

The household head and anyone liable for the rent are no longer excluded
wholesale: #2017's in-unit set is built on the CTR applicant, so an applicant
is never in it, and is_liable_for_household_rent marks the young couple of a
grandmother who applies alone as liable, which wrongly excluded them
(maintainer point 3). A joint tenant who is not their unit's claimant or
partner (an input) is still excluded. A student head whose family cannot
claim stays the co-tenant's non-dependant, as main's case has it. No raw
is_household_head read remains.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s the Default Scheme does

Westminster publishes only a summary of its working-age scheme, which states
that the Council Tax Reduction Schemes (Default Scheme) (England) Regulations
2012 form its basis, and the Appendix A scale. The Default Scheme's para 30(3)
makes one deduction for a couple "(other than where there is an award of
universal credit)", as Merton's and Kingston upon Thames's full texts do.
With no Westminster provision departing from it, the model follows the
Default Scheme (Sol review r1 finding 4, d1398 part 2, logged in RULINGS.md).

A YAML case pins it: a UC couple, one earning £30,000 at 37.5 hours and one
£2,600 at 10 hours, pays £15.95 + £5.20 a week (1,099.80 a year). The
property oracle's Westminster entry follows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 3 commits October 22, 2026 02:13
…e changelog

Sol review r1 finding 2 asked for regression coverage across the national
and devolved schemes, since the eligibility variable is shared. A son in his
mother's benefit unit who pays her board stays her non-dependant in
England's pensioner scheme (270.40), Scotland's (288.60), Wales's (348.40)
and Merton's (691.60 on his own earnings); a lodger's son who pays the
householder himself is excluded in Scotland. The relationship gap is #2559.

The changelog now says what changes in the national schemes too
(maintainer point 5): who is excluded for paying board or as a joint tenant.

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

Each case said it was provisional until #2017: the 19-year-old parents are
the grandmother's non-dependants, but the model charged none in her benefit
unit. They passed only because the couple defaulted to tertiary education,
so the full-time student exemption applied (maintainer review point 3). The
couple are now not in education, and the Newham father works 37.5 hours:

- England pensioner (JSA): the payee is exempt, the other pays the lowest
  amount, 270.40, so the reduction is 489.20, not 759.60.
- Newham (UC): one deduction, the father's 22.61 a week on £576.92
  (1,175.72); the mother has no earned income of her own, so is exempt.
  The reduction is 84.28, as the maintainer's probe gave.
- Kingston upon Thames (UC): both on UC with no earned income, so both are
  exempt; the reduction is unchanged at 1,627.32.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Para 2(3)-(4) define being on income-based JSA and income-related ESA as the
award being payable to the person, and para 2(1) a person on Income Support
as one in receipt of it; State Pension Credit has no definition, so the
model reads it the same way. Comment only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis MaxGhenis changed the title Charge in-unit non-dependants in the local Council Tax Reduction schemes Charge in-unit non-dependants in the local Council Tax Reduction schemes, and exclude a lodger personally only outside the head's family Oct 22, 2026
@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

UK hub build sprint-2077b: hand-off at cf0475ddb

The branch is a fast-forward of 663a5b733: same author, no force-push. The base is still #2017 (in-unit-non-dep-deductions), which sits on #2007.

Tests (local, locked venv):

  • YAML: all 64 files that touch CTR or non-dependants pass, 874 of 874, at the final model code. Against the parent (Charge non-dependant deductions for non-dependants within the claimant's benefit unit #2017 merged with main, 7ba613fb9), 21 of this head's cases fail, including all three reproducers.
  • Property tests (-n 4): 62 of 62 pass. That's the four core non-dependant files (17), with the ported local properties 5-6 and the new conservation assertion, plus eight further CTR property files (45).
  • uvx ruff@latest (0.17.1) format and check are clean. .github/check_fix_pr.py, run locally on the diff against main, passes with 23 changed tests.

Impact (Aggregate impact workflow, certified enhanced FRS, dispatched because this base gets no PR CI):

Open items:

🤖 Generated with Claude Code

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-recheck Re-triggers Fix evidence without changing the PR (UK hub, 2026-10-12)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants