Skip to content

Test that AFCS payments never confer severe disability; document AFCS vs AFIP (stacked on #1946) - #2003

Draft
MaxGhenis wants to merge 1 commit into
working-age-severe-disability-premiumfrom
afcs-severe-disability
Draft

MaxGhenis wants to merge 1 commit into
working-age-severe-disability-premiumfrom
afcs-severe-disability

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator

Stacked on #1946. Retarget to main once #1946 merges. This PR carries no formula change: it is tests and documentation only.

Summary

#1946 fixes is_severely_disabled_for_benefits paragraph 5. It reads armed_forces_independence_payment instead of any afcs payment, as Child Tax Credit Regulations 2002 reg 8(5) and Working Tax Credit Regulations 2002 reg 17(4) require. This PR adds what #1946 does not have, as listed in the review on this PR:

  • Documentation.
    • afcs_reported: what FRS benefit code 8 covers.
    • armed_forces_independence_payment: its legal basis, and that it is not part of afcs.
  • YAML cases, appended to Give the legacy severe disability premium its statutory conditions (stacked on #1896) #1946's is_severely_disabled_for_benefits.yaml. They check that AFCS payments confer nothing, alone or next to a lower award, through every amount that reads the flag.
  • Hypothesis properties for the AFCS rule across those amounts.

The first version of this PR made the formula change itself on main. #1896 has now merged and #1946 is next in the merge train, so the formula change is left to #1946. Making it here as well would knock #1946 off its tested head.

What afcs holds

afcs adds afcs_reported, which policyengine-uk-data builds from FRS benefit code 8:

  • The FRS 2024-25 data dictionary (UKDA study 9563) labels code 8 "Armed Forces Compensation Scheme".
  • The questionnaire (card H3) asks about the "Armed Forces Compensation Scheme (formerly War Disablement Pension), including Guaranteed Income Payments".
  • The code frame has no armed forces independence payment (AFIP) code.

AFIP is one of six injury benefits in the AFCS Order 2011 art 15(1): lump sum, supplementary award, guaranteed income payment, AFIP, fast payment and medical expenses. CTC reg 8(5) and WTC reg 17(4) name only AFIP. UC Regs 2013 reg 24(2)(b) names no armed forces payment.

Tests

Appended to tests/policy/baseline/finance/benefit/family/is_severely_disabled_for_benefits.yaml: 7 cases, computed by hand from the law.

  • DLA and PIP. An AFCS payment alongside DLA care at the middle rate, and alongside PIP daily living at the standard rate: not severe.
  • CTC. A child with an AFCS payment adds no severely disabled child element.
  • WTC. An AFCS payment adds no severe disability element. AFIP adds it: £1,705 in 2024-25 (WTC Regs Sch 2).
  • UC. A 17-year-old qualifying young person with an AFCS payment gets no higher disabled child addition. On the enhanced PIP daily living rate they get it: £495.87 × 12 = £5,950.44 in 2025-26.

The file passes in full on this head: #1946's 9 cases plus these 7.

New tests/test_severe_disability_afcs_properties.py. Each example is a population of 10 to 20 random families with random DLA care, PIP daily living and Attendance Allowance categories, AFCS payments and AFIP.

  1. Differential. The flag equals the tax credit condition recomputed from the inputs: CTC reg 8(3)-(5) plus WTC reg 17(2)'s higher-rate Attendance Allowance.
  2. Metamorphic. Setting every AFCS payment to zero, or to another random amount, changes neither the flag nor any amount that reads it: the UC higher disabled child addition, the CTC severely disabled child element, the WTC severe disability element and the severe disability premium.
  3. Monotone. Giving everyone AFIP turns the flag on and never off.

On this head, all 3 properties pass, and so do the code-health tests. Against the formula on main before #1946, all 3 fail. The populations are not vacuous: across the 10 examples (333 people), 33 people have an AFCS payment and nothing else, and the UC addition, CTC element, WTC element and premium are each positive for 64 to 111 people or benefit units.

Effect

There are no formula or parameter changes, so model output is unchanged.

For context on #1946's AFCS change, two real Microsimulation comparisons, 2024-25 to 2030-31, on private copies of the Enhanced FRS 2024-25 with weights unchanged:

  • Formula alone: no change in any year. The dataset stores is_severely_disabled_for_benefits, and build_from_multi_year_dataset sets every stored column as an input for every year, so the stored flag wins. Main 7b9fc379 against a branch with only the AFIP formula, on the same copy, gave every reported aggregate identical: benefits, premiums, net income and poverty.
  • Stored flag also corrected for code 8 only (one column changed; the rebuild matches the stored flag on all 113,403 records without a code 8 payment):
    • the flag drops by 130k people in 2025-26 (from 4.14m to 4.01m);
    • Housing Benefit falls by less than £0.1m in every year, and fewer than 10 survey records are affected, so there is no breakdown;
    • nothing else moves. No one under 20 reports a code 8 payment.

Not changed here

Axiom

axiom: n/a: tests and documentation only. The provision changes in #1946. For #1946's change, CTC Regs 2002 reg 8 and the WTC reg 17(2)-(6) qualifying benefits are queued as a dispatch-ready addendum on TheAxiomFoundation/rulespec-uk#361 (addendum to be posted after review). uk:regulations/uksi/2013/376/24 is already correct: higher_rate_disabled_child_addition_applies has no armed forces input.

🤖 Generated with Claude Code

@vahid-ahmadi

Copy link
Copy Markdown
Collaborator

Review pass (Claude Code, on Vahid's behalf), on closing this in favour of #1946.

#1946 already contains this PR's fix. At 9dd45148, is_severely_disabled_for_benefits reads armed_forces_independence_payment > 0 for paragraph 5 instead of afcs > 0, the same change as here at 296934cb. #1946 also adds Attendance Allowance at the higher rate, from WTC Regs 2002 reg 17(2).

What #1946 doesn't have yet, and should carry over before this closes:

  • tests/test_severe_disability_afcs_properties.py: the metamorphic property that changing any AFCS payment leaves the UC higher disabled child addition, the CTC severely disabled child element, the WTC severe disability element and the severe disability premium unchanged.
  • The YAML cases that pair an AFCS payment with DLA care at the middle rate or PIP daily living at the standard rate, and the UC higher disabled child addition cases.
  • The afcs_reported and armed_forces_independence_payment documentation and references: FRS benefit code 8 is AFCS plus war disablement pensions, and AFIP is not part of afcs.

Timing. #1946 is a draft stacked on #1896, so closing this delays the AFIP fix until both land. If #1896 isn't close to merging, I'd merge this first and rebase #1946 over it; otherwise consolidating is fine.

… vs AFIP

Stacked on #1946, which reads armed_forces_independence_payment (not afcs)
for CTC Regs 2002 reg 8(5) / WTC reg 17(4). This adds what #1946 lacks:

- afcs_reported documented as FRS benefit code 8 (AFCS including guaranteed
  income payments, and war disablement pensions);
  armed_forces_independence_payment documented with AFCS Order 2011 art 24A.
- YAML cases: AFCS with DLA care middle / PIP daily living standard; CTC
  severely disabled child element, WTC severe disability element (AFCS 0,
  AFIP 1,705 in 2024-25) and the UC higher disabled child addition (AFCS 0,
  PIP enhanced 5,950.44 in 2025-26).
- Hypothesis properties: differential against the tax credit condition
  (CTC reg 8(3)-(5) + WTC reg 17(2) higher-rate AA); AFCS invariance of the
  flag and of every amount that reads it; AFIP monotone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis force-pushed the afcs-severe-disability branch from 296934c to abef7e9 Compare October 2, 2026 13:52
@MaxGhenis MaxGhenis changed the title Count armed forces independence payment, not any AFCS payment, as a severe disability Test that AFCS payments never confer severe disability; document AFCS vs AFIP (stacked on #1946) Oct 2, 2026
@MaxGhenis
MaxGhenis changed the base branch from main to working-age-severe-disability-premium October 2, 2026 13:54
@MaxGhenis

Copy link
Copy Markdown
Collaborator Author

Agreed: consolidated rather than raced. #1896 has merged and #1946 is next in the train. I kept the formula change out of this PR so #1946 stays on its tested head.

This PR is now stacked on #1946 (abef7e9a, on #1946's 5ab03ee0). It carries only what you listed:

On this head the YAML file passes 16 of 16, the 3 properties pass, and the code-health tests pass. Against pre-#1946 main, all 3 properties fail. Once #1946 merges I'll retarget this to main.

🤖 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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants