Skip to content

Count per-person cash and stocks-and-shares ISA balances in the holder's benefit unit #2729

Open

Description

@juaristi22

#2712 adds person inputs cash_isa_balance and stocks_and_shares_isa_balance, and makes the household cash_isa and stocks_and_shares_isa their sums.

The means tests still read the household totals. The capital sources for UC, Housing Benefit, Pension Credit, Income Support, JSA and ESA pool those totals with the household's other financial capital, and allocate the pool between benefit units. So a lodger's or an adult child's cash ISA is shared with the main family's capital.

#1983 solved this for the Lifetime ISA. lifetime_isa_countable_capital sits in each programme's person_sources, which count the claimant's and partner's holdings in their own benefit unit.

What's needed:

  • Count cash_isa_balance through person_sources where person balances are given.
  • Do the same for stocks_and_shares_isa_balance. It sits inside share_like_capital and corporate_wealth, so it must not be counted twice.
  • Keep the household proxy for datasets that store only household totals, as all current Microcosm exports do.
  • Tests: a lodger's cash ISA stays out of the main benefit unit's capital, and household-only data gives today's results.

Raised in Pavel's review of #2712 (nice to have 10). It needs #2712 merged. For population runs it also needs the person balances from PolicyEngine/microcosm#1415.

Activity

  1. vahid-ahmadi commented on Oct 29, 2026

    @vahid-ahmadi
    Collaborator

    Checked against main at 2c7bf5a (after #2712, merged at 2c5e297). Code reading only; I ran nothing.

    1. The claims hold. cash_isa and stocks_and_shares_isa are household sums of the person balances (variables/household/wealth/cash_isa.py:19, stocks_and_shares_isa.py:21). All six programmes carry cash_isa and share_like_capital in sources (for example universal_credit/means_test/capital/sources.yaml:49-51, pension_credit/income/capital/sources.yaml:30-35), and only lifetime_isa_countable_capital in person_sources. The pool is shared by claimant and partner counts (uc_assessable_capital.py:43-69), so a lodger's cash ISA does reach the main family today.

    2. should: cash has the same double-count risk the issue names for stocks and shares. cash_isa keeps a stored column (cash_isa.py:9-12), so a dataset can hold both a household total and person balances. If cash_isa_balance goes into person_sources while cash_isa stays in sources, those balances count twice. Suggest the pool takes max(0, cash_isa - household sum of cash_isa_balance) and person_sources takes cash_isa_balance. Household-only data then gives today's result exactly, person-only data puts nothing in the pool, and there is no need to detect which kind of data you have.

    3. should: for stocks and shares, net the person sum out of share_like_capital, not corporate_wealth, because share_like_capital already chooses between corporate_wealth and the itemised sum (share_like_capital.py:55). One test where corporate_wealth exceeds the components and one with components only would pin both branches.

    4. should: add a test with a dependent child's ISA balance. Today the pool hands it to the adults. Through person_sources the claimant/partner mask (uc_assessable_capital.py:47-51) drops it, which fits UC: the capital condition is the claimant's (Welfare Reform Act 2012 s.5). I did not check the legacy benefits' rules on children's capital. Also say in cash_isa_balance's docs whether Junior ISAs are in it.

    🤖 Generated with Claude Code

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions