Repository navigation
UK November event data, PR2: feed re-pin, trading allowance claim status, Scottish council tax and NSND, young people and PIP rows, UC take-up age fit, PIP points, UC limited capability - #1550
Conversation
…425 Chronicle main 8045b13 brings PolicyEngine/chronicle#420's facts for the November UK events, which PR2 of the November event-data plan reads (microcosm#1095): the young people batch (#423: ONS NEET, the LFS A06 tables, PAYE RTI by age, ASHE Table 6, HMRC's employer NICs age reliefs, DWP's UC people by age and conditionality regime), the PIP batch (#424: Pathways to Work PIP points, PIP cases with entitlement) and the Scottish batch (#425: HMRC's Scottish income tax outturn statistics 2024-25, the Scottish Government's social security caseloads and spending). It also carries what main merged after 6475380: #413's UK area inputs, #415's land value inputs (VOA's council tax stock of properties 2026, MHCLG's council tax collection and QRC4 for 2025-26, EPC, land value estimates, dwelling density, the market value survey, ONS land under buildings) and #421's NRS data zone dwelling bands (2,091,616 rows in all). The rows stay chronicle.consumer_fact.v5. A row-by-row diff of the two artifacts finds no row dropped and no value moved: 506,321 rows are new, and 14,784 NRS data zone rows change only their record-set spec hash. No compiled value moves on either surface: both reference files and both compile-parity receipts are byte-identical. The national membership moves its feed label and the candidate counts of MHCLG's council tax band stock by region (VOA's 2026 stock adds candidate facts; no resolution changes), and the local membership its feed label and the 1,263 DESNZ constituency keys, whose derived keys hash the feed identity. The 38 vendored resources and the DESNZ constituency resource carry the same rows under the new feed identity (the DESNZ resource's 2,526 rows and values match on their source record ids). The census and the validation register restate the pin, the coverage manifest the CGT resource's hash, and the H2 fixture moves the stage contract hashes of the 19 stages that bind vendored resources. The high-value home stock's feed inputs are unchanged, so it is not rebuilt. The consumer artifact was built with CPython's cyclic garbage collector off: the build holds every row in memory (about 50 GB footprint on the 24 GiB Mac), and with the collector on the first run stalled for an hour in collection passes over a swapped heap. The regeneration's Python steps ran the same way. The rows are acyclic, so the outputs are the same. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…1535, nit 3) The FRS's full-time education question never codes an apprentice as in full-time education, so frs_person_draws no longer flags an employee aged 21 to 24 who has is_in_full_time_education (from frs_education). The draw's target stays r times everyone aged 21 to 24 at the frame's weights: only the pool it flags from narrows, and the receipt names the excluded flag. The stage refuses a frame without the flag, and the graph node declares it as an input. On policyengine-uk 2.174.1 the flag at these ages moves only the s.9B employer NICs relief, so the rest of the engine's is_apprentice readers are unchanged. The stage's signed eligibility text is restated for María's signature. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…#1439) trading_allowance_receipts keeps its name and #1428's claimant draw, and now writes policyengine-uk's trading_allowance_claim_status instead of encoding the claim in gross receipts, which stay at the engine's zero. Drawn claimants are CLAIMANT, so a raise to GBP 3,000 relieves exactly min(profit, GBP 2,000) more. Every other trader with a positive profit is NON_CLAIMANT. A person with no positive profit is UNKNOWN, and so is the full-relief group: FRS respondents with a profit of GBP 1,000 or less, not drawn claimants, whose receipts lie within the allowance. SPI rows never join the group. The group's share is María's ruling. It is zero, since M10 found no FRS surplus over SPI's declarers, so the group is empty. The carrier trading_allowance_full_relief marks it. The five bound SPI self-employment rows (Table 3.10 by self-employment band, Table 3.6 by total income) now count declarers only by filtering on the carrier, so no row moves while the group is empty. The release keeps the carrier, so a re-measured row reads the same population. The spec, schema branch and graph cells follow. The claim status leaves the signed defaults, and self_employment_gross_receipts is re-signed at zero. Both new columns join the export allow-list, and the receipts column leaves it. tools/measure_uk_trading_allowance_gainers.py measures the raise's gainers on a release from the claim statuses it stores (on an older release it makes the stage's draw again on person_build_id, since the release renumbers person_id). With --fit, it solves the two claimant rates for HMRC's 400,000 gainers at about GBP 380. Without it, it judges the rates on the expected gainers, each band's rate times its would-be gainers, against 400,000 within 5%, with the release's realised count and the draw's spread beside it (María's ruling of 9 November 2026). The regeneration of the references, receipts, coverage manifest, contract digests and H2 follows in its own commit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…iagnostics (S4) Two national rows from HMRC's Scottish Income Tax Outturn Statistics 2024-25 join the contract as measured diagnostics for the Scottish Budget 2027-28 income tax costing: - hmrc.scottish_income_tax.nsnd_outturn: Table 1's final non-savings, non-dividend revenue of Scottish taxpayers, on earned_income_tax + property_income_tax over pays_scottish_income_tax, uprated to 2025 by the engine's OBR average earnings index; - hmrc.scottish_income_tax.nsnd_taxpayers: Table 2's All rates count, on people taxed at the Scottish rates with earned_income_tax above zero, read at 2025 without uprating. Both select feed 8045b1383's 2024-25 record sets for Scotland. The taxpayer row pins the layout's all value, since the six rows by marginal rate share its record set and measure. Two signed exclusions hold both out of the solve; their approved_on is drafted for María's signature. The tests pin 542 targets, 480 in registry scope, 297 unmapped declarations and 51 exclusions. The exclusion names resolve to committed references once the integration regenerates them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… (S2(a)) The FRS council tax stage's Scottish bills sum to GBP 3.10bn on the last release, about 9% below the Scottish Government's own measure of the 2024-25 liability before council tax reduction, while the bound Scottish band stock already fixes the household mix. So the stage now levels the bills' amounts, not the weights (S2(a) of the November event-data plan, microcosm#1095). The measure is the sum over the 32 council areas of CTAXBASE 2025's Band D equivalent dwellings before council tax reduction at September 2024 (the middle of 2024-25; dwellings after discounts and exemptions, as the bills are) times CTAS 2026's average Band D council tax for 2024-25: GBP 3.393bn. Both tables are vendored from the pinned feed into scotgov_band_d_liability_facts.json (64 rows), which the stage verifies against the pin before it reads the raw tab. One factor, the measure over the Scottish households' derived bills at the spine design weights, scales every Scottish household's council_tax; bills elsewhere and every weight are unchanged. The stage receipt records the measure, the stored total, the factor and the Scottish households' support as a band. A frame with no Scottish bill to level (a synthetic fixture's) keeps its bills as derived, and its receipt says so. obr.council_tax_scotland stays a held-out diagnostic. The manifest declares the resource artifact, a verify_vendored_fact_resource operation and the new level_scottish_council_tax operation, which the operation vocabulary and the sources schema now carry; the closed-world assert covers all three declarations and the artifact. The synthetic spine roster and the pinned resource and operation lists follow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…1439) T1 stores each trader's trading_allowance_claim_status instead of #1428's gross receipts, so its claimant rates are re-fitted to HMRC's policy paper on the raise (about 400,000 taxpayers with a lower bill, by about GBP 380 on average) on the new encoding before PR2's arm, as María asked on 6 Nov. tools/measure_uk_trading_allowance_gainers.py --fit on control C2's release (0dff777: main after PR1 plus the 8045b13 re-pin; review date 2026-11-07; all seven terminal gates pass) sets every trader outside the full-relief group to CLAIMANT, runs one simulation pair at 2028 on policyengine-uk 2.174.1 (the allowance at GBP 3,000 against one held at GBP 1,000 from 6 April 2027) and solves the two free band rates: 0.6364 for profits up to GBP 4,500 (from 0.72) and 0.1532 from there to GBP 9,000 (from 0.14). Both lie in the unit interval. The evidence file holds band aggregates only, each band resting on 30 or more households. The rates move in the stage module and both copies of the stage's manifest together; the calibration text names the fit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Nit 3, T1 and S2(a) change stages and S4 adds two contract rows, so the surfaces derived from them are regenerated once on the branch head, on the national cut of the re-pinned feed: - the national target references and membership: S4's two Scottish rows resolve and are active (1,597 to 1,599 active references; no other reference moves). The NSND outturn reads HMRC's GBP 18,635m for 2024-25, uprated to 2025 by the OBR earnings index; the taxpayer count reads 3,036,400 as published. ACTIVE_REFERENCE_COUNT follows, and the Scotland geography test checks both rows are active; - the national compile-parity receipt: the two rows enter as ledger-only (new targets have no frozen fixture value); nothing else moves; - the release-input coverage manifest, for the stage manifest's new hash; - last, the charter-H2 fixture: the frs_council_tax, frs_person_draws and trading_allowance_receipts stage payloads and graph nodes, the synthetic CGT asset-type facts sized to the frame those stages leave, and the normalization note's new string column. The local census, references, membership and receipt do not move: PR2's rows are national. The regeneration ran its Python steps with CPython's cyclic garbage collector off, as the re-pin did; the outputs are the same. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…agnostics (Y4) Three national rows from DWP's People on Universal Credit by country, age and conditionality regime (Stat-Xplore UC_Monthly, chronicle#420 item 3) join the contract as measured diagnostics for the young people work review: - dwp.uc.people_aged_16_to_24, dwp.uc.people_aged_16_to_21 and dwp.uc.people_aged_22_to_24: Great Britain, every regime, DWP's single years of age summed at the four quarterly points of 2025 and averaged (monthly_window_sum_average, the State Pension by-age pattern). The model counts claimants and partners (is_claimant_or_partner) in benefit units with positive universal_credit, in the Great Britain regions. The bands are María's call of 8 Nov: 16 to 17 sits inside 16 to 21, so no row and no difference of rows shows it on its own. The regime split waits for her regime mapping. Three signed exclusions, drafted for her signature, hold the rows out of the solve. The tests pin 545 targets, 483 in registry scope, 300 unmapped declarations and 54 exclusions; the exclusion names resolve to committed references once the integration regenerates them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… (P3) DWP's PIP cases with entitlement (Stat-Xplore PIP_Monthly_new, chronicle#420 item 6) join the contract as 94 measured diagnostics, the source of P2's award-mix check. There is no England-and-Wales fact, so England and Wales are separate rows (María's call of 8 Nov): - per country: every case; each component's standard, enhanced and nil award; and age bands from 16 to 19 up to 70 to 74, with 75 and over merged. DWP's cube carries no case above 79, so its 75 to 79 band meets the model's recipients aged 75 and over; - the nine English regions by each award of each component. The rows select the country and region cubes by their source tables, on the four quarter-end points of 2025 (monthly_window_average), under a new dwp_pip monthly family in SOURCE_MONTH_FAMILIES. The model counts people with pip above zero by their reported pip_dl_category and pip_m_category. The breakdowns are single: on the interim arm's release the award-by-age cross rests on fewer than three survey households in many Welsh and some English cells, while every single breakdown clears three once 75 and over is merged. Ninety-four signed exclusions, drafted for María's signature, hold the rows out of the solve. The tests pin 639 targets, 577 in registry scope, 394 unmapped declarations and 148 exclusions; the exclusion names resolve to committed references once the integration regenerates them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ons.neet.people_aged_16_to_24 joins the contract as a measured diagnostic for the young people work review: ONS's NEET Table 1 (August 2026, chronicle#420 item 1), UK, aged 16 to 24, not seasonally adjusted, as the mean of the four LFS quarters inside calendar 2025 (María's call of 8 Nov). The model counts people aged 16 to 24 neither employed nor self-employed, nor in full-time education (the FRS answer since Y2), nor in approved training; the FRS records no part-time study or other training, which ONS counts as education, so the proxy and ONS's count measure different things. A signed exclusion, drafted for her signature, holds the row out of the solve. The compiler gains quarterly_window_average, beside the monthly windows: - the selector declares period_type quarter and an explicit, unique, ordered YYYY-Qn list; the reference takes source_window, an explicit period and no operands; - _resolve_quarterly_window_reference_facts requires one fact per declared quarter, of one series and one publication, and the value is their sum over the declared count; - each LFS quarter is its own record set (people_nsa.2025_q1, ...), so the series check drops the quarter piece from record-set ids and layout values. The drop sits behind strip_quarters on _selector_period_invariant_key, which only the quarterly resolver sets, so no other series identity moves; - the source-window period check, the reference metadata (ledger_source_quarters and count), the authoring list, the UK hold exemption for window operations and the contract's allowed_value_operations carry it. Sixteen engine-free tests cover the mean, the refusals, the declaration rules and the confinement of the quarter drop. The shared compiler suite (514), the BE references (156) and the UK compile, holds and reference tests pass. The tests pin 640 targets, 578 in registry scope, 395 unmapped declarations and 149 exclusions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test_uk_measurement_period holds every variable a binding reads as a filter or condition to a reviewed list: such reads keep the frame's stored values, so each must be engine-computed or unchanged between the frame's period and the calibration period (microcosm#1324). PR2's rows add nine: - engine-computed at the calibration period, stored by no frame: earned_income_tax and pays_scottish_income_tax (S4's Scottish NSND rows) and pip (P3, which the engine adds from the award categories); - stored, and the same in every period: is_claimant_or_partner (Y4, a benefit-unit role), is_in_full_time_education and is_in_approved_training (Y3, the FRS answers since Y2), pip_dl_category and pip_m_category (P3, stored for every projected year) and trading_allowance_full_relief (T1's stage flag). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tools/generate_uk_target_references.py and the national compile-parity builder on feed 8045b1383's national cut (repin_8045b1383.sh from "national", the local surfaces, coverage and H2 skipped: the new rows are national only), at the head of Y4, P3 and Y3: - target_references.json: 1,697 references, 1,599 plus Y4's 3, P3's 94 and Y3's 1, all active; no existing reference moves. The allowed operations gain quarterly_window_average, and the hierarchy the new rows' labels; - target_reference_membership.json: the 98 rows active on their declared geographies; no existing entry or pin moves; - the national parity receipt: 98 new ledger_only rows (no fixture counterpart), none removed. Every exclusion name now resolves to a committed reference. The tests pin the new count (ACTIVE_REFERENCE_COUNT 1,697), the operation list, 38 GB UC rows, 120 UC monthly references with Y4's windows, the 94 PIP references on the four quarter-end points of 2025, and P3's membership pins. Y4's three rows read DWP's 762,585 people aged 16 to 24, 386,618 aged 16 to 21 and 375,968 aged 22 to 24. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Y2's full-time education flag takes full-time students off Universal Credit, but uc_take_up refits each family type's award-band pools to DWP's caseloads without reading age, so it refilled the single caseload with other entitled singles: claimants and partners aged 16 to 24 stayed well above DWP's count already at the spine's design weights (María's call of 2026-11-09, "Age-aware redraw"). The redraw keeps every pool's count. Within each pool, the drawn units with a claimant or partner aged 16 to 24 (is_claimant_or_partner, at the stored age, which policyengine-uk carries unchanged to the entitlement year) claim at one odds ratio against the pool's other drawn units, and the two rates realize the pool's count together, each in the order of the uniform. The ratio is solved by bisection on its log over Great Britain, at the stage's household weights, so that those young claimants and partners in entitled units that claim come as near DWP's People on Universal Credit aged 16 to 24 as the redraw allows: every regime, the single years summed in February, May, August and November 2025 and averaged, 762,585, the value the dwp.uc.people_aged_16_to_24 diagnostic compiles. Fixed claims (units that report Universal Credit, and units moved off or kept on their legacy benefits) and pools whose count needs more claims than their other drawn units can give keep young units claiming whatever the ratio, so the count can stay above DWP's; where no ratio reaches it, the ratio holds at the nearer end and the receipt says why. Without the age inputs the stage keeps its old path. The facts are vendored with the tool from the pinned 8045b138 feed into dwp_uc_people_by_age_facts.json (Great Britain's rows of the four months' every-regime record sets, 112 rows), with its selection and package entry. The manifest declares the second artifact, its verify operation and three new keys on assign_award_band_take_up_residual (young_people, age_targets, age_fit), which the sources schema carries. The receipt's age_fit block records DWP's count, the young claimants and partners before and after, and the ratio, withheld where fewer than three source households carry the drawn young units. Y4's exclusion reason is restated: the fit brings the 16 to 24 count as near DWP's as the redraw allows, and the rows stay held out as checks on the fit, on the solve and on the split between 16 to 21 and 22 to 24. Tests: the count reader and its refusals, the committed count, the fit keeping the pool's count while meeting DWP's young count on a frame where it can, the out-of-reach bound, the inputs' refusals and the redraw's plumbing; the pinned resource lists follow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The release-input coverage manifest restates the source manifest's digest (25 leaves), and the charter-H2 spine fixture carries uc_take_up's new artifact, verify operation, age keys and notes, with its stage contract hash. The H2 parity test passes on the regenerated fixture. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
María signed PR2's drafted texts on 9 November 2026: - the 100 measure exclusions (S4's two, Y4's three, P3's 94 and Y3's one): approved on 2026-11-09, expiring 2027-02-09, with the signature marker dropped from their adjudications; - S4's reviewed_no_index uprating hold for the Scottish taxpayer count: approved on 2026-11-09, expiring 2027-01-09; - T1's declarer-only notes on the five bound SPI self-employment rows, and S2(a)'s level rule in frs_council_tax's notes (sources.yaml and source_stages.json in lockstep): "María's signature of 2026-11-09"; - the five changelog fragments that called the dates drafts; - and the texts with no date to set: Nit 3's restated eligibility, T1's full-relief group and its zero share, the restated #1428 filer stance, the carrier kept on the export with all five SPI rows filtered, the re-fitted claimant rates, and self_employment_gross_receipts re-signed at zero. The concepts module keeps its signature marker on that text, as it does on every signed text there. The arm's review date (2026-11-09) is the signing day, so it stays valid evidence for these registers. The release-input coverage manifest restates the source manifest's digest, and the charter-H2 fixture carries frs_council_tax's notes; H2 parity passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On the age-fit arm (pr2q-cf73a) the age fit held at its lower bound: the shortfalls that the single pools from GBP 700 a month up pass to their neighbours, where DWP's count exceeds every unit they entitle, filled the single pools around the under-25 standard allowance to every drawn unit, so young units claimed whatever the ratio. A replay of the stage on the spine's checkpoint, which reproduced the stored receipt exactly, sized the alternative, and María adopted it on 9 November 2026, to be tested in the next arm. With the age fit's inputs, _pass_unmet_gaps takes each pool's drawn weight with no claimant or partner aged 16 to 24, and a shortfall passed to another pool fills only those units: its room is the pool's undrawn claims plus that weight, less its count. What no pool can take that way stays unplaced, so the family type's caseload falls short of DWP's count by it. A pool's own count still draws on all its drawn units, an excess passes as before, and without the age inputs the stage keeps its old path. The age_fit receipt records each family type's unplaced shortfall. On the saved inputs of the arm's stage the young claimants and partners meet DWP's count, and the single caseload falls short of DWP's at the stage's weights; the calibration binds single households without children below the redraw's count, so the solve can close it. The stage's gate holds each family type no further from DWP's count than before the redraw, which the singles meet. The pooling and age-fit rule texts, the stage notes, the module docstring (which drops an interim figure from a comment) and the changelog follow; sources.yaml and source_stages.json stay in lockstep. Tests: the gap rule with and without older weights, and a shortfall left unplaced rather than drawn from young units. The coverage manifest and the H2 fixture are regenerated; H2 parity passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test_uk_pension_age_benefit_targets expected one filter on Table 3.10's employment counts by self-employment band. T1 (713a0d0, microcosm#1439) gave SPI's rows of declarers a second, trading_allowance_full_relief = false, and this row is one of them. The E4 frame in test_uk_stochastic_tools lacked is_in_full_time_education, which the apprentice draw reads since Nit 3 (31b9aa5). The code is unchanged; the tests now pin what it does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…(P1) policyengine-uk 2.174.1 decides a PIP component's rate from pip_dl_points and pip_m_points (8 points for the standard rate, 12 for the enhanced) wherever no category is supplied for the year. The release stored pip_dl_category and pip_m_category, which the engine copies into every projected year, so no reform to the thresholds could move anyone (P1 of the November event-data plan, microcosm#1095; María's go of 9 November 2026). A new late stage, pip_points, just before trading_allowance_receipts, draws each recipient's daily living and mobility totals within their stored award from DWP's Pathways to Work evidence pack, chapter 2, Tables 2.9 and 2.10 (the PIP caseload's points by age group, England and Wales, end of January 2025; chronicle#420 item 5). The tables are vendored from the pinned feed as dwp_pip_points_facts.json and verified against the pin. Each age group's distribution spreads a daily living band's share over its integer points, with the open band at 41, and takes the mobility totals as published; restricted to the stored award's range, it is inverted by one uniform per component on person_id. A recipient of one component draws the other's total below 8, and a person with neither keeps -1. The stage asserts that the points give back every stored category at the thresholds; its receipt gives England and Wales's weighted shares by DWP's cells against DWP's, by age group, with support bands and small cells withheld. The release drops the two categories (UK_RELEASE_EXPORT_DROPPED_COLUMNS), the export allow-list carries the points instead, and the categories join the reviewed export exclusions, in code and gates.json. The coverage manifest tool restates the categories as engine-derived exclusions. The eFRS reference's engine (2.89.0) read them as plain inputs, so a reviewed list admits the inputs the pinned engine derives since the reference, and the ledger's engine-derived section carries the two entries, dated for María's signature. The points join through a family of their own. The spec gains the stage (YAML and JSON in lockstep), the operation kind assign_pip_points_by_award with its schema branch, the artifact and its verify operation. The graph, kernels, spine build and H2 fixture tool wire it, and the roster pins move to 55. Tests: eight engine-free ones for the reader, the draws, the fallback, the stage and its closed world; an engine test that policyengine-uk's categories from the points equal the stored ones in every year from 2024 to 2030, on thresholds of 8 and 12; and the manifest tool's reviewed list. The coverage tests' pins, engine-free and engine, restate the categories as engine-derived and add the stage to the required build stages; the engine one also checks that the pinned engine derives both categories. For María's signature: points spread evenly within a band, with the open band at 41; Scotland's and Northern Ireland's recipients on England and Wales's tables; pension-age recipients on the 60-and-over row; draws on person_id. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The release-input coverage manifest restates the source manifest's digest, adds the pip_points family and restates the two PIP categories as reviewed exclusions (141 required and 4 reviewed of 145 inputs), and the charter-H2 spine fixture carries the 55th stage, its cells and its contract. H2 parity passes. The release contract's committed digests in microcosm-data (the spec's policy, gates manifest and fingerprint, and the release cut's scoped parts) are re-pinned on this spec. They also catch up with PR2's earlier commits, whose spec and gates.json edits had left them at main's values; CI's engine-free job failed on that at a859ac7, in test_uk_release_assembler. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
policyengine-uk 2.174.1 gives limited capability for work and work-related activity to anyone flagged is_disabled_for_benefits (any reported disability benefit or ESA), unless their own ESA award lacks the support component. The FRS 2024-25 links most UC claims to DWP's records, and BENEFITS.UCLCW gives the claim's own status. SN 9563's UKDA data dictionary codes it 0 None, 1 LCFW Group and 2 LCFWRA Group, and it is blank where the claim has no linked record. This is Y1 of the November event-data plan (microcosm#1095), on María's NS6 ruling of 9 November 2026, which revisits her ruling of 29 October to keep the proxy. frs_spine carries the status as frs_uc_lcw_status on the UC row's person, and the release drops it. The FRS keeps one UC row per claim, couples included; the carrier refuses a second UC row on a claim, an unknown code, or a UC row whose person isn't on the spine. A new engine-backed stage, uc_limited_capability, runs just before uc_take_up. It asks the locked engine for its proxy, the UC claimant role and carer status, then stores uc_limited_capability_for_WRA and uc_limited_capability_for_work for every person. Linked FRS claims take DWP's status: - NONE sets every claimant false; - LCWRA keeps the claimants the proxy flags. If it flags none, both flags go to the UC row's person, or to the partner where the UC row's person cares and the partner doesn't; - LCW does the same, with WRA false. Everyone else keeps the proxy. The receipt counts the linked claims by status against the proxy, with support bands and small cells withheld with their partner, and counts each branch of the rule. The spec gains the stage (YAML and JSON in lockstep) and the operation kind assign_uc_limited_capability_from_admin_status, with its schema branch. The graph, kernels, spine build and H2 fixture tool wire it; the fixture tool's string audit counts the carrier (33 columns), and the roster pins move to 56. The export allow-list carries both flags, and the coverage tool gains the stage's family. The bound LCWRA row's note records the ruling; it no longer says the carer and childcare rows sit on the measure-exclusion register, since neither does. The synthetic FRS fixtures carry UCLCW beside UCSTART. Tests: - the carrier (three); - the stage's rule, receipt, refusals and closed world (six); - two engine tests on 2.174.1: unlinked people keep the engine's own proxy, and the LCWRA element follows DWP's status in 2024 and in a 2025 dataset holding the stored flags. For María's signature: the NS6 restatement, the code mapping, the joint-claim rule, NONE overriding the proxy, and who keeps the proxy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The release-input coverage manifest restates the source manifest's digest and adds the stage's family. Its counts are unchanged: 141 required and 4 reviewed of 145 inputs. - The charter-H2 spine fixture carries the 56th stage, its cells and its contract, plus the UCLCW carrier in its synthetic BENEFITS rows, its person sources and its normalization note. H2 parity passes. - microcosm-data's release contract digests (the spec's policy, gates manifest and fingerprint, and the release cut's scoped parts) are re-pinned on this spec. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
María signed P1's five choices and Y1's six on 9 November 2026. P1: - points spread evenly within a band, with the open band at 41; - Scotland's and Northern Ireland's recipients on England and Wales's tables; - pension-age recipients on the 60-and-over row; - draws on person_id; - the two categories leaving the release, with their reviewed export exclusions and the coverage ledger's two engine-derived entries (approved 2026-11-09). Y1: - NS6 restated: read UCLCW for linked claims, the proxy elsewhere; - the code mapping; - the joint-claim rule; - NONE overriding the proxy; - who keeps the proxy; - the restated LCWRA row note. The markers go. These texts now record the signature: the two stages' notes (YAML and JSON) and module docstrings, P1's export exclusion reasons (code and gates.json), the ledger entries and the coverage tool's copy, the LCWRA note, and the two changelog fragments. The coverage manifest, the H2 fixture and microcosm-data's release contract digests are regenerated for the texts, and H2 parity passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
María's call of 10 November 2026, after the calibrate-only arms on pr2q-daa35's spine: bind DWP's people on Universal Credit aged 16 to 21 and 22 to 24 (Y4) and England's and Wales's PIP cases by the award of each component (P2), and keep S4's two NSND rows held out. - calibration_measure_exclusions.json drops those 14 entries (149 to 135), the set the combined variant measured. - 16 to 24 stays held out as the check on its two parts, since binding it as well would weight the same people twice. Its reason no longer says the parts stay held out, and its adjudication records the call. The restated entry is for María's signature: approved_on 2026-11-10, expiring 2027-02-10, so an arm that reads this register needs a review date from 2026-11-10. - The 82 other PIP rows keep their signed exclusions. - The contract's parity notes on the 14 rows, the PIP cube's comment in uc_source_periods and its test, and three changelog fragments now say which rows bind. - test_packaged_exclusions_load pins the register at 135 (was 149), and its note now names PR2's rows beside S4's. No derived surface moves: no committed reference, receipt, fixture or digest reads the measure-exclusion register or the parity notes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
María signed the restated exclusion for DWP's people on Universal Credit aged 16 to 24 on 10 November 2026. That covers the reason that keeps the row held out as the check on its two bound parts, and the adjudication that records her call of that day. The signature marker goes from the adjudication, and Y4's changelog fragment now says she signed it. approved_on stays 2026-11-10, the signing day, and the entry expires 2027-02-10. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Y1 put uc_limited_capability between uc_capital_coherence and uc_take_up. The legacy-closure stage's order pin still put the capital check two stages before it, so CI's engine-free job (3.14) failed at 33c2737. The pin now names all three stages before it. Y1's targeted run had missed this file, which reads the stage order from the packaged spec. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
microcosm#1439's "Done when" asks the stage's tests to cover an allowance above £3,000, the case #1428's receipts encoding mis-scored. On the locked engine, a reform to £5,000 in 2028-29 relieves a claimant's 2025 profit by min(profit, £4,000) and a non-claimant's by nothing, for profits of £1,500 and £6,000. The file passes: 11 tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Y1 put uc_limited_capability straight after uc_capital_coherence. The capital check's test of the stages that follow it, none of which writes a UC report, failed both engine-free jobs at 09add32. The test now expects Y1's stage first. The 14 test files that name the stages around Y1's insertion pass locally (605 tests). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Review of 8780aa3 I read the code and config changes against the merge of #1535 ( From #1535: all four items are closed. Should 1 was counted, with fewer than three households, and noted in the stage notes. Should 2 was fixed in Should
Nit
Checked and fine
CI at 8780aa3: lint, wheels, installed-emitter, select-countries, integration-uk, engine-uk (3.13) and engine-uk (3.14) pass. engine-free (3.13, 3.14) and engine-us (3.13, 3.14) are still running. Verdict: the code matches its signed texts and the law I checked. Should 1 and Should 2 are the two to settle before the national is rebuilt on it. Both can be handled with notes if the fixes wait. 🤖 Generated with Claude Code |
Vahid's review of #1550 (Should 1): policyengine-uk 2.174.1 has one set of PIP points thresholds, and frs_spine reads Scotland's Adult Disability Payment (FRS codes 117 and 118) as PIP. So a threshold reform reaches Scotland's ADP recipients and Northern Ireland's PIP recipients too, whose awards their own regulations set. - The pip_points receipt gains recipients_by_country. For England, Wales, Scotland and Northern Ireland it gives the rounded records, a support band and the weighted count at the stage's weights. The weighted count is withheld for a country on fewer than three source households. Recipients in a region no country lists are counted apart. - The P1 changelog says so. It also says (Nit 3) that the points are each component's total, drawn independently: they score the 8 and 12 thresholds, not a rule on one activity's points. - No frame cell moves, and the stage notes are unchanged. The 11 test files that read the stage pass (317), with two new tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Vahid's review of #1550, Should 1 and Should 2, settled with notes on María's signature of 10 November 2026: - A, pip_points. A reform to the points thresholds reaches Scotland's ADP recipients, whom the FRS codes as PIP, and Northern Ireland's PIP recipients, whose awards their own regulations set. The receipt counts each country's recipients for netting them out. The points are each component's total, drawn independently: they score the 8 and 12 thresholds, not a rule on one activity's points. Text A is in the stage notes (YAML and JSON) and the module docstring, and the P1 changelog says it is signed. - B, frs_council_tax. Scotland's level counts the liability of about 21,600 second homes and 43,500 liable empty homes in September 2024 (Scottish Government, Second Homes and Empty Properties in September 2025), which no FRS household occupies. They are roughly 2 to 3% of the chargeable stock, so the factor may carry 2 to 5% of the level that belongs to no FRS household. Netting them out needs CTAXBASE's counts by class in Chronicle, a follow-up. Text B is in the stage notes (YAML and JSON) and the S2(a) changelog. The release-input coverage manifest restates the source manifest's digest, and the charter-H2 fixture carries the two stages' notes. The 46 engine-free files that read the spec, the coverage manifest or the two stages pass (3,266 tests, 20 skipped), and H2 parity passes on the regenerated fixture. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks, Vahid. Should 1 (ADP and NI PIP under a threshold reform): agreed. Should 2 (second homes and empty dwellings in Scotland's level): agreed: the level carries their liability. gov.scot's Second Homes and Empty Properties in September 2025 puts September 2024 at about 21,600 second homes and 43,500 liable empty homes, roughly 2 to 3% of the chargeable stock. The stage notes and the changelog now say how much of the level they could carry, signed by María ( Nit 3: the P1 changelog's scope now says the points are each component's total, drawn independently. They score a change to the 8 or 12 thresholds, not a rule on one activity's points, and they keep no link between the components. Nit 4: agreed. The arm reads take Y4's 16–24 at the spine's design weights beside the release; for the head arm those are 1.002 and +0.1%. We'll report the spine reading on every arm. 🤖 Generated with Claude Code |
|
Round 2 at b4250eb I read
Records: text A sits in CI at b4250eb: lint, wheels, installed-emitter, select-countries, integration-uk, engine-uk (3.13, 3.14), engine-us (3.13, 3.14) and engine-free (3.14) pass. engine-free (3.13) is still pending. Verdict: Should 1 and both nits are done. Should 2 is the one left. Its notes are accurate, but the D14f share already gives an interim correction, so the deferral needs either that or a reason. 🤖 Generated with Claude Code |
|
Thanks, Vahid. 1. Should 1: agreed on the note. The counts are at the stage's spine weights; to net ADP and Northern Ireland recipients out at release weights, filter on 2. Should 2: we'll defer the correction to PR3 of the November event-data plan (#1095), which nets these dwellings out of the level. You're right that D14f already nets them out of
3 and 4: thanks. 🤖 Generated with Claude Code |
main moved microcosm-emitter-interface to 0.14.0 (and its floor in microcosm-build); this branch moved policyengine-uk and the UK side's policyengine-core. uv.lock merges both, uv lock confirms it unchanged, and APPROVED_UV_LOCK_SHA256 is that lock's digest. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part of #1095. The fragment still said 26, from before the six columns microcosm#1550 adds were declared; gates.json declares 32. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The UK lock moves on from 2.174.1 to 2.177.7, the newest release, after #1550 merged (microcosm#1095); policyengine-core stays at 3.34.10, and uv.lock moves policyengine-uk alone. 2.177.5 to 2.177.7 add no input, so the concept coverage keeps its 378 inputs and only its version moves. They change what the build's engine reads return: - 2.177.5 (PolicyEngine/policyengine-uk#2807): no income-related ESA for a claimant who has reached pensionable age, or for a couple that would get Pension Credit without it. - 2.177.6 (PolicyEngine/policyengine-uk#2808): the legacy enhanced disability premium for enhanced PIP daily living and armed forces independence payment beside the highest DLA care rate, and four councils' own working-age CTR lists. The is_enhanced_disabled_for_benefits the build stores now reaches only Kingston upon Thames's working-age Council Tax Reduction and two deprecated counts. - 2.177.7 (PolicyEngine/policyengine-uk#2830): the allowances and reliefs set against income in the way that gives the least tax. Every text that cites the locked engine was checked against 2.177.7 and moves with it; only tax_band's comment changed among the variables they cite. The approved lock digest, the three pyproject floors, the engine-core pin test, the version stamps of the uprating pins and the bonus-sacrifice anchor, the coverage manifest and the changelog follow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
PR2 of the plan for the November event data (microcosm#1095). It re-pins the UK feed onto Chronicle main after PolicyEngine/chronicle#423, #424 and #425, which bring PolicyEngine/chronicle#420's facts for the November UK events, and carries the pieces that read them. It stays on policyengine-uk 2.174.1, as main locks it.
Closes #1439 (T1). That issue's last "Done when" item, the national rebuilt and the trading allowance measure rescored on it, follows with PR2's datasets after the merge.
Draft. María signed the PR's texts on 9 November 2026 (see "Rulings and signatures"). Lane P's PIP points stage (P1) and Y1, the admin-linked limited capability status, are in, and María signed their eleven choices the same day. The arm at the signed head and four calibrate-only variants ran on 9 and 10 November (see "Measurement"). On their results María chose on 10 November to bind Y4's two age bands and P2's PIP award split, and to keep S4 held out. She signed the one restated register text the same day.
The re-pin to 8045b13 (2,091,616 rows).
Nit 3 (Vahid's review of UK November event data, PR1: full-time education, single ages 16 to 24, Scottish PRIS diagnostics, energy kWh columns #1535): apprentices only outside full-time education.
frs_person_drawsno longer flags an employee aged 21 to 24 who is in full-time education (is_in_full_time_education). The FRS never codes an apprentice that way.T1, microcosm#1439: the trading allowance claim status in three outcomes.
trading_allowance_receiptswritestrading_allowance_claim_status: CLAIMANT for drawn claimants, NON_CLAIMANT for other traders with a positive profit, UNKNOWN otherwise.self_employment_gross_receiptsstays at the engine's zero.tools/measure_uk_trading_allowance_gainers.pyjudges the rates on the expected gainers, each band's rate times its would-be gainers, against 400,000 within 5%. The release's realised count is reported beside it (María's ruling of 9 November 2026).S4: HMRC's Scottish NSND outturn 2024-25, two held-out diagnostics. These are the revenue (£18,635m, uprated to 2025 by the OBR earnings index) and the taxpayer count (3,036,400, read at 2025 under a reviewed hold, since no pinned index counts taxpayers).
S2(a): Scotland's council tax bills levelled.
Y4: DWP's people on Universal Credit aged 16 to 24, 16 to 21 and 22 to 24.
P3: DWP's PIP cases with entitlement, 94 rows. England and Wales are separate rows, each with its total, the awards of each component and age bands; the nine English regions are split by each award. All are single breakdowns. Each country's six award rows bind, the award split (P2, María's call of 10 November 2026); the other 82 stay held out.
Y3: ONS's NEET people aged 16 to 24, held out. It is the mean of 2025's four LFS quarters, not seasonally adjusted, on a new
quarterly_window_averagecompile rule.The UC take-up redraw fits young claimants by age (
uc_take_up, María's call of 9 November 2026).P1: PIP points for every recipient (
pip_points, María's go of 9 November 2026).pip_dl_pointsandpip_m_points(8 points standard, 12 enhanced) wherever no category is supplied for the year. The release used to store the categories, which the engine copies into every projected year, so no reform to the thresholds could move anyone.Y1: DWP's limited capability status on linked UC claims (
uc_limited_capability, María's NS6 ruling of 9 November 2026, which revisits her ruling of 29 October to keep the engine's proxy).is_disabled_for_benefits(any reported disability benefit or ESA), unless their own ESA award lacks the support component.BENEFITS.UCLCWgives the claim's own status (SN 9563's data dictionary: 0 None, 1 LCFW Group, 2 LCFWRA Group; blank where the claim isn't linked).frs_spinecarries it on the UC row's person; the FRS keeps one UC row per claim, couples included.uc_take_upstores both flags for everyone: the locked engine's proxy, with DWP's status on linked FRS claims. Unlinked reporters, the take-up redraw's entrants, the legacy-closure movers and every SPI row keep the proxy.Measurement
0dff7773e: main after PR1 plus the re-pin; review date 2026-11-07; feed 8045b13):cf73a73ad, before the squash; review date 2026-11-09):daa359a0b; a full spine, since P1 and Y1 change stages; review date 2026-11-09):uc_take_upreproduces the stored receipt. Replayed with and without Y1's flags, it gives 1.2% more Great Britain benefit units claiming with an LCWRA element with them.Rulings and signatures
María's call of 10 November 2026, on the calibrate-only variants: bind Y4's 16 to 21 and 22 to 24 rows and P2's award split, and keep S4's two rows held out (
b835be176; the signature below is33c273773).approved_on2026-11-10 and expires 2027-02-10, so the next arm needs a review date from 2026-11-10.Signed by María on 9 November 2026. The registers carry
approved_on2026-11-09: the exclusions expire 2027-02-09 and the S4 hold 2027-01-09. The arm's review date is the signing day.frs_person_drawseligibility text.self_employment_gross_receiptsre-signed at zero;reviewed_no_indexuprating hold.pip_points):person_id.uc_limited_capability, NS6 revisited):UCLCWfor linked claims, and keep the proxy elsewhere. The bound LCWRA row's note records it, and no longer says the carer and childcare rows sit on the measure-exclusion register, since neither does.uc_reporter_redraw's award screen, earlier in the spine, still reads the proxy.Still to come in this PR
Not in this PR
Derived surfaces
scotgov_band_d_liability_facts.json(S2(a)),dwp_uc_people_by_age_facts.json(the age fit) anddwp_pip_points_facts.json(P1).pip_pointsfamily, and the two categories as reviewed exclusions (141 required and 4 reviewed of 145 inputs);gates.jsonedits had left them at main's values.uc_limited_capabilityfamily (still 141 required and 4 reviewed of 145 inputs);UCLCWin its synthetic BENEFITS rows;Testing
Targeted tests by touched surface at each step, one process per file:
test_uk_release_input_coverage.py, now restated;test_uk_pension_age_benefit_targetsandtest_uk_stochastic_tools, now pinned ine7f8223a3;test_uk_cgt_projection(the engine is installed there), the two intest_uk_rowwise_build_driver(a temp folder under home prints as~; they pass outside it) andtest_uk_orrery_reconstruction(Orrery's Node package isn't installed locally);a859ac7c9failed in the engine-free job, intest_uk_release_assembler, on the release contract's stale digests, which2e0dc5771re-pins. CI stops at its first failure.uc_take_upand the concept mapping) and 7 engine files: 1,704 passed, 5 skipped and 2 failed of 1,711;uc_take_up's preceding stage, and the engine coverage test's required build stages. Restated; the two files rerun pass (34 and 52);daa359a0b): the 13 engine-free and 2 engine files that read the signed texts, the coverage manifest or the contract: 920 passed and 5 skipped of 925. H2 parity, on the regenerated fixture: passed.b835be176), the files that read the measure-exclusion register or the contract's notes:test_uk_measure_simulation, now 135; the file reruns pass (65);test_uk_release_assembler: 38 passed.33c273773): the 20 engine-free files that read the measure-exclusion register and the 2 engine files above: 1,056 passed, 1 skipped.33c273773failed in the engine-free job (3.14) on one test of 22,242: a stage-order pin intest_uk_legacy_closure_take_up, stale since Y1 putuc_limited_capabilitybeforeuc_take_up.09add3214restates it, and the file passes (26).e4185628d): a reform to £5,000 in 2028-29 relieves a claimant's 2025 profit by min(profit, £4,000) and a non-claimant's by nothing. T1's engine file passes (11).Checks:
ruff checkandruff format --checkare clean on the changed Python files, P1's 24, Y1's 22 and the binds' 3 included.tools/ci_test_plan.py verifypasses.Disclosure
Figures here are national, Great Britain, England, Wales or Scotland-level aggregates, and one English region's population row, each resting on 30 or more survey households. Statements over several rows include cells on fewer: the twelve bound award rows (Wales's nil cells rest on 10 to 29 households) and the counts and averages over P3's rows (cells on 3 to 29 households among them). No figure rests on fewer than three. They include no unit-record values and quote no SPI-channel rows.
🤖 Generated with Claude Code