feat: compute PIP daily-living and mobility amounts from flags#56
Merged
Conversation
This was referenced May 1, 2026
Until now, PIP amount fields (`pip_daily_living`, `pip_mobility`) were
only populated from FRS recorded values; setting an eligibility flag on
a synthetic household built via `from_situation` produced £0 PIP, and
PIP-rate reforms had no effect even on FRS data when the recorded amount
sat outside the modelled rate.
This change adds:
- `PipParams` Rust struct (and Python wrapper class) with the four PIP
weekly rates: daily-living standard/enhanced and mobility standard/enhanced
- 2025/26 rates per gov.uk/pip/what-youll-get sourced under Welfare
Reform Act 2012 s.79 / SI 2013/377
- `pip_daily_living_amount` and `pip_mobility_amount` helpers in
`src/variables/benefits.rs` that:
- Pass through any FRS-recorded amount unchanged (preserves existing
calibration behaviour)
- Otherwise compute from the eligibility flag × the rate parameter
- Return 0 when neither holds or `params.pip` is unset
- `passthrough_benefits` now uses these helpers, so PIP from flags flows
into total_benefits and downstream household net income
Tests:
- 8 Rust unit tests covering the std/enh/recorded-override/no-flag/no-
params/reform-scaling paths
- 4 YAML policy-test cases covering the same paths end-to-end
Stacked on #55 (LBTT/LTT).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7a9662c to
17324e5
Compare
710db92 to
5b4b4cb
Compare
vahid-ahmadi
added a commit
that referenced
this pull request
May 29, 2026
Extends the pattern from #56 (PIP) to: - DLA care component (low/mid/high) — SSCBA 1992 Sch.2 para.2 - DLA mobility component (low/high) — SSCBA 1992 Sch.2 para.3 - Attendance Allowance (low/high) — SSCBA 1992 s.64 Synthetic households that set `dla_care_*` / `dla_mob_*` / `aa_*` eligibility flags now produce non-zero amounts via the new `DlaParams` and `AaParams` structs (with 2025/26 weekly rates from gov.uk). FRS-recorded amounts continue to pass through unchanged. Adds: - 2025/26 rates in `parameters/2025_26.yaml`: DLA care low/mid/high £29.20/£73.90/£110.40 weekly, DLA mob low/high £29.20/£77.05 weekly, AA low/high £73.90/£110.40 weekly - Helpers `dla_care_amount`, `dla_mobility_amount`, `attendance_allowance_amount` in `src/variables/benefits.rs` - 10 Rust unit tests (recorded-override / no-flag / per-band-rate / passthrough flow) - 4 YAML policy-test cases under `tests/policy/dla_aa.yaml` - Python wrapper exposure (`DlaParams`, `AaParams`, `Parameters.dla`, `Parameters.aa`) Stacked on #56. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
Author
|
Rebased onto Previously stacked behind the LBTT/PIP chain; now sits directly on |
# Conflicts: # interfaces/python/policyengine_uk_compiled/models.py
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.
Summary
Addresses part of #44. PIP amount fields are now computed from the existing eligibility flags + a new
PipParamsparameter struct. Stacked on #55.Before: setting
pip_dl_enh: trueon a synthetic household produced £0 PIP becausepip_daily_livingwas only ever populated from FRS recorded amounts.After:
Reforms flow through too: doubling
daily_living_enhanced_weeklydoubles the synthetic household's PIP DL amount.What's included
Engine (
src/parameters/mod.rs,src/variables/benefits.rs):PipParamsstruct with the four 2025/26 weekly ratespip_daily_living_amount(p, params)andpip_mobility_amount(p, params)helpers:params.pip× 52passthrough_benefitsnow uses the helpers, so PIP from flags flows intototal_benefitsand downstream net incomeParameters (
parameters/2025_26.yaml): rates from 7 April 2025 per gov.uk/pip/what-youll-get under WRA 2012 s.79 / SI 2013/377:Python wrapper (
models.py,__init__.py): newPipParamsclass exposed underParameters.pip.Rust unit tests (8): enhanced/standard/recorded-override/no-flag/no-params and reform-scaling for both DL and mobility, plus a passthrough-flow test on a benunit.
YAML policy-test cases (4) in
tests/policy/pip.yaml: DL+mob combinations end-to-end through the binary, withwould_claim_*: falseon the benunit to isolate PIP from modelled means-tested benefits.Verified locally
cargo test: 149 passing (141 + 8 new)pytest interfaces/python/tests: 79 passingpython -m policyengine_uk_compiled.yaml_tests tests/policy: 21/21pip_dl_enh + pip_mob_stdproduces £7,259.20 passthrough benefit (= £5,740.80 + £1,518.40, matching the 2025/26 weekly rates exactly)Stacking
vahid/pip-from-flags←vahid/lbtt-ltt(#55) ←vahid/yaml-test-harness(#54) ←vahid/parity-harness(#53) ←vahid/from-situation(#52). Five-deep stack; once each merges in order, this rebases onto main.Out of scope (follow-ups for #44)
old_basic_pension_weeklybaseline-scaling pattern)src/data/clean.rs)Test plan
pip_dl_enh: trueon a synthetic household yields ~£5,741 baseline_total_benefits in addition to any modelled benefits🤖 Generated with Claude Code