Conversation
… and exemption In a shared-rent household every family liable for the rent claims, but the pensioner scheme and the non-dependant exemption were picked once per household from the head's family. SI 2012/2885 reg 3 (and SI 2012/2886 Sch para 3, SI 2013/3029 reg 3, SSI 2021/249 reg 3, SSI 2012/319 reg 12) define "pensioner" per person and partner, and the exemption applies where "the applicant or his partner" is blind or gets a listed benefit (SI 2012/2885 Sch 1 para 8(6) and equivalents). - council_tax_reduction_pensioner (BenUnit) replaces the household flag; the name and entity match #1944 and #1966, which extend the same definition. - council_tax_reduction_applicant_has_non_dep_exemption (BenUnit) replaces the household exemption; the councils' schemes apply it per claim. - council_tax_reduction_scheme_supported is per family, so each family falls back to its reported reduction only where its own scheme is unmodelled. - Councils' person-level non-dependant deductions no longer depend on the head's family; each claimant's own scheme decides whether to use them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 1, 2026
MaxGhenis
added a commit
that referenced
this pull request
Oct 2, 2026
SI 2012/2885 Sch 1 para 8(6) exempts "an applicant's dwelling if the applicant or his partner is" blind or on one of the listed benefits. With jointly liable sharers each family is its own applicant, but the composed aggregator read the household-level exemption, which looks only at the oldest adult's family. A blind head therefore exempted a sighted sharer's claim, and a blind sharer exempted nothing. council_tax_reduction_applicant_has_non_dep_exemption is the benefit-unit exemption over is_claimant_or_partner, with the same name and formula as #2015's, which applies it to the local schemes. The national aggregator now uses it; the local schemes keep the household variable here. YAML: a blind head does not exempt a jointly liable sharer, a blind sharer is exempt while the head is not, and a blind sharer's own adult son costs no one a deduction. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With the scheme chosen per family, one household can hold a simulated claim and a family whose scheme is not simulated. Review r1 found that a family that cannot claim then kept its reported reduction beside a head whose simulated award already covered the whole bill: £3,000 against £1,800. - A family that cannot claim keeps a reported reduction only where no claim in its household is simulated (new household flag council_tax_reduction_household_has_simulated_claim). Without sharers this is the base behaviour. - A jointly liable claimant's reported reduction is limited to its own share of the council tax (SI 2012/2885 Sch 1 para 7(3)-(4)), the most any scheme could give it. Tests: three YAML cases; the property tests now generate reported reductions, check the fallback and the household bound, and toggle one claimant's exempting benefit to show it leaves the other claim unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#2009 now names the liable people directly. A household head can be liable without being the claimant or partner of their family (a grandparent heading a family formed around a young couple), so "the applicant or his partner" (SI 2012/2885 reg 3, Sch 1 para 8(6)) is not always the family's claimant and partner. New person-level council_tax_reduction_applicant_or_partner: the liable member, and the other member of the couple where the liable member is the claimant or partner, whatever the partner's age; in a family that cannot claim, its claimant and partner. The pensioner flag and the applicant exemption read it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#2078 (also stacked on #2009) adds is_council_tax_reduction_applicant_or_partner and council_tax_reduction_head_applies_alone for the CTR means test. They define the same people as this PR's council_tax_reduction_applicant_or_partner: the claimant and partner where the liable person is one of them, the liable head alone otherwise, and the claimant and partner in a family that cannot claim. Take #2078's two files byte for byte, so whichever PR lands second merges without conflict, and point the pensioner flag and the applicant exemption at it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
Author
|
Coordination note from #2062 (issue #2059), also stacked on #2009. This PR's Whichever of the two PRs lands second renames those reads to |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #2009 (
ctr-claimant-household-head, at4b84ea069), which is stacked on #2006 and #1896. Merge after #2009; this PR retargets tomainthen.The bug
Since #2006 and #2009, a household whose rent is shared has several Council Tax Reduction claimants: the household head's family, and each family liable for a share of the rent. Each claims on its own share of the council tax. Two things were still decided once per household, from the head's family:
council_tax_reduction_household_has_pensioner("any member of the head's family is State Pension age") chose between England's pensioner scheme and the council's working-age scheme.simulated_council_tax_reduction_benunit, in Merton, Kingston upon Thames, Newham, Westminster and Oxford, and incouncil_tax_reduction_scheme_supported.council_tax_reduction_household_has_non_dep_exemptionexempted every claimant from non-dependant deductions in the councils' schemes when the head or the head's partner was blind or had a qualifying disability benefit. It ignored a sharer's own disability.Reproduction:
claimant_family_scheme.yaml. Each case is 2026, with two jointly liable families each claiming half of £1,800, no UC and no capital.Wales and Scotland each have one scheme in the model on this base, and each family's applicable amount was already its own, so those cases do not change.
The law
Read on legislation.gov.uk on 2026-10-01 (revised text):
"Pensioner" is per person and partner.
Jointly liable people apply separately. Two or more residents can be jointly and severally liable (LGFA 1992 s.6(3), s.75(3)). Each is then in a class in their own right, defined by their own pensioner status (SI 2012/2885 reg 11 and Sch 1 para 1; SI 2013/3029 regs 22-25).
The non-dependant exemption is the applicant's. "No deduction is to be made in respect of any non-dependants occupying an applicant's dwelling if the applicant or his partner is" blind, or receives in respect of himself Attendance Allowance, the DLA care component, the PIP daily living component, AFIP, or the Scottish and ADP equivalents:
It does not exempt another applicant in the same dwelling.
Changes
is_council_tax_reduction_applicant_or_partner(Person) andcouncil_tax_reduction_head_applies_alone(BenUnit), taken byte for byte from Means-test the Council Tax Reduction applicant and partner, not the benefit unit's claimant #2078, which is also stacked on Give Council Tax Reduction to the household head's family, not the oldest adult's #2009 and needs the same people for the means test. They identify the people whose circumstances set a claim's scheme and exemption.council_tax_reduction_liable_person) is its claimant or partner, these are the claimant and partner, whatever their ages.council_tax_reduction_pensioner(new, BenUnit) replacescouncil_tax_reduction_household_has_pensioner: the applicant or partner has reached State Pension age.council_tax_reduction_applicant_has_non_dep_exemption(new, BenUnit) replacescouncil_tax_reduction_household_has_non_dep_exemption. The conditions are unchanged; it reads the applicant and partner.simulated_council_tax_reduction_benunit), the four_legacycouncils and Oxford take each claim's own pensioner flag.council_tax_reduction_scheme_supportedis now BenUnit.council_tax_benefitreconciles simulated and reported reductions within a household. Now that schemes are per family, one household can hold a simulated claim beside a family whose scheme is not simulated.council_tax_reduction_household_has_simulated_claim; one bill needs a household-level reconciliation. In households without sharers this is exactly the base behaviour.*_council_tax_reduction_individual_non_dep_deduction) depend only on the non-dependant's own family and the council area. A pension-age head's family no longer zeroes them.local_non_dep_deductionsapplies each applicant's own exemption.normal_gross_income_non_dep_deductionno longer takes the claimant's exemption.config.pygainsis_*_area(local_authority, country)for each modelled council;is_*_working_ageis built on it.National schemes and the exemption
On this base, the national schemes (England pensioners, Wales, Scotland) apply no applicant exemption at all; only the councils' schemes do. #2007 adds it to the national schemes, reading
council_tax_reduction_household_has_non_dep_exemption. It also readscouncil_tax_reduction_household_has_pensionerin three places:council_tax_reduction_individual_non_dep_deduction, to pick England's national scale;council_tax_reduction_non_dep_deduction_exempt, to pick England's UC limb;council_tax_reduction_non_dep_deductions, for when Wales deducts both members of a non-dependant couple on UC (WSI 2013/3029 Sch 6 para 5(3)).Whichever of #2007 and this stack lands second should:
council_tax_reduction_applicant_has_non_dep_exemptionforapplicant_exempt.each_member_deductedis evaluated on the non-dependant family, so the family flag cannot simply replace it there.council_tax_reduction_pensioneris false, and the first otherwise. (Apply Housing Benefit and national Council Tax Reduction non-dependant deductions as legislated #2007's author pointed this out.)council_tax_reduction_individual_non_dep_deductionandcouncil_tax_reduction_non_dep_deduction_exempt), select England's pensioner parameters by country only, as this PR does for the councils. Each claim's own scheme already decides whether its award uses them. Apply Housing Benefit and national Council Tax Reduction non-dependant deductions as legislated #2007's two tests that pin "no national deduction in English working-age households" should instead check that the working-age award is unaffected.The national exemption is not added here, so the two PRs do not both claim that change.
Invariants (property-tested)
policyengine_uk/tests/test_council_tax_reduction_claimant_family_scheme_properties.pyuses Hypothesis.council_tax_benefit(reported reductions included) stay unchanged.council_tax_benefitis exactly the rule above, for every family.council_tax_benefitunchanged.On the base (
4b84ea069), run without the new flags, properties 4 and 7 both fail. In property 4, a claiming family's council award moved when the other families changed. In property 7, one claimant's exempting benefit changed the other claim's deductions, and a claimant's own benefit did not remove its own. The hand-minimized forms are the Oxford, Merton and Newham YAML cases.Tests
YAML.
claimant_family_scheme.yamlhas 16 cases:On the base (
4b84ea069), with the branch-only variables removed from the expected outputs, the 7 Oxford, Merton, Maidstone and Newham scheme and exemption cases fail. The other 9 pass, as they should:Updated.
claimant_household_head.yaml(2 cases) andlegacy_claimant_non_dep_exemption.yaml(4 cases) read the per-family flags.Run locally on the head:
9efdea22d);7ac22effc; after the switch to Means-test the Council Tax Reduction applicant and partner, not the benefit unit's claimant #2078's identical variable in9efdea22d, property 1 passed again);ruff formatandruff checkare clean.The full suites ran clean on the first version (
ae3e5e0ea): YAML 1,523 passed, pytest 2,047 passed and 45 skipped. On this head they run in CI.CI. CI does not run on PRs whose base is not
main, so the "Code changes" workflow is dispatched on this branch: run 37019227983 on9efdea22d(running).Enhanced FRS impact
These are real
Microsimulationruns of base4b84ea069(#2009's head) against branch7ac22effcon the same dataset, six runs in all.9efdea22donly replaces the applicant variable with #2078's identical one.e433e532…), 2026-27efrs_payer.h5,ed1a29912656…), 2025-26 and 2026-27What the runs show:
claims_all_entitled_benefitsis false there, as Give Council Tax Reduction to the household head's family, not the oldest adult's #2009 showed).The first version of this PR measured −£4.8m on the payer build. The review traced all of it to the per-family fallback for families that cannot claim. That version kept their reported CTR beside a simulated claim that already covered the bill, and dropped it where the base kept it. The reconciliation above removes both effects.
Not caused by this PR. On the base, about 516k households (215 survey households) in the payer build already receive more CTR than their modelled council tax, because their reported CTR exceeds the dataset's council tax. None of them has a simulated claim; this PR leaves them as they are. A follow-up task has been queued to find the cause.
Review
Subfleet review r1 of
ae3e5e0eareturned REQUEST_CHANGES:council_tax_benefit, with the three YAML cases and properties 5-6.council_tax_reduction_non_dep_deduction_exempt. Added above.The legal reading (scheme and exemption per applicant and partner) was confirmed. Review r2 of this head is running; its verdict will be added here.
Coordination with other open PRs
council_tax_reduction_pensioner(BenUnit) with the full reg 3 test.is_council_tax_reduction_applicant_or_partnermembers.council_tax_reduction_household_has_pensioner.pyby deleting the file.council_tax_reduction_devolved_working_agealready reads the per-family flag. Itssimulated_council_tax_reduction_benunitline for England should readbenunit("council_tax_reduction_pensioner", period), as here.council_tax_reduction_household_has_pensionertohas_attained_state_pension_credit_qualifying_age. Move that intocouncil_tax_reduction_pensioner.council_tax_reduction_non_dep_deductionsas claims × share × household pool. To compose, multiply by the claim's own~council_tax_reduction_applicant_has_non_dep_exemption, and choose Wales's pool per claim as above.local_non_dep_deductionsto claims × pool × share, and changes the per-person helper's income and hours. Its author has built and tested the composition with this PR's head:origin/local-ctr-in-unit-non-deps-on-2015at 20bbf36. There the local-authority YAML (126) and Charge in-unit non-dependants in the local Council Tax Reduction schemes #2077's local properties pass, and this PR's properties passed on the composition of the previous head. Whichever lands second can take that branch's_legacy.py,council_tax_reduction_individual_non_dep_deduction_eligible.pyand property-oracle hunk verbatim. To compose:where(applicant_exempt, 0, …));in_scheme_areaand its removal ofclaimant_exempt;applicant_or_partner.yamlcases that read the household flags atcouncil_tax_reduction_pensionerandcouncil_tax_reduction_applicant_has_non_dep_exemption.council_tax_reduction_household_head, which the shared applicant files read. Whichever lands second switches them tois_resolved_household_head, in both branches.legacy_claimant_non_dep_exemption.yamlonly through Replace generic child and adult flags with each programme's legal definitions #1896. There is no overlap beyond the renamed output.axiom: TheAxiomFoundation/rulespec-uk#410 queued
🤖 Generated with Claude Code