Repository navigation
Add a stratified UK sample and audit outputs for round 2 of the policyengine-uk audit - #215
Merged
Merged
Conversation
…yengine-uk audit Round 1 of the internal UK audit drew 100 unstratified households from the public transfer dataset, so pensioners, carers, childcare, Scotland and council tax were barely exercised. This adds what round 2 needs: - policybench/uk_audit.py: a seeded, stratified 200-household sample (12 strata) that selects transfer-data households by structure and states the facts the data lacks (State Pension, Attendance Allowance, caring hours, childcare costs, social tenancies, a council and its Council Tax liability), each from a documented distribution. - policybench/uk_audit_councils.csv: 47 councils with their 2026-27 Band D and the page each figure was read from, and the rental area a private renter there is placed in. - A uk_audit output spec: the seven UK headline outputs plus the High Income Child Benefit Charge, Carer's Allowance, Attendance Allowance, Housing Benefit, Council Tax Reduction, Tax-Free Childcare and Scottish Child Payment. The UK headline set is unchanged. - Prompts state the new facts in words; State Pension becomes promptable. - `policybench uk-audit-sample` and `policybench run --program-set`. - policyengine-uk 2.125.1 -> 2.126.7 (US pins unchanged). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Pension Credit and Housing Benefit count corporate financial wealth and property other than the home as capital, so a household with little savings but large holdings was not low-income for the means tests the strata exist to exercise. The strata now require savings, corporate wealth and other property together under £16,000. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… in the CLI export-full-run kept only the headline outputs, so a uk_audit run lost its seven new outputs before flagging. It now takes --program-set (default headline, unchanged). The uk-audit-sample branch imported json inside main(), which made json local to the whole function and broke other commands. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A baby aged 0 could be given a date of birth after 6 April of the fiscal year, contradicting the prompt's whole-year facts (Child Benefit would start at the birth while the reference pays the year). Such dates move back a year. UK negative amounts print as -£6,756 rather than £-6,756. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ctations The transfer path states the State Pension PE-UK computes (state_pension), so it now skips state_pension_reported, which the audit sample states instead. Tests follow the new tenure wording and use a still-hidden input for the rejection case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
policyengine-uk takes age as the age on 6 October and rejects a date of birth that disagrees. The previous move (back a full year) made a baby aged 1. The date now moves back 182 days within 7 October to 5 April, and a test runs the moved baby through the engine. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The prompt says the children are the adults' dependents, but PE-UK reads is_parent as an input that defaults to false, and Tax-Free Childcare tests only parents' income and work. Four round 2 references paid Tax-Free Childcare to families whose parents fail those tests. to_pe_uk_situation now states is_parent for the adults whenever the household has children. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he sampler - export-full-run refuses to write a non-headline output set to the public app data unless --skip-app-data is given. - The sampler counts a missing capital value as nil, never draws from zero-weight candidates, and does not draw a State Pension for an adult whose computed one is already stated. - Note in draw_state_pension that the scheme follows the men's cut-off. - numpy>=1.25 for Generator.spawn; a council-band comment now matches the code. Regenerating with seed 20261011 reproduces all 200 frozen round 2 scenarios exactly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
marked this pull request as ready for review
October 11, 2026 21:52
Contributor
Author
|
Merged by the session that opened it (PolicyBench UK round 2), on the standing merge gates:
Round 2's nits that were left for round 3 (record |
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.
Round 2 of the internal policyengine-uk audit (round 1: #212). Nothing here is published; the UK board stays internal pending d1254. The record, with the per-cell audit and every policyengine-uk issue and fix, is in
~/reviews/policybench-uk-round2/README.md.What this adds
policybench/uk_audit.py: a seeded, stratified sample of 200 households (seed 20261011) drawn from the pinned public transfer dataset.policybench/uk_audit_councils.csv: 47 councils, each with its 2026-27 Band D and the source it was read from (a URL, or for Birmingham, Glasgow and Aberdeen the document title). Councils whose figure could not be read from an official page are left out.uk_auditoutput spec: the seven UK headline outputs, plus seven new ones:The UK headline set is unchanged.
Prompts and situations:
council_taxas the liability before Council Tax Reduction.is_parent), which Tax-Free Childcare reads. Without it, 4 Tax-Free Childcare references were wrong; they were rebuilt before the audit.CLI and export:
policybench uk-audit-sample;policybench run --program-set;policybench export-full-run --program-set.Without the flags, worker commands, workload fingerprints and exports are unchanged.
export-full-runrefuses to write a non-headline output set to the public app data unless--skip-app-datais given.Pin: policyengine-uk 2.125.1 → 2.126.7. That includes round 1's #2248, #2258 and #2259. 2.126.8 came out the same day, and all 2,800 round 2 references are identical on it. US pins are unchanged.
Changes to the headline UK board, and known limitations
Headline UK prompts change in wording only:
US prompts are unchanged.
PROMPT_CONTRACT_VERSIONis not bumped. It namespaces the response cache for every country, so a bump would invalidate the US cache for a UK-only wording change. The UK headline board is internal and has not been run since #212. The next UK headline run must start from a fresh run directory, because the version is also in the resume fingerprint.is_parentchanges no headline UK reference: 0 of 700 cells move when it is dropped (round 1's 100 households, headline outputs). In round 2 it moved 4 Tax-Free Childcare references, which were rebuilt before the audit.Known limitations of the round 2 sample (the references follow the stated facts, so the audit cells stay valid; the sampler should change in round 3):
is_child_or_QYPleft policyengine-uk in #1655). So an 18- or 19-year-old living with a parent counts as an adult, on both the headline path and this sampler. 5 of the 200 households state such a pair as a couple: 075 and 079 (carers stratum), 177, 179 and 196.aa_categorywhatever the country.Invariants (tested, including property-based tests)
uk_auditoutput maps to a policyengine-uk variable, and every council and rental area is a policyengine-uk enum member.tests/test_uk_audit.pyandtests/test_export_full_run.py: 61 passed locally. CI runs the full suite (test,lint,app,paper); this PR merges only once all four pass on its head.What the run found (internal)
Six models, 200 households, $36.67. The reference audit (blind judge on ChatGPT-subscription Codex lanes, then my adjudication against the engine code and the law) found new policyengine-uk defects. Each is filed with a fix PR or an issue; the record lists them and the cells they explain. Prompt-side findings for round 3 are listed in
~/reviews/policybench-uk-round2/policybench_followups.md; they are not in this PR, because round 2's frozen prompts must stay as run.🤖 Generated with Claude Code