Skip to content

Autumn Budget 2026: post-Budget written briefing - #1469

Merged
MaxGhenis merged 24 commits into
mainfrom
budget-2026-post-budget-briefing
Oct 29, 2026
Merged

MaxGhenis merged 24 commits into
mainfrom
budget-2026-post-budget-briefing

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

The post-Budget written briefing promised by the webinar invitations ("Our written briefing follows by 7am tomorrow"), due live by 07:00 UK (07:00Z) on Thursday 29 October. It is also the hero of the UK newsletter at 12:00 UK.

What's in it

  • app/src/data/posts/articles/uk-autumn-budget-2026-briefing.md: one post on the Budget's household measures together: what the Budget does (the 7 measures we model, and the significant ones we don't); the combined effect of the 7-measure package (cost by year, net income by decile, winners and losers, inequality; poverty held, see the plan); one paragraph per measure with its headline figure and explainer link; how our estimates compare with the official costings (the matching line in the OBR's detailed forecast table 1.1, Table 6.1's totals as context) and why (the dashboard's notes, merged in uk-autumn-budget-dashboard-2026#296 and Create Team page #298, with their figures, linked on the dashboard's Public finances view); savings income (official costing only); what we're improving (Max's approved text, verbatim); methodology and the Nuffield Foundation funding credit.
  • posts.json entry dated 2026-10-29 07:00:00, authors Max Ghenis, Vahid Ahmadi and María Juaristi (approved by Max via the coordinator, 19:30Z).
  • Cover app/public/assets/posts/uk-autumn-budget-2026-briefing/cover.webp, in the illustrated style of the Pension Tax Allowance cover. The bars on the page are the package's 2026-27 percentage gain by income decile, to scale.

Figures

Every PolicyEngine figure in the results is read from the dashboard's publication: production's release manifest, revision 17 (www.policyengine.org, live since 22:02Z on 28 Oct when uk-autumn-budget-dashboard-2026#290 merged; byte-identical to the test deployment's, SHA-256 9685adc1…) (updated 2026-10-28 19:24:46Z). Every entry is approved (Vahid's approval binds each entry's artifact and output digests; María is second signer on the four hand-written entries' attestations), the savings measure is absent, and every figure equals revision 44's. So the post and its card no longer say the figures are provisional. Package combined--f91fe847275730cb; all 8 artifacts used match the digests in their receipts. Every figure was re-checked on the production manifest at about 22:05Z: 0 failures.

The "why each differs" bullets also quote figures from the dashboard's comparison notes (#296 and #298, merged into the release branch), which draw on further runs of the model; the post says so and links them. Since the release branch's eaf1a887 the full notes are tooltips on the comparison table's Difference cells. All seven render on the dashboard's Public finances view, each in every year its row has a Difference cell (a year the measure isn't in force on either side is a status line), and each is restored only because it renders. The capture (capture_notes_v2.js → cap_to_hashes.py → notes_from_bundle.py, run fail-fast by run_production.sh) lays each year's page over the top of the window, opens each tooltip and finishes its fade. Since Sol r5 it requires every character of each note to be on screen. Each text node must lie in boxes inside the tip, any clipping ancestor and both viewports, and win a hit test at its own centre in the frame, with the frame winning at top level. It must also be visible, with effective opacity above 0.5, colour and fill above half alpha, 3:1 contrast and 8px or more, under no mask, clip-path or filter. A self-test on production plants 14 kinds of hidden text and catches every one. It also reads the manifest each render showed from the page itself: the catalogue's snapshotSha256 (the loader's SHA-256 of the manifest bytes it read) and the dashboard's key, before and after reading the notes, once the page has checked the live manifest itself (data-publication-check="page"). Both must equal the manifest the capture fetched before and after. The hash travels through the hashes and notes files to the checker, which fails unless it equals the SHA-256 of the manifest bytes it checks. The capture fails on hidden text, a missing year, a mid-capture deploy, a second build, or a render under any other manifest. It writes nothing downstream when it fails, and test_capture_gates.py proves each gate refuses tampered input (13 of 13). On the test deployment at 21:55Z (build dpl_BZ8H…, revision 17, the same manifest hash in all six renders) all seven notes, the statement and the timing caveat were recovered byte for byte from the deployed JavaScript, and the checker passed with 0 failures. On production at about 22:04Z (build dpl_4GAM…, revision 17, no hidden tips) the same seven notes rendered, byte-identical to the test site's. At about 22:38Z the rebuilt capture ran again on production: every character of all seven notes on screen in every year, all twelve render checks on manifest 9685adc1… (revision 17), one build. The notes, statement and caveat were identical to the 22:04Z capture's, and run_production.sh ended OK with the checker at 0 failures.

A checker (check_briefing.py, kept outside the repo) recomputes every PolicyEngine figure from the manifest's artifacts and every official figure from the OBR's detailed forecast table 1.1 (policy.xlsx in uk-autumn-budget-dashboard-2026#300 at 555e7f74, sha256 cdcc2a06…) and the Table 6.1 workbook, and asserts the post prints each exactly. It fails, naming the figure, when the manifest withholds or doesn't publish a cell the post prints. It checks the card description, the software versions and dataset against the manifest's execution identity, and that the post and card call the figures provisional exactly while any entry is. Each figure restored from a note is traced to the note as the dashboard renders it: the page hashes each rendered note, and notes_from_bundle.py recovers the matching text from the deployed JavaScript by SHA-256, so the notes file is byte-for-byte what readers see; it must come from the same deployment and manifest revision, and each note's own PolicyEngine figures must equal the manifest's. Every other number is traced to a quoted source (Budget, policy costings, PTA explainer, OBR EFO), and any untraced number fails. It also checks that "What we're improving" is Max's approved text verbatim, and that no poverty figure appears outside it. Mutation tests (a dropped note, a changed note figure, a stale revision, a missing caveat, a note disagreeing with the manifest, an edited article figure, an edited or appended line in the approved section, a poverty line) each fail. It passes on revision 17 with 0 failures.

The fuel note's statement of the law (3p back on 1 January 2027, 2p more from 1 March) matches policyengine-uk 2.151.0's fuel duty schedule and its legislative references (SI 2026/164 as amended by SI 2026/555; Hydrocarbon Oil Duties Act 1979 s.6(1A)); the Treasury's costing extends the cut "from 1 January 2027 to 1 July 2027". "The Treasury's 500,000" is in HM Treasury's Pension Tax Allowance explainer.

Comparables review, 2026-10-28 (manifest revision 17)

Every PolicyEngine estimate the briefing features, beside the official costing: the line in the OBR's detailed forecast table 1.1 (policy.xlsx, dashboard #300 at 555e7f74) that matches what we model, with Table 6.1's rounded total for context. £ million; negative is a cost. Gap is PolicyEngine relative to the OBR line. A gap above 25% needs a verified reason, or is marked GAP STATED, REASON NOT ESTABLISHED for Max's read.

Estimate Year PolicyEngine Official (OBR line) Table 6.1 total Gap Above 25%? Explanation
Package of seven (sum of OBR lines) 2026-27 -3,110 -3,935 -3,955 -21% no
Package of seven (sum of OBR lines) 2027-28 -615 -1,122 -1,095 -45% yes Sum of the measures' gaps below: Property income tax +399, Fuel duty +261, Trading allowance -110, Zero VAT on electricity -58, Pension Tax Allowance +14.
Package of seven (sum of OBR lines) 2028-29 +210 +235 +260 -10% no
Package of seven (sum of OBR lines) 2029-30 +166 +85 +120 +95% yes Sum of the measures' gaps below: Trading allowance +47, Property income tax +35.
Package of seven (sum of OBR lines) 2030-31 +301 +248 +280 +21% no
Package of seven (sum of OBR lines) 2031-32 +281 +150 +180 +87% yes Sum of the measures' gaps below: Trading allowance +48, Property income tax +47, Carer's Allowance taper +21, Pension Tax Allowance +15.
Household Energy Payment (PSCE in RDEL) 2026-27 -1,969 -2,627 -2,625 -25% yes REASON: scope. The official line also covers the devolved governments' share (about £425m, our Barnett estimate, dashboard note) and £100m for councils in England (Budget); ours is 94% of the remaining £2,100m, and the Budget doesn't itemise the last £130m or so.
Zero VAT on electricity (VAT) 2026-27 -840 -734 -755 +14% no
Zero VAT on electricity (VAT) 2027-28 -353 -296 -305 +19% no
Fuel duty (Fuel Duty) 2026-27 -301 -574 -575 -47% yes REASON: coverage. We count fuel households buy, about £13bn of the OBR's £24bn of fuel duty (EFO; dashboard note); scaled to the OBR's receipts ours would be about £450m and £760m against £574m and £782m (note's run). The rest of the 2026-27 gap fits a costing with the full 5p back on 1 January 2027 (£555m) where the law brings back 3p then and 2p from 1 March (£410m): the note's inference, not established. The official figure is the government's estimate, which the OBR used but could not certify (EFO chapter 3).
Fuel duty (Fuel Duty) 2027-28 -521 -782 -780 -33% yes REASON: coverage. We count fuel households buy, about £13bn of the OBR's £24bn of fuel duty (EFO; dashboard note); scaled to the OBR's receipts ours would be about £450m and £760m against £574m and £782m (note's run). The rest of the 2026-27 gap fits a costing with the full 5p back on 1 January 2027 (£555m) where the law brings back 3p then and 2p from 1 March (£410m): the note's inference, not established. The official figure is the government's estimate, which the OBR used but could not certify (EFO chapter 3).
Pension Tax Allowance (Income tax) 2027-28 -30 -44 -45 -33% yes GAP STATED, REASON NOT ESTABLISHED. Ours is net of Pension Credit, Housing Benefit and CTR; the OBR's Welfare inside cap line is zero. Income tax alone, ours is £42m/£112m/£193m against the OBR's £44m/£83m/£144m: about 5% lower (from the printed figures, Max 28 Oct), then 35% and 34% higher (PTA seat's run of #290 at 9b98370e, equal to the published net). 2030-31 and 2031-32: the Treasury's costing note gives no reason for figures after the allowance ends; ours are zero.
Pension Tax Allowance (Income tax) 2028-29 -83 -83 -90 -1% no
Pension Tax Allowance (Income tax) 2029-30 -144 -144 -150 -0% no
Pension Tax Allowance (Income tax) 2030-31 0 +49 +50 -100% yes GAP STATED, REASON NOT ESTABLISHED. Ours is net of Pension Credit, Housing Benefit and CTR; the OBR's Welfare inside cap line is zero. Income tax alone, ours is £42m/£112m/£193m against the OBR's £44m/£83m/£144m: about 5% lower (from the printed figures, Max 28 Oct), then 35% and 34% higher (PTA seat's run of #290 at 9b98370e, equal to the published net). 2030-31 and 2031-32: the Treasury's costing note gives no reason for figures after the allowance ends; ours are zero.
Pension Tax Allowance (Income tax) 2031-32 0 -15 -15 -100% yes GAP STATED, REASON NOT ESTABLISHED. Ours is net of Pension Credit, Housing Benefit and CTR; the OBR's Welfare inside cap line is zero. Income tax alone, ours is £42m/£112m/£193m against the OBR's £44m/£83m/£144m: about 5% lower (from the printed figures, Max 28 Oct), then 35% and 34% higher (PTA seat's run of #290 at 9b98370e, equal to the published net). 2030-31 and 2031-32: the Treasury's costing note gives no reason for figures after the allowance ends; ours are zero.
Property income tax (Income tax) 2027-28 +399 0 +35 n/a yes REASON: timing. The OBR puts £0.0bn (rounded) and £1.0bn of Self Assessment receipts from the savings and property rises in 2027-28 and 2028-29 (EFO Table 4.4), so those years aren't comparable with our tax years. From 2029-30 ours is 9% to 11% above the line; the official costing takes off £0.1bn a year for incorporation and non-compliance (EFO paragraph 3.17).
Property income tax (Income tax) 2028-29 +412 +539 +575 -24% no
Property income tax (Income tax) 2029-30 +429 +394 +435 +9% no
Property income tax (Income tax) 2030-31 +446 +403 +445 +10% no
Property income tax (Income tax) 2031-32 +459 +412 +455 +11% no
Trading allowance (Income tax and NICs) 2027-28 -110 0 0 n/a yes GAP STATED, REASON NOT ESTABLISHED. Candidates: the official costing includes taxpayers switching from expenses to the allowance (Treasury costing note: included, size not given), which we don't model; without gross receipts in the survey data we give traders with profits above £3,000 nothing (dashboard note). 2027-28: the dashboard's caveat that a change such as the trading allowance can appear about a year later in the official costings.
Trading allowance (Income tax and NICs) 2028-29 -118 -221 -225 -47% yes GAP STATED, REASON NOT ESTABLISHED. Candidates: the official costing includes taxpayers switching from expenses to the allowance (Treasury costing note: included, size not given), which we don't model; without gross receipts in the survey data we give traders with profits above £3,000 nothing (dashboard note). 2027-28: the dashboard's caveat that a change such as the trading allowance can appear about a year later in the official costings.
Trading allowance (Income tax and NICs) 2029-30 -119 -165 -165 -28% yes GAP STATED, REASON NOT ESTABLISHED. Candidates: the official costing includes taxpayers switching from expenses to the allowance (Treasury costing note: included, size not given), which we don't model; without gross receipts in the survey data we give traders with profits above £3,000 nothing (dashboard note). 2027-28: the dashboard's caveat that a change such as the trading allowance can appear about a year later in the official costings.
Trading allowance (Income tax and NICs) 2030-31 -120 -171 -175 -30% yes GAP STATED, REASON NOT ESTABLISHED. Candidates: the official costing includes taxpayers switching from expenses to the allowance (Treasury costing note: included, size not given), which we don't model; without gross receipts in the survey data we give traders with profits above £3,000 nothing (dashboard note). 2027-28: the dashboard's caveat that a change such as the trading allowance can appear about a year later in the official costings.
Trading allowance (Income tax and NICs) 2031-32 -130 -178 -180 -27% yes GAP STATED, REASON NOT ESTABLISHED. Candidates: the official costing includes taxpayers switching from expenses to the allowance (Treasury costing note: included, size not given), which we don't model; without gross receipts in the survey data we give traders with profits above £3,000 nothing (dashboard note). 2027-28: the dashboard's caveat that a change such as the trading allowance can appear about a year later in the official costings.
Carer's Allowance taper (Welfare inside cap) 2030-31 -24 -33 -40 -28% yes REASON: Scottish block grant in the official figure, no income tax line; like-for-like, before tax, ours is about a sixth higher. Ours is net of £15m/£32m of income tax on the allowance (dashboard note); before it, £39m/£79m against the OBR's Carer's Allowance and UC spending of £33m/£69m. The OBR's total adds £5m/£10m Scottish BGA (current).
Carer's Allowance taper (Welfare inside cap) 2031-32 -48 -69 -80 -31% yes REASON: Scottish block grant in the official figure, no income tax line; like-for-like, before tax, ours is about a sixth higher. Ours is net of £15m/£32m of income tax on the allowance (dashboard note); before it, £39m/£79m against the OBR's Carer's Allowance and UC spending of £33m/£69m. The OBR's total adds £5m/£10m Scottish BGA (current).

Savings income: official costing only, no PolicyEngine figure published. OBR income tax line 2026-27 0, 2027-28 +63, 2028-29 +483, 2029-30 +443, 2030-31 +475, 2031-32 +510; Table 6.1 row 62 +15, +125, +555, +520, +555, +590.

Comparables infrastructure (scorecard#208, newsletters#29) is unmerged, so this table is the comparables review. The Resolution Foundation (08:00Z) and IFS (10:30Z) publish after the post goes live, so their estimates go in the newsletter and not in this table.

Plan

  • Draft from revision 43

  • Figure-by-figure check script against the manifest (re-runs in one step on production)

  • Comparables table (official costings and the Report Output pages with charts from v1 for household calculation reports #296 reasons)

  • Independent review r1 (GPT-6.1 Sol): REQUEST CHANGES, 3 blocking and 2 nits, answered in 5cfcf24 (provisional stated; unexplained remainders kept without run-only figures; pence: fuel duty rate dropped, mileage and duty rates kept as statutory rates; HBAI deciles; company car 40% cap)

  • Independent review r2 (GPT-6.1 Sol) on a frozen snapshot of 5cfcf24: r1 findings 1, 2, 4 and 5 RESOLVED, no new blocker. It keeps r1's pence point (5p cut, 55p/35p mileage rates); the coordinator ruled those statutory rates stay. Its two nits are applied in 8cff379 (PTA eligibility includes people reaching State Pension age in the year; the checker now checks the card), and its note that untraced numbers were only listed is fixed: they now fail.

  • Restore the dashboard notes' figures once Report Output pages with charts from v1 for household calculation reports #296 merged, only for notes that render (all seven do), traced to the rendered text; move to release manifest revision 17 (all approved; provisional wording removed) in 28047bf

  • Independent delta review r3 (GPT-6.1 Sol) of 28047bf: REQUEST CHANGES. Finding 2 (the reasons' intro pointed at Table 3) fixed in e2ba2d2; 4 superseded by the OBR basis; 5 (property behaviour and Self Assessment figures untraced) now traced to the EFO (paragraph 3.17, Table 4.4); 6 (provenance wording) applied; 7: the checker now fails on a rendered note it can't recover. 1 (capture on production) is the production step below. 3 (trading timing for 2028-29) not taken: unverified, and the row is marked reason not established.

  • Coordinator, ~21:00Z: the Carer's Allowance and PTA gaps cite the OBR's table 1.1 directly (its text), traced to policy.xlsx; the PTA's income tax (−£41.53m unrounded) is from the PTA seat's run of Create Donate page #290 at 9b98370e, whose net equals the published result to the penny

  • Max's rule via the coordinator (~21:30Z): every official comparison uses the matching OBR line, with Table 6.1 as context (Tables 3, 6 and 7 and every bullet), in e2ba2d2; checker and comparables moved to the same basis; 17 mutations each fail

  • Coordinator, ~22:00Z (Max's corrections) in 04aad56: the PTA's 2027-28 gap reads "about 5% lower", computed from the printed figures (£42m against £44m; 35% and 34% unchanged); Table 2 (measures we don't model) moved to each measure's OBR table 1.1 total to the £ million, Table 6.1's rounded totals as context in its source line (the checker asserts each Table 6.1 figure is the OBR total rounded to £5m and that each measure number names the same measure in both tables); a reusable mutation test (mutate_briefing.py): 25 of 25 mutations caught

  • Max's style rule via the coordinator (~21:05Z) in 02ae653: "is above" → "exceeds" (VAT and property gaps); the checker fails on Max's grep and on the same with an amount between. The property bullet follows the dashboard's reworded note ("almost no Self Assessment receipts" in 2027-28), still cited to EFO Table 4.4. Notes re-captured on the test deployment's current build with the tooltip route: checker 0 failures, 28 of 28 mutations caught

  • main merged in (d20a79e; posts.json conflict with the property explainer Autumn Budget 2026 property income tax explainer #1460, both entries kept); the property paragraph links that explainer (04f2afd), whose figures match ours

  • Coordinator's cautions in c2713f8: poverty held until production is live and María has ruled on the unfloored poverty columns (Create Donate page #290); no reason given for the Carer's Allowance gap (its note's tax reason is being corrected) or the PTA gap (its data reason may be dropped); "official counts income tax only" cut

  • Max's voice sweep (via the voice-sweep session) in 4be0729: seven sentences to the active voice ("We leave out the savings income rate rise…", "We rank households into deciles…", "We hold our estimate back from this release…; it follows with that update")

  • Independent review r4 (GPT-6.1 Sol) of 02ae653, the whole comparison section on the OBR basis: REQUEST CHANGES. It found Tables 2, 3, 6 and 7, the labels, the certification wording, the PTA and Carer's Allowance figures and all seven notes correct. Dispositions:

    • 5 (three gaps not reproducible from the printed amounts) fixed in 8b913fc: every gap is computed from the figures Table 6 prints (VAT £57 million, fuel £273 million, trading £46 million to £103 million), and the checker derives them the same way;
    • 2, 3 and 4 fixed in the capture scripts (outside the repo; see Figures): opacity and viewport test after the fade, the manifest each render used, fail-fast with nothing written on failure;
    • 6 (the Carer's Allowance bullet called the measure's £38 million and £79 million total "the official figure") applied verbatim in 6a14eb1 on the coordinator's yes (~22:00Z): "The measure's total in the OBR's table is £38 million in 2030-31 and £79 million in 2031-32, before the Treasury rounds it to the nearest £5 million. It includes …"; the checker requires it, and two mutations fail without it;
    • 1 (production) is the production step below.
  • 8b913fc also: the energy payment's remainder ("about £2,100 million remains for the payment in England, and ours is 94% of that. At £100 each, the up to 20 million households the Budget names take up to £2,000 million of it; neither the OBR nor the Budget itemises the rest"), traced to the Budget and the OBR's single line for measure 1. The checker accepts both the release branch's note wording and dashboard Browser back button doesn't move backward through frames #303's (notes moved onto the OBR lines): 32 of 32 mutations caught with each

  • Coordinator, ~22:00Z: "What we're improving" (Max: "Use the widened text"), verbatim, before the methodology, in b800ea4; the checker traces it; poverty stays held (Max: the dashboard publishes tonight on the current model, poverty and people-affected columns out, one consolidated update later this week)

  • main merged in again (031898f; posts.json kept the briefing, the Carer's Allowance taper post Add blog post: the Carer's Allowance earnings taper in the Autumn Budget 2026 #1464 and the trading allowance explainer Autumn Budget 2026 trading allowance explainer #1463); in 6a14eb1 the trading allowance and Carer's Allowance paragraphs link those explainers (both live; their official figures and ours match the briefing's). Dashboard Browser back button doesn't move backward through frames #303 now prints the trading gap as £46 million, as the post does

  • Production (uk-autumn-budget-dashboard-2026#290 merged 22:01:45Z, live 22:02Z, revision 17): notes captured on www.policyengine.org, run_production.sh OK, checker 0 failures, comparables from production (Sol r4 finding 1)

  • Delta review r5 (GPT-6.1 Sol) of 6a14eb1 on production: REQUEST CHANGES. It found every figure, the new section and both linked explainers correct, and r4's findings 4, 5 and 6 resolved. Dispositions:

    • 1 (blocking: text hidden inside a visible tip could pass) fixed in the capture: every character checked, as above; self-test 14 of 14;
    • 2 (blocking: the manifest a render used wasn't verified end to end) fixed: the capture reads each render's manifest hash from the page, which hashes the bytes its loader read, and the hash travels to the checker. Wrapping fetch before navigation was tried first, but Chrome gives the navigated frame a fresh global, so it can't see the bytes;
    • 3 (the Carer's Allowance explainer should flag the overlap correction): a separate published post, so it went to the coordinator, who chose to add it here (see below);
    • 4 ("The notes compare our figures with Table 6.1's totals" goes stale if dashboard Browser back button doesn't move backward through frames #303 merges) applied verbatim in a65a182; the checker requires it
  • Max's rule, active voice in all writing, reduced passives included (28 Oct): 36 more rewrites in 819aa7f and 9e475c3, all in the wording, with no change to any figure, source or claim. Examples: "which Table 1 lists", "The 5p cut continues", "the government's costing, which the OBR certified", "with payments from January 2027", "Self Assessment payments can fall in a later year", "If we scale our estimate up to the OBR's fuel duty receipts". Where the article paraphrases a dashboard note's own passive wording, the checker traces the new phrase to the same rendered note. The checker now fails on be + participle and on reduced passives (for example "certified by" or "rounded to") outside the approved "What we're improving" text and the Nuffield credit. On production revision 17 it gives 0 failures

  • Delta review r6 (GPT-6.1 Sol) of the voice changes: REQUEST CHANGES. 32 of 36 pairs faithful. In a65a182:

    • 1 ("rising with CPI" could read as actual prices): its sentence verbatim;
    • 2 ("rising energy bills" not in the note): kept, because the Budget's own text (para 6.24) says the £100 million funds "targeted support to households acutely impacted by rising energy bills". The sentence now reads "to target support at the households that rising energy bills hit hardest", traced to that paragraph;
    • 3: "Scaling our fuel duty cost up to…";
    • 4: "where the Scottish Government has responsibility for Carer's Allowance", and "is devolved" is off the checker's allowed list.
      CI green on a65a182 (10 of 10); 48 of 48 mutations caught
  • Delta review r7 (GPT-6.1 Sol) of a65a182 and the rebuilt capture: REQUEST CHANGES. It found r5 finding 2 (the manifest each render used), r5 finding 4 and all four r6 findings resolved, every changed sentence matching its source, and the checker at 0 failures. Dispositions:

    • 1 (blocking: three ways invisible text could still pass, by its model of the code, not seen on production: a filter on the frame, a cover over only the opening words, clipping by an ancestor above the tip) fixed in the capture: the frame and every ancestor up to the top-level root get the painting checks (mask, clip path, filter, blending, legacy clip, zoom, any transform but a translation); every clipping ancestor bounds every character, those above the tip included; hit tests run at five points of every character; characters must be at least 6px high; first-line, first-letter, pseudo-element and background-image checks added. The self-test plants 34 kinds of hidden text, each of which must trip the diagnostic named for it: 34 of 34 caught on production, the real note clean before and after
    • the code that ran is now provable: the capture is one function, the page hashes its source (Function.prototype.toString), and cap_to_hashes.py refuses a capture whose hash differs from capture_notes_v2.js (51b3185c… on both production runs)
    • production rerun at 23:07Z (revision 17): every character of all 7 notes in all 20 note-years passed, hidden empty, note hashes identical to 22:38Z; run_production.sh OK, checker 0 failures; gate tests 15 of 15, each now requiring its own PROBLEM line
    • 2 (the explainer sentence): in b87ba4b, below
    • 3 (the mutation harness counted any failure): it now runs the unchanged article first and stops unless it passes, and counts a mutation only when the diagnostic named for it fires
  • main merged in again (0a8a96c: Carer's Allowance taper post: split the official-comparison paragraph #1484 split the Carer's Allowance taper post's official-comparison paragraph, docs: point the property post's dashboard links at main #1485 repointed the property post's links); posts.json keeps the briefing's card, and the briefing article is byte-identical to a65a182. Checker on the merged head: 0 failures

  • r5 finding 3, on the coordinator's call (a): b87ba4b adds one sentence to the Carer's Allowance taper post, after "This is the run behind the figures for this measure on PolicyEngine's Autumn Budget dashboard, split here into its parts.": "We will update the 2030-31 population estimates after correcting how the taper interacts with overlapping benefits, such as the State Pension." It turns the "What we're improving" bullet Max approved into a sentence, in the coordinator's exact wording

  • Delta review r8 (GPT-6.1 Sol) of the merge and the new sentence: APPROVE, no findings. The sentence resolves r5 finding 3 and reads cleanly where it sits; the merge brought in only Carer's Allowance taper post: split the official-comparison paragraph #1484 and docs: point the property post's dashboard links at main #1485; the briefing and its card are unchanged; the explainer's figures (£24m/£48m net, £39m/£79m before tax, £33m/£69m and £38m/£79m official) agree with the briefing's

  • Delta review r9 (GPT-6.1 Sol) of the capture and test fixes: REQUEST CHANGES, three blocking findings, all in the capture, which it found by modelling the code rather than on production: an inset shadow on the text's own ::after could hide it; the check compared text with a translucent background before compositing it; and the capture read its source hash from a shared global at the end, so an overlapping run could carry another run's hash. A separate completeness audit (GPT-6.1 Sol, 20261028-192833-briefing-audit) found eight more ways text could pass unseen: translucent backgrounds, lines laid over each other, pseudo-element paint, pointer events kept off with !important, inert covers, shadows beyond their hit bounds, text security, stroke, shadow or line-through, and covers between the sample points. The capture now fixes all eleven (source sha256 41e230fd…):

    • the census places every ::before and ::after box in the frame from its style and grows it by its paint reach (shadows, outlines, filters, decoration);
    • the check composites the background: the first fully opaque one must belong to the tip, with every translucent layer laid over it, and the contrast check uses the result;
    • each run hashes its own source into a constant, draws a run id, and publishes only while it is the latest run. A race test on production held one variant's final fetch while the file's run finished; the result kept the file's run and hash, and the variant left only its own hash in __capSuperseded (notes/race-prod-rev17-r10.json);
    • covers are now rectangle censuses, with the hit-test stack ordering each pair, so a cover between the sample points no longer passes. Also new: no two characters may overlap, the check forces pointer events at 24-ID specificity and fails any element left without them, and inert content, the top layer, custom highlights, view transitions and running animations near the tip all fail. So do text painting other than glyphs, outlines and reflections. A structural proof shows nothing on the page can paint above the frame;
    • the production runs turned up two Chrome behaviours: the hit-test stack never lists table rows or row groups (the check now places static ones by their table), and it lists a descendant before its ancestor whatever their paint order (nested pairs now use the topmost hit).
  • Production, revision 17 (manifest 9685adc1), on deployment dpl_Ejrz4MQY at 00:15Z, and again on dpl_5kAvQud9 at 00:30Z after dashboard Move the text from the params setter to the middle of the screen #306 deployed:

    • the self-test caught 56 of 56 kinds of hidden text, each by its named diagnostic, with the real note clean before and after;
    • every character of all 7 notes in all 20 note-years passed, with hidden empty and note hashes identical to round 7's;
    • run_production.sh OK with 0 checker failures; gate tests 16 of 16 (now including the race variant's hash); mutations 48 of 48.

    One self-test that I started 4 s after a reload stopped with an error when the tip closed. It failed closed, and the reruns ran clean.

  • Delta review r10 (GPT-6.1 Sol, 20261028-202928-briefing-r10) of all eleven fixes: REQUEST CHANGES. It found the three r9 findings resolved and every plant catching its mechanism, and four more blocking findings, all in the capture, by modelling the code rather than on production:

    • the text's own inset shadow could paint over its background;
    • chained drop-shadow filters reach further than the check allowed;
    • a z-index on a grid or flex item makes the body a stacking context;
    • a pseudo-element could keep pointer events off with a layered !important.
  • Completeness audit r2 (GPT-6.1 Sol, 20261028-202928-briefing-audit-r10): thirteen more cases, none established on production, among them a backdrop filter, a translucent rounded background, border paint, fragmented backgrounds, display: contents containing blocks, zero-height pseudo-elements, a hidden filtering wrapper, SVG text, overlapping-character identity and nested ordering.

  • The capture now fixes all seventeen (source sha256 30cf3af8…):

    • every background in the compositing walk must lie under every character, fragment by fragment and inside its borders;
    • nothing may paint between a background and the text: no inset shadow, and below the opaque background no border, outer shadow, column rule, filter or backdrop filter;
    • an element's reach adds every filter on it and its ancestors in sequence, and is stretched by every transform above it;
    • stacking contexts follow the parent's display, and the body may carry no z-index;
    • ::before and ::after boxes take pointer events too, and one that is positioned or forms a stacking context is placed by a hit test on its own box;
    • text in an SVG fails;
    • the self-test waits for the tip's entrance animation to finish before its last look. One run had caught that 200ms fade at its start, and failed closed.
  • Production, revision 17 (manifest 9685adc1), on deployment dpl_2zfd93yx at about 01:31Z, after dashboard One report creation button is called Create report, one is called Build report #310 deployed (Switch to sentence case throughout the repo #312 and Create report button on navbar doesn't work #311 before it):

    • the self-test caught 75 of 75 kinds of hidden text, each by its named diagnostic, with the real note clean before and after;
    • every character of all 7 notes in all 20 note-years passed, with hidden empty and note hashes identical to rounds 7 and 10;
    • run_production.sh OK with 0 checker failures, and its output identical to round 10's; gate tests 16 of 16; mutations 48 of 48.

    The same code passed on dpl_At5xt27y, and the code one change before passed on dpl_46dvpJhY and dpl_At5x. One report creation button is called Create report, one is called Build report #310 deployed during one capture, splitting its years between two builds, and cap_to_hashes.py refused it as designed.

  • Delta review r11 (GPT-6.1 Sol, 20261028-214518-briefing-r11) of the capture fixes: running. It covers the capture tooling only, not the post, so it doesn't gate the merge (coordinator, with Max's go)

  • Completeness audit r3 (GPT-6.1 Sol, 20261028-214518-briefing-audit-r11): running, on the same terms

  • Max's go, relayed by the coordinator at about 01:50Z 29 Oct: "Briefing Autumn Budget 2026: post-Budget written briefing #1469 now", covering the briefing and the three wording changes beyond it (the Carer's Allowance explainer sentence, "where the Scottish Government has responsibility for Carer's Allowance", and the energy payment's "rising energy bills" clause). Head b87ba4b, gh pr checks exit 0, MERGEABLE.

Resume steps (steps 1–5 done again at 23:07Z on production revision 17 with the r7 capture; if production's revision changes before merge, repeat them)

  1. Production is live when https://www.policyengine.org/uk/autumn-budget-2026/data/manifest.json returns 200 (it 404s until uk-autumn-budget-dashboard-2026#290 merges). Note its revision (N).
  2. Open https://www.policyengine.org/uk/autumn-budget-2026?tab=dashboard&sub=finances in the built-in browser and set its viewport to 1440x1000 (the capture lays a 1280-wide frame over the window and refuses a smaller one). Optionally run the self-test first: window.__capSelfTest = true; then the script; all 34 caught must be true, and control and after empty.
  3. Run the capture: set window.__capSelfTest = false, then paste ~/reviews/budget-briefing-2026/scripts/capture_notes_v2.js from window.__cap = { status: "running" }; to the end into the browser's JavaScript tool, unchanged (it returns "started"). window.__capSourceSha256 must equal uv run python scripts/capture_source_sha.py; cap_to_hashes.py refuses the capture otherwise. Poll window.__cap.status until "done", about a minute. Save JSON.stringify(window.__cap) to ~/reviews/budget-briefing-2026/notes/cap-prod-revN.json. The full JSON includes the scripts list, so read it in two calls if needed.
  4. Run ~/reviews/budget-briefing-2026/scripts/run_production.sh notes/cap-prod-revN.json prod-revN from ~/reviews/budget-briefing-2026. It must end "OK". It stops at the first failure: any note text not on screen, a missing note, a second build, a render under another manifest, text it can't recover, or any checker failure. Then run scripts/test_capture_gates.py --cap notes/cap-prod-revN.json --notes notes/notes-prod-revN.json (all ok).
  5. If N isn't 17, change "manifest revision 17" in the post and in this body, then rerun step 4. If a note's wording changed (for example, dashboard Browser back button doesn't move backward through frames #303 merged), the checker already accepts Browser back button doesn't move backward through frames #303's wording. For any other change, re-trace the affected bullet to the new note.
  6. Replace the comparables table here with comparables-prod-revN.md, and rerun scripts/mutate_briefing.py (all caught).
  7. Commit and push any fix as Max. Freeze a packet with the article, posts entry, cap, hashes, notes and the check output, then run the Sol delta review: subfleet run --task review --tier hard. Arm a subfleet wait.
  8. Confirm gh pr checks 1469 exits 0 and mergeable is MERGEABLE. Then report to the coordinator. Merge only on Max's yes relayed by the coordinator, or by Vahid or María at 07:00 UK. Never use --admin.

🤖 Generated with Claude Code

Draft from the dashboard's test publication, manifest revision 43.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
policyengine-calculator-next Ready Ready Preview Oct 28, 2026 10:54pm UTC
policyengine-website Ready Ready Preview Oct 28, 2026 10:54pm UTC

Request Review

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ines

Dashboard links move to /uk/budgets/autumn-2026. The "why each differs"
bullets keep each reason from uk-autumn-budget-dashboard-2026#296 and drop
the figures that came from the seats' own runs (#296 is still a draft);
derived gaps (manifest less Table 6.1) and official figures stay. Adds
the PTA gaps by year, the trading allowance's 2027-28 gap as a labelled
inference, one line on the package's scope beside the decile and
average-household figures, and drops the description of what the
Treasury's distributional analysis covers until it is verified.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Three series of ten bars put the labels on top of each other at the top
deciles; the tooltip and Table 4 give the values.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Say plainly that the figures are provisional (key results, provenance
  line and card description); the checker ties this to manifest status.
- The energy payment and fuel duty notes keep their unexplained
  remainders, without the run-only figures.
- Net income: changes include changes in VAT and fuel duty; deciles use
  the HBAI definition and hold about a tenth of people.
- Company car rates are capped at 40%; Table 1 drops the fuel duty rate.
- The Treasury's 2027-28 analysis: which measures it covers, as verified
  against its paragraph 1.4.
- People shares rounded (about 94%, 3%, 6% and 1%), from the age table.
- PTA 2030-31 and 2031-32: the Treasury's policy costing note gives no
  reason for the official figures.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Prose shares are whole per cent (about 99%, 4% and 6%); Table 5 keeps
one decimal. All come from the age table's "all" row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Pension Tax Allowance: eligibility includes people reaching State
  Pension age during the tax year (the Treasury's explainer).
- Revision 44 of the test publication changes only the flat summary
  files; every artifact the post uses is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nifest revision 17

Each policy's "why it differs" bullet now carries the figures from the
dashboard's notes as merged in #296 and #298 and rendered on its Public
finances view (all seven, in every year): the HEP's Barnett share and
unitemised remainder, the electricity VAT base, fuel duty's scaled cost
and the 5p timing, the PTA's income tax cost and gainers, property's Self
Assessment timing and incorporation, the trading allowance's percentages,
and Carer's Allowance's income tax. The 2027-28 trading allowance gap now
cites the comparison card's timing caveat instead of our inference.

The figures follow release manifest revision 17, in which every entry is
approved, so the provisional wording leaves the article and the card.
Every figure matches revision 44's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nce gaps

On the coordinator's cautions:
- Poverty stays out until production is live and María has ruled on the
  unfloored poverty columns (dashboard #290); the key result and the
  poverty paragraph are held, and the section is now Inequality.
- Carer's Allowance: the note's income tax reason is being corrected by
  its seat, so the bullet keeps our own figures (the tax on the higher
  allowance, and the cost before it) and gives no reason for the gap.
- Pension Tax Allowance: the note's data reason may be dropped, so the
  bullet gives our income tax cost and gainers without it, and no longer
  says the official costing counts income tax only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Max's rule, relayed by the coordinator: cite the primary source. Each
official figure is now the line in the OBR's detailed forecast table 1.1
that matches what we model (the government's costing, certified by the
OBR; fuel duty is the government's estimate, which the OBR used but could
not certify). Table 6.1's rounded totals stay as context rows in Tables 3,
6 and 7, and the note under Table 6 names the other lines by the table's
labels.

- VAT: 14% and 19% above the VAT line; the Table 6.1-based "within about
  4%" is dropped.
- Property: 9% to 11% above the income tax line from 2029-30; the
  behaviour and the Self Assessment timing now cite the EFO (paragraph
  3.17, Table 4.4).
- Trading: against income tax and NICs, 27% to 47% below.
- HEP: against £2,627 million.
- PTA: income tax against the OBR's income tax line (coordinator's text);
  the net-versus-Table 6.1 sentence is replaced.
- Carer's Allowance: the OBR's breakdown (coordinator's text), then ours.
- Intro to the reasons now says the notes use Table 6.1's totals, and
  points at Table 6 (Sol r3). The provenance line names the EFO (Sol r3).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Max's rule (28 Oct): active voice in all writing, and reduced passives
count. "Certified by the OBR" becomes "which the OBR certified"; "is
extended" becomes "runs three months longer"; "capped at", "cut from",
"kept for a year" and "set 1 point above" in Tables 1 and 2 become active
or noun phrases; "rounded to", "calibrated before", "quoted from" and
"linked above" name who acts. Every number, name and claim is unchanged.
The Nuffield credit stays as the fixed formula the coordinator kept, and
"What we're improving" stays as Max approved it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Twelve more sentences from the independent voice sweep, among them the
deciles definition (twice), the energy payment's start, Self Assessment
timing (three places) and the fuel duty scale-up. The article paraphrases
the dashboard's own passive note wording, and the checker traces the new
phrases to the same rendered notes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The notes' basis now reads "The notes explain the comparisons", true of
  the merged notes and of dashboard #303's (Sol r5, finding 4).
- Zero VAT: Sol r6's sentence verbatim, so "rising with CPI" can't read as
  a claim about actual prices (r6, 1).
- Energy payment: the councils' £100 million targets "the households that
  rising energy bills hit hardest", from the Budget's own text ("households
  acutely impacted by rising energy bills"), now traced to it (r6, 2).
- Fuel duty: "Scaling our fuel duty cost up to..." names what we scale (r6, 3).
- Carer's Allowance: "where the Scottish Government has responsibility for
  Carer's Allowance", Sol r6's active replacement for "is devolved" (r6, 4).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 2 commits October 28, 2026 18:41
Adds the sentence Max approved in the briefing's "What we're improving"
section, after the paragraph's dashboard sentence, as Sol's r5 review
asked (finding 3).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@PavelMakarchuk

Copy link
Copy Markdown
Contributor

Audit of the briefing at b87ba4b8 against the dashboard's production manifest revision 17, Max's PDF (rev17), the seven explainer posts, Budget Table 6.1, the policy costings, OBR detailed table 1.1 and Impact on households. One must-fix before 3:00am EDT; every figure otherwise traces.

Must fix before publication

  1. "Why each differs" (L195–L203) disagrees with the live dashboard notes it links to. The live notes compare with Table 6.1 totals; the briefing compares with the matching OBR line, so the same gaps read differently:

    Measure Briefing Live dashboard note
    Zero VAT £106m (14%), £57m (19%) above £85m (11%), £48m (16%) above
    Property, from 2029-30 9% to 11% above the OBR line "within 1.5%" of Table 6.1
    Trading £46m–£103m below (27%–47%) £46m–£107m below (28%–47%)
    Fuel £273m / £261m lower £274m / £259m lower
    Carer's Allowance no overall share "about 60% of the official costing"

    Property: 429/394, 446/403, 459/412 = +9% to +11% (OBR line); 429/435, 446/445, 459/455 = within 1.5% (Table 6.1). Both are right on their own basis. The briefing's text matches dashboard#303, which is still open. Either merge Browser back button doesn't move backward through frames #303 and confirm it is live before 3:00am EDT, or restore one sentence after L195 that names the two bases (Max's PDF still has it).

Should fix

  1. Fuel duty (L199, last sentence). "fits" a costing that assumes the full 5p returns on 1 January: the costing note does not state its baseline, and the OBR gives another possible cause (late policy changes after its certification deadline). The fuel post does not make this claim. The dashboard note and Max's PDF carry the same sentence; change all three together.
  2. Reason labels claim causes the explainers call unexplained. PTA "(scope)" (L200): on income tax alone ours is 35% and 34% higher, and the PTA post says "we have not established why". Property "(timing and behaviour)" (L201): the property post says the later gap is unexplained, and adding back the OBR's £0.1bn behaviour puts the official line above ours. Trading "(behaviour and coverage)" (L202): the PR's own comparables say "reason not established".
  3. "as property income tax rates rise" (L8, L76, posts.json description). The rates rise once, in April 2027. The top-decile loss grows from £50 to £56 because property income grows and the PTA ends.
  4. PTA "pay no income tax" (L153). True only for income taxed at 20%; the PTA post gives an example with property income at 24% that still pays tax.
  5. Table 2 omits measures that Max's PDF lists, for example Parental Allowance (measure 6, −£69m to −£72m from 2029-30) and the First Time Buyer ISA (38), while it includes the smaller Lifetime ISA change.
  6. Table 7 note (L216). "The line that matches what we model" does not fit: this release does not model savings.
  7. Carer's Allowance losers. 0.15% of people are worse off in 2030-31 and 2031-32 because of the Universal Credit interaction; the briefing does not say why.
  8. L224 "add people-affected figures". Table 5 already gives the gain and lose shares. Max's approved wording, so his call.
  9. Mobile tables. Post tables do not scroll inside their container, so at 375 px Table 2 (about 465 px) and Table 6 (about 428 px) will widen the page. Scroll wide research-post tables inside their own container #1472 fixes this site-wide; merging it before 3:00am EDT covers it.

Nice to have

  • L62: "almost all" of the 2026-27 cost is the three energy and fuel measures; it is all of it.
  • L143: "0.03% or less" → "0.02% or less".
  • L203: 48 + 32 = 80, not 79; add a rounding note.
  • L139: the gain shares also include carers gaining from the taper and people gaining from the property measure.
  • Chart: rounded data draw three 2029-30 bars as zero; no x-axis title.
  • Table 1: property rates rise "on top of Budget 2025's rise", as the savings section says.
  • Dashboard links 307-redirect to the canonical /uk/autumn-budget-2026 path.
  • Print: the Table 4 and 5 captions split from their tables at page breaks.
  • The PR also edits the live Carer's Allowance post, with no "Updated" note.

Verified as correct

  • The revision 17 manifest is byte-identical to production; all 8 artifacts match their receipt checksums.
  • Every PolicyEngine figure traces exactly: key results, Tables 3–6, all 30 chart values, Table 4's 33 cells, Table 5, the Gini change and the per-measure paragraphs. The package differs from the sum of the seven measures by £0.0001m–£0.80m a year, so "less than £1 million" holds. No withheld cell appears.
  • Every OBR table 1.1 line and Table 6.1 figure in Tables 2, 3, 6 and 7 matches, with correct measure numbers, signs and £5m rounding; every gap percentage recomputes.
  • Policy descriptions match the Budget paragraphs, the costing notes and Impact on households.
  • Max's PDF agrees apart from item 1 and item 6. The explainer posts and the savings post (Autumn Budget 2026 savings income tax explainer #1466) agree on figures. "What we're improving" is verbatim.
  • Links resolve (obr.uk blocks scripts). Authors, date, tags and CI (7 of 7) pass.

Not checked: the Vercel preview itself (login), the unrounded "further run" figures (fuel £450m/£760m, PTA 670,000), the fuel duty SI texts, and the effect of open dashboard PRs #285 and #306 after regeneration.

🤖 Generated with Claude Code

@MaxGhenis
MaxGhenis marked this pull request as ready for review October 29, 2026 01:48
@MaxGhenis
MaxGhenis merged commit 69e9a6a into main Oct 29, 2026
10 checks passed
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Admin merge audit. I merged this at the reviewed head b87ba4b (squash, 69e9a6a) with --admin --match-head-commit. The only block was the required approving review, which Max can't give on his own PR.

  • Go: Max, to the Budget coordinator at about 01:50Z on 29 October: "Briefing Autumn Budget 2026: post-Budget written briefing #1469 now". It covers the briefing and the three wording changes listed in the description. The coordinator relayed it, then chose the admin merge at 01:55Z.
  • Gates at merge: gh pr checks exit 0 (10 of 10 pass), MERGEABLE, not a draft, no CHANGES_REQUESTED review.
  • Reviews:
    • Text: GPT-6.1 Sol r8 APPROVE on the article (sha256 d1a98f79…). The article hasn't changed since.
    • Capture tooling: Sol r9 and r10 requested changes, and the completeness audits listed more cases. The capture fixes all of them (source 30cf3af8…). The production rerun on revision 17 caught 75 of 75 plants, and every note-year came out clean.
    • Round 11: Sol r11 (20261028-214518-briefing-r11) returned APPROVE WITH CHANGES. Its five findings are all in the capture tooling and don't block publication; they change no note, figure or render check. Audit r3 is still running. Both feed a follow-up to the tooling, not this page.
  • Figures: production manifest revision 17 (sha256 9685adc1…). The briefing checker found 0 failures, and the poverty figures stay held back.

@PavelMakarchuk

Copy link
Copy Markdown
Contributor

Live review, part 1: the published page (https://www.policyengine.org/uk/research/uk-autumn-budget-2026-briefing, checked 10:20pm EDT).

The post merged at 9:55pm EDT at b87ba4b8, the head that the audit above reviewed, and its text on main is unchanged from that head. So every item in the audit is now live, including the must-fix:

  • "Why each differs" vs the live dashboard. dashboard#303 is still open, so the live dashboard notes still compare with Table 6.1 totals while this post compares with the matching OBR line. Property reads "9% to 11%" above here and "within 1.5%" on the dashboard; zero VAT reads 14%/19% here and 11%/16% there. Either merge Browser back button doesn't move backward through frames #303 (and its official_costings.json:127/:134 follow-up, see the comment there), or add one sentence naming the two bases.

New on the live page — tables at 375 px. #1472 (scroll wide post tables) is not merged, so five tables are wider than the 343 px text column and the whole page widens to 535 px on a phone:

Table Width at 375 px
Table 2: Other household measures we don't model 519 px
Table 6: PolicyEngine and official costings by measure 500 px
Table 3: Budgetary impact of the seven measures 426 px
Table 7: Official costing of the savings income rate rise 393 px
Table 5: Share of people by the change in their household's net income 392 px

Merging #1472 fixes all five. At 1280 px there is no overflow, the four charts render, and the cover and author images load (200).

More parts follow as I finish each check.

🤖 Generated with Claude Code

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Thanks, Pavel. Both fixes already exist as PRs:

🤖 Generated with Claude Code

@PavelMakarchuk

Copy link
Copy Markdown
Contributor

Live review, part 2: the figures from "further runs" and the dashboard notes (checked 10:35pm EDT, 28 October, against main at 69e9a6a, dashboard main at f79397d with manifest revision 17, and the explainer posts on app-v2 main)

The audit above did not trace these figures. All but three now trace to a published artifact, an explainer post or an official document. Three have no source that a reader or reviewer can check.

No traceable source

Line Figure What I found
L198 ONS consumer spending is "10% to 12% lower" than our DESNZ-based spending The figure is only text: obrDeviationNotes.js (the comment above domestic_electricity_zero_vat and the note) and dashboard#303. No data file, receipt, explainer post or named ONS/DESNZ series gives the two bases. The energy post does not mention it. Suggest naming the ONS series and year and the DESNZ table, or dropping the number.
L199 £760 million in 2027-28, "scaling our fuel duty cost up to the OBR's fuel duty receipts" Needs our household fuel duty for 2027-28, which is not published. The implied scale factor is 760 / 434 = 1.75, against 24 / 13.4 = 1.79 for 2026-27. That fits OBR receipts rising £1.8bn in 2027-28 (EFO para 4.29), but I could not recompute it.
L199 "45 billion litres" data_inputs/treasury/exceptions.yaml L48 says "about 45bn litres" and gives no source. The arithmetic on it holds (below).
L195 "some of their figures aren't in Table 6 or in our published results" Correct, but 670,000 is in the published results (see below), so the sentence covers fewer figures than it suggests. No change needed.

Traced

Line Figure Source and check
L197 £425m devolved share Energy post footnote 3: £2,627m ÷ 1.1931 = £2,202m for England (including the £100m for councils); 2,627 − 2,202 = £425m. The factor 1.1931 is the Statement of Funding Policy (June 2025) population proportions at 100% comparability.
L197 about £2,100m; ours 94% 2,627 − 425 − 100 = £2,102m; 1,969 / 2,102 = 93.7%.
L197 25% below £2,627m 1,969 / 2,627 = 0.750.
L197 up to 20 million × £100 = up to £2,000m; "the rest" Budget para 3.5 and footnote 80. The rest is 2,102 − 2,000 ≈ £100m. The energy post (L75) says the same. The live dashboard note says "the remaining £130 million or so" (2,100 − 1,969), which is a different remainder; both are right.
L147 19.7 million households 1,969 / 100 = 19.69 million.
L76, L147 £67 per UK household; £68 to £73 in deciles 1 to 8; £47 in decile 10 artifacts/household_energy_payment_2026/101a07dc7238a10e/winners_losers.csv, 2026: all 67.4; deciles 1 to 8 from 67.7 to 73.5; decile 10 47.5 (47.45 unrounded).
L149 £29 per household; about 94% gain Zero VAT artifact: 28.8; age_impact.csv all ages 93.76%.
L151 £18 per household in 2027-28 Fuel artifact: 17.8.
L199 £273m and £261m lower 574 − 301 and 782 − 521.
L199 about £13bn of £24bn Fuel post L532 (£13.4bn household duty); EFO para 4.29 (£24bn).
L199 about £450m in 2026-27 Duty only, 301 − 50 = £251m; 251 × 24 / 13.4 = £449.6m.
L199 £50m and £87m of VAT Fuel post table L332–L333; exceptions.yaml.
L199 about £555m (full 5p) and about £410m (the law) 45bn × 5p × 3/12 = £562.5m, "about" £555m. Under SI 2026/164 as amended by SI 2026/555, duty is 55.95p from 1 January to 28 February and 57.95p from 1 March: 45bn / 12 × (3p × 2 + 5p × 1) = £412.5m.
L200 £42m, £112m, £193m of income tax PTA post L745–L747. 42 / 44 = 0.955 ("about 5% lower"), 112 / 83 = 1.349, 193 / 144 = 1.340.
L200 about 670,000 people gain in 2027-28 Published, not a further run: artifacts/state_pension_income_tax_protection/1bfeed3c27a3c9b9/age_impact.csv, 2027, people_directly_affected = 665,907. The Treasury's 500,000 is the HMT explainer (PTA post L757).
L200 £182 and £250 a year PTA post L27–L28 and appendix: £250.70 × 1.034 = £259.20 (5p) × 52 = £13,478.40; 20% × (13,478.40 − 12,570) = £181.68, rounded up to £182. × 1.025 = £265.70 × 52 = £13,816.40; 20% × 1,246.40 = £249.28, rounded up to £250. The 3.4% (April 2028, CPI) and 2.5% match the Triple Lock post (L126) and the dashboard's October forecast file.
L153 up to £94 in 2027-28 20% × (13,036.40 − 12,570) = £93.28, rounded up (Budget para 6.182; PTA post L17).
L153 about 3% gain in 2029-30 PTA artifact age_impact.csv 2029: 2.85%.
L155 about 6% lose; top decile £62 Property artifact 2029: 5.81%; decile 10 −61.8.
L157 about 1% gain Trading artifact 2027: 0.88%.
L159, L203 £24m and £48m; £15m and £32m of income tax; £39m and £79m before tax Carer's post L752–L755: net 23.8 and 47.6; tax 15.4 and 31.8; 78.5 − 39.2 = 39.3 and 160.1 − 80.6 = 79.5.
L203 about a sixth more 39 / 33 = 1.18 and 79 / 69 = 1.14.
L159 around 48,000 carers Budget chapter 3: "expected to benefit around 48,000 carers in England and Wales".
L201 almost no SA receipts in 2027-28, £1.0bn in 2028-29 EFO Table 4.4, "Changes to savings and property tax rates": 0.0 and 1.0.
L201 £0.1bn a year of behaviour EFO para 3.17.
L238 policyengine 6.11.1, PolicyEngine UK 2.151.0, Microcosm UK 2024-25 manifest.json revision 17, execution.identity.
L137 0.01% threshold calculators.py L425: np.abs(income_change_pct) > 0.0001.

The 57% share of a year's electricity use is not in the briefing; it is only in the dashboard's measure description.

🤖 Generated with Claude Code

@PavelMakarchuk

Copy link
Copy Markdown
Contributor

Live review, part 3: Tables 1 and 2, the measure paragraphs and the Treasury's distributional analysis against the Budget documents (checked 10:50pm EDT, 28 October)

Sources: the Budget document (E03668986_HMT_Budget_2026), the policy costings, Table 6.1, Impact on households, SI 2026/164 and SI 2026/555, and the EFO text.

New evidence on a known item: fuel duty, "the full 5p returns on 1 January" (L199)

Audit item 2 says the costing note "does not state its baseline". It does, and the OBR says the same:

  • Policy costings, p. 13: the measure "extends the temporary 5 pence per litre (ppl) cut in fuel duty … by 6 months, from 1 January 2027 to 1 July 2027. This follows the announcement in May 2026 to extend the 5ppl cut in fuel duty until 31 December 2026."
  • EFO October 2026, chapter 3: "The Government has since announced a further freeze to fuel duty rates and delay of the reversal until January 2027".
  • The law is different. SI 2026/164 article 8, Table D, as SI 2026/555 article 2 amends it, sets unleaded petrol and heavy oil at 55.95p from 1 January to 28 February 2027 (a 3.45% deduction from 57.95p), and the deduction ends after 28 February.

So the sentence has documentary support. The OBR's other cause is about certification, not the baseline: "Small changes were made to the policy parameters of the fuel duty policy … following the costings certification deadline" (EFO chapter 3, footnote 1, and the Foreword). Suggest citing the two quotes in place of "fits the official costing if it assumes", for example: "The costing note describes the measure as extending the full 5p cut 'from 1 January 2027', and the OBR describes the earlier plan as a delay of 'the reversal until January 2027'; the law instead brings it back as 3p then and 2p more from 1 March." This moves item 2 from Should fix to Nice to have. The dashboard note and Max's PDF carry the same sentence.

New evidence on a known item: Table 2 omissions

Besides Parental Allowance (6) and the First Time Buyer ISA (38), Table 6.1 has two household measures that are larger than the Lifetime ISA row in 2026-27:

Row Measure 2026-27
66 Great British Summer Savings Scheme: VAT at 5% on family days out, 25 June to 1 September 2026 −310
67 Free bus travel for children aged 5 to 15 in England, 1 to 31 August 2026 −145
39 Lifetime ISA withdrawal charge (in Table 2) −15

Both were in force before the Budget, which may be why they are out. If that is the rule, one clause in the Table 2 note would say so.

Should fix

None in this part.

Nice to have

  1. Cash ISAs (L46). "The cash ISA limit stays at £20,000" does not say why it costs £72m a year by 2031-32. Budget para 2.52: the government "decided not to reduce the cash ISA limit". Max's PDF (PR Identify series of best practices that app will employ #1 head, row 11) says "reversing the cut to £12,000 for under-65s that the government had planned".
  2. Scope words in Table 2. Universal Credit (L43): Budget para 6.11 says "in Great Britain". Student loans (L42): the costing covers "English borrowers" (costings, Student Loans note).
  3. Distributions (L50). "where dividend tax fits better" paraphrases the costing's "where dividend Income Tax treatment is more appropriate". The costing's words are safer.
  4. Pension Tax Allowance, "or reaching it during the tax year" (L23, L153). This is not in Budget para 6.182 or the costing note, which say "above State Pension age". It comes from HMT's explainer (PTA post L16). Table 1's source line names only the Budget and the costings.
  5. Treasury paragraph (L125). It says the Treasury "leaves out the Household Energy Payment and the Carer's Allowance change". Neither has any effect in 2027-28 (the payment is in 2026-27 and the taper starts in 2030-31), so leaving them out does not change the Treasury's 2027-28 figures. The differences that matter in 2027-28 are the savings rate rise, the 12 other measures, and the benefits-in-kind from public services (the Youth Guarantee package) that Figures 1.A and 1.B add. The Treasury also ranks households by equivalised net income; we rank by HBAI income before housing costs.

Verified

  • Table 1: energy payment (Budget paras 3.5 and 3.6; Table 6.1 row 1), zero VAT (para 3.4 and 6.210: "six months from 1 October 2026", "to 1 July 2027", "expected to apply UK-wide from April 2027"), fuel duty (para 6.211), Pension Tax Allowance (para 6.182; costing p. 63), property income (para 6.246: 24%, 44%, 49%; England, Wales and Northern Ireland; 6 April 2027), trading allowance (para 6.254), Carer's Allowance taper (para 6.13: "100% taper", "planned to be introduced in 2030-31 and apply in England and Wales"; costing: "within the 2030-31 financial year").
  • L32 to L35: savings (para 6.247: "across the UK"), Triple Lock (para 1.29 and chapter 5: "the amount required to maintain its value relative to earnings as reached in April 2029"; "£15 billion a year by the late 2030s"), National Living Wage (para 6.128 and chapter 3: 3.9%, £13.21, the Low Pay Commission's recommendations "in full"), Bank Surcharge (para 3.5 and Table 6.1 row 55: 3% to 6%, 1 January 2027 to 31 March 2028, "to fund breathing space measures for households").
  • Table 2 descriptions: student loans (costing: 6% cap, 1 September 2026 to 31 August 2027, Plans 2 and 3), Universal Credit (costing: £2,500 "until 31 March 2028", effective 1 April 2027), mileage (costing p. 14: 55p from 6 April 2026, 35p above 10,000 miles from 6 April 2027), bus fares (Table 6.1 row 4: "for one year from 1 January 2027, funded by reprioritising DESNZ budgets"), Lifetime ISA (para 6.240), Founders' Relief (para 6.257), BADR (para 2.53), distributions (costing: from 6 April 2028), private hire VAT (para 6.219: 2 January 2028), company car tax (costing: 1 point, "subject to a maximum of 40%", from 6 April 2030).
  • Measure paragraphs: the energy payment's £100m for councils (para 3.6), the Barnett share (para 3.5), 48,000 carers and the new IT system (chapter 3), the property behaviour (EFO para 3.17), the fuel duty rise on 1 July 2027 to 60.59p (EFO chapter 3).
  • Treasury paragraph (L125): paragraph 1.4 lists 18 policies; five are ours (zero VAT, fuel duty, trading allowance, Pension Tax Allowance, property income); it includes the savings rise and not the energy payment or the Carer's Allowance taper. Paragraph 1.7: "households in the lowest income deciles … will benefit the most … as a percentage of net income", "increases in tax will be concentrated on the highest income households", "all but the top 20% of households will benefit". All three claims match.

🤖 Generated with Claude Code

@PavelMakarchuk

Copy link
Copy Markdown
Contributor

Live review, part 4: the live page's metadata, navigation, chart and links (https://www.policyengine.org/uk/research/uk-autumn-budget-2026-briefing, checked 10:40pm to 10:55pm EDT, 28 October; curl, headless Chrome and a browser at 1280 px and 375 px)

Should fix

None that is specific to this post. #1472 is still open, so the five wide tables from part 1 still widen the page to 535 px at 375 px.

Nice to have

  1. The known "as property income tax rates rise" wording (audit item 4) is in five places. The page's <meta name="description">, og:description, twitter:description and JSON-LD description all come from posts.json, and the newsletter hero (newsletters#34) repeats the clause. A fix to posts.json updates the first four; the newsletter needs its own edit.
  2. The chart's y-axis runs to −0.2% although the lowest value is −0.03%, so about a quarter of the plot is empty. The tooltip header is a bare "4" (no "Income decile"), which adds to the known missing x-axis title.
  3. Site-wide, not this post: there is no <link rel="canonical"> (the fuel duty post has none either); the JSON-LD author names are slugs ("max-ghenis", "vahid-ahmadi", "maria-juaristi"), not names; datePublished is 2026-10-29T07:00:00 with no time zone; there is no og:url or og:site_name. Worth a separate issue.

Verified

  • Title: "Autumn Budget 2026: our briefing on what it means for households | PolicyEngine". og:title and twitter:title match; sentence case.
  • Description: "We estimate the seven household measures we model cost £3.11 billion in 2026-27 and raise net income by £107 per household on average that year. From 2028-29 they raise £166 million to £301 million a year …". Table 3: −3,110; +210, +166, +301, +281 from 2028-29, so the range is right.
  • Image: og:image and twitter:image are /assets/posts/uk-autumn-budget-2026-briefing/cover.webp, 200, image/webp, 1600 × 900, 26.5 kB; twitter:card is summary_large_image. JSON-LD is an Article with the same headline, description, image and publisher.
  • Listings: first card on /uk/research (rendered DOM), also on /uk and on /uk/research?topics=autumn-budget. The "More on" tags are United Kingdom, Autumn Budget, Policy analysis and Featured, from posts.json tags uk, autumn-budget, policy, featured.
  • Contents and anchors: all 11 contents links resolve to a heading with that id, including #what-we're-improving. The two in-text anchors, #savings-income (L32) and #how-our-estimates-compare-with-the-official-costings (L72), resolve.
  • Share links: in a browser after load, X, Facebook, LinkedIn and email carry https://www.policyengine.org/uk/research/uk-autumn-budget-2026-briefing. (A headless DOM dump before hydration shows url= empty; that is not what readers get.)
  • Chart: the post has one chart ("Change in household net income by income decile"); the other three Recharts surfaces are its legend icons. At 1280 px it is 797 × 360 px; the y-axis title is "Change in net income (%)"; the legend reads 2026-27, 2027-28, 2029-30 with --chart-1, --chart-3, --chart-5, the same as the bars; 27 bars draw and 3 are zero-height (the known rounding item). The tooltip for decile 4 reads 0.23%, 0.05%, 0.00%, matching the source block (L92). At 375 px it fits the 343 px column, all ten deciles label, and the legend is one row.
  • Links (curl, following redirects): 13 unique URLs. gov.uk (2), the six explainers, the Triple Lock post and the Nuffield Foundation return 200. The dashboard links return 307 to /uk/autumn-budget-2026 and then 200 (known). The finances deep link keeps ?tab=dashboard&sub=finances through the redirect and opens Public finances with the comparison. obr.uk returns 403 to curl (known; it blocks scripts).
  • Images: the cover and the three author images load.

🤖 Generated with Claude Code

@PavelMakarchuk

Copy link
Copy Markdown
Contributor

Live review, part 5: consistency with the other live outputs, and a fresh read for wording (checked 10:55pm to 11:05pm EDT, 28 October)

Compared with: the live dashboard (/uk/autumn-budget-2026, Public finances), the six explainer posts and the Triple Lock post on app-v2 main, Max's PDF (uk-autumn-budget-2026-policies-explained PR #1 head c3e8eea7, open; main b56b14c3, rev17), and the newsletter (newsletters#34 head 97d2b0a7, open).

Should fix

  1. Abbreviations that the post never expands. OBR (first at L54), RPI (L22), CPI (L198), ONS (L198), ISA (L46) and NICs (L187) have no full form anywhere in the post. DESNZ appears at L45 and is expanded only at L198. Table 6's line names, "PSCE in RDEL" (L172), "Other AME (current)", "Scottish BGA (current)" and "Onshore CT" (L193), are the OBR table's own labels, which the note says, but a reader cannot decode them. One short glossary line under Table 6 would cover the last group, for example "PSCE in RDEL: public sector current expenditure in resource departmental expenditure limits; AME: annually managed expenditure; BGA: block grant adjustment; CT: corporation tax".

Nice to have

  1. "We plan to update these results later this week" (L222). The post is dated Thursday 29 October, so "this week" leaves two or three days. A date, or "in the coming days", avoids a promise that dates quickly.
  2. "About 670,000 people gain in 2027-28" (L200). The figure is people_directly_affected (665,907, all aged 65 or over): people whose own income tax falls. People in households that gain are 1.41% of 69.99 million, about 990,000. "about 670,000 pensioners pay less income tax" says what is counted and matches the Treasury's "500,000 pensioners pay less income tax" (PTA post L757).
  3. The Carer's Allowance bullet (L203) has no reason label, while the other six do. If the labels stay (see audit item 3), "(scope)" fits its text.
  4. Triple Lock (L33). "£15 billion a year by the late 2030s" is the Budget's wording (para 1.29). The Triple Lock post (L7) gives DWP's basis: £15 billion in 2039-40, in cash terms, for Great Britain. Adding "in cash terms" would align the two.
  5. Max's PDF, At a glance (PR Identify series of best practices that app will employ #1 head): "Trading allowance | New: £1,000 to £3,000 from April 2027". The allowance exists already; the briefing's "Rises from £1,000 to £3,000" (L25) is right. This is in the PDF, not the post.

Consistent (no change needed)

  • Explainer posts: every figure the briefing shares with them agrees (see part 2): energy payment £1,969m, 19.7 million, £67, £68 to £73, £47, £425m, £2,100m, 94%; zero VAT £840m and £353m, £29, 14% and 19%; fuel £301m and £521m, £50m and £87m of VAT, £13.4bn of £24bn; PTA £42m, £112m, £193m, £30m, £83m, £144m, £182 and £250; property £399m to £459m, £429m vs £394m (property post L73: "about 9%"); trading allowance; Carer's Allowance £24m and £48m, £33m and £69m, £5m and £10m, £39m and £79m.
  • Fuel duty, the law: the fuel post (L5, L14, L21–L24) and SI 2026/164 as amended give 52.95p, 55.95p from 1 January and 57.95p from 1 March 2027; L199 agrees.
  • Newsletter hero (newsletters#34): "£3.11 billion in 2026-27", "£107 a year on average", "every income decile gains between £98 and £110", "£50 a year … in 2028-29, rising to £56 in 2031-32" all match L5, L6 and L8. "From 2028-29 to 2031-32 they raise money, as the higher rates on property income raise more than the other measures cost" matches L62 and Table 3. Its last bullet repeats "as property income tax rates rise" (audit item 4), so a change to the post needs the same change there. All 13 of its policyengine.org links return 200, or the known 307 for /uk/budgets/autumn-2026.
  • Max's PDF (PR Identify series of best practices that app will employ #1 head): the energy payment, fuel duty and Pension Tax Allowance "why ours differs" texts are word for word the briefing's (the figures come from figures.json placeholders). Its sources line (L392) still names Table 6.1 as the notes' basis, the sentence the audit's must-fix asks for. Its Cash ISA row adds the reason the post lacks (part 3, item 1).
  • Live dashboard: dashboard#303 is still open, so the notes still compare with Table 6.1 (known must-fix). The Public finances chart for 2027-28 shows zero VAT −£355m vs −£305m and the Pension Tax Allowance −£30m vs −£45m, both on that basis. The energy payment note says "£2,625 million" and "the remaining £130 million or so"; the post says £2,627 million and "the rest" (about £100m). Each is right on its own basis.

Wording checks that passed

  • Spelling: UK throughout; no -ize forms, "behaviour", "programme" not used, "per cent" not used (the post uses %).
  • Sentence case: the title, all 11 headings and all 7 table captions.
  • Units and years: every fiscal year is "2026-27" style; billions in the key results and millions in the tables, with no slips between them; minus signs in tables are U+2212.
  • Signs: "A negative number is a cost to the public finances" (L54, L72) holds in Tables 2, 3, 6 and 7.
  • Gini (L143): calculators.py L461 computes (reformed_gini − baseline_gini) / baseline_gini, so "falls by 0.17%" is a relative change, as written.
  • Voice and neutrality: no prescriptions or one-sided framing; "to help fund the energy support" (L35) is Table 6.1 row 55's own purpose.

🤖 Generated with Claude Code

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Thanks, Pavel. Here's where each point in parts 2 to 5 stands. I compared each with the post's source on app-v2 main at 69e9a6a, whose article (sha256 d1a98f79…) hasn't changed since the merge. One point is an error in the public text, and #1487 proposes the correction. The rest are wording, or items already in hand.

The correction in #1487 (ready, held for a go)

  • Part 5, item 3: "about 670,000 people gain" (L200). You're right. The figure is people_directly_affected for 2027-28 (665,907). calculators.py counts a person when their own income tax, National Insurance, student loan repayment or employment income changes by £1 a year or more. The measure's modifier changes only income tax (and Universal Credit's income-tax slices), and only where is_SP_age holds, and none of the other three variables reads income tax directly. So the count is what you say it is: people at State Pension age whose own income tax falls. All 665,907 fall in the 65+ band. On the post's own measure of gaining, people in households that gain, about 990,000 people gain (1.41% of 69.99 million). Briefing: say what the 670,000 Pension Tax Allowance count counts #1487 changes the sentence to "about 670,000 people above State Pension age pay less income tax in 2027-28, against the Treasury's 500,000". The words now match the Treasury's and the Pension Tax Allowance post's (L757). It changes one line and no figure, and it waits for a go before merging. The dashboard note "More pensioners gain in our data (670,000 vs 500,000)" has the same problem; that one is the dashboard's to change, and I'm passing it to the coordinator.

Part 2: the figures without a public source

  • L198, "10% to 12% lower". It traces to OBR comparison: compare like for like, and say what each side counts uk-autumn-budget-dashboard-2026#297. There, ONS Consumer Trends household electricity spending measured 0.88 (2024) to 0.90 (2025) of our base, which is DESNZ Energy Trends domestic volumes at Quarterly Energy Prices 2024 prices. UK: data fixes for the Budget 2026 household measures microcosm#1418, item 12, records the same comparison ("ONS 04.5.1 is 12% lower"). The issue comments record the comparison; I haven't found the diagnostic behind it. Naming the series in the post is wording, so it's on the list below.

  • L199, "about £760 million in 2027-28". I couldn't find the run behind it. A reconstruction from published figures supports it: scale our 2027-28 duty-only cost, £434 million (£521 million less £87 million of VAT), by the OBR's £25.8 billion of 2027-28 receipts (£24 billion plus the £1.8 billion rise, EFO para 4.29) over our household duty. Holding household litres at 2026-27's level (£13.4 billion of duty) and day-weighting the 2026-27 and 2027-28 rates gives £740 million to £770 million, depending on whether we take the rates before or after the Budget. Our household duty for 2027-28 itself isn't published, which L195 already says of these figures.

  • L199, "45 billion litres". exceptions.yaml gives no source. The figure matches the OBR's £24 billion of 2026-27 fuel duty at 52.95p a litre, the rate that holds all year under the Budget: 24 ÷ 0.5295 = 45.3 billion. "About £555 million" and "about £410 million" weight by days, not months:

    • 5p on 45 billion litres for the 90 days from 1 January to 31 March is £554.8 million;
    • 3p for those 90 days, plus 2p more for March's 31 days, is £409.3 million.

    Vahid's review of OBR comparison: the like-for-like mark, and why each policy differs behind an ⓘ (#297) uk-autumn-budget-dashboard-2026#298 checked the same arithmetic.

  • L195: agreed, no change.

Part 3

  • Fuel duty, L199. The two quotes give a firmer basis than "fits the official costing if it assumes". Your suggested sentence is wording, so it's on the list, together with the dashboard note, which carries the same sentence.
  • Table 2, rows 66 and 67. Confirmed in Table 6.1: the Great British Summer Savings Scheme (−£310 million) and free bus travel for children in August (−£145 million), both in 2026-27 and both finished before the Budget. Table 2 doesn't state its rule for what it includes, which is audit item 6. Adding rows or a rule changes the content, so it goes to Max with the rest of item 6.
  • Nice to have 1 to 5 (the cash ISA reason, "in Great Britain" and "English borrowers", the costing's own words for distributions, the source of "or reaching it during the tax year", and the Treasury paragraph) are all wording, and all are on the list. On item 5: the sentence holds, but for 2027-28 it points at the wrong differences. As you say, the savings rise, the Treasury's 12 other measures, its benefits in kind and its income ranking make the difference.

Part 4

Part 5

  • Items 1, 2, 4 and 5 (abbreviations and a glossary line under Table 6, "later this week", the Carer's Allowance reason label, "in cash terms") are wording, and they're on the list. Item 4 also depends on audit item 3, the reason labels.
  • Item 3: Briefing: say what the 670,000 Pension Tax Allowance count counts #1487 proposes the correction (above).
  • Item 6, "New: £1,000 to £3,000" in the PDF. You're right: the allowance already exists, as L25 says. The row lives in the PDF's own repo, and the corrected PDF of 29 October (published/2026-10-29-corrected/proposal.md:44) still has it, so I'm passing it to the coordinator. The newsletter doesn't link the PDF.

The wording list

These change live public text, so they go to Max as one set, alongside d2159:

  1. Expand OBR, RPI, CPI, ONS, ISA, NICs and DESNZ (L45) at first use, and add a glossary line under Table 6 for its line names.
  2. L198: name the ONS series and the DESNZ sources.
  3. L199: your two quotes in place of "fits the official costing if it assumes", with the same change to the dashboard note.
  4. L222: "in the coming days", or a date, for "later this week".
  5. L46: why keeping the cash ISA limit costs money (Budget para 2.52).
  6. L42 and L43: "English borrowers" and "in Great Britain".
  7. L50: the costing's "where dividend Income Tax treatment is more appropriate".
  8. Table 1's sources: add the Treasury's explainer for "or reaching it during the tax year" (L23, L153).
  9. L125: name the differences that matter in 2027-28: the savings rise, the 12 other measures, the Treasury's benefits in kind and its income ranking.
  10. L203: a reason label.
  11. L33: "in cash terms".

🤖 Generated with Claude Code

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

A correction to my reply above, on part 5, item 6. "New" in the PDF's at-a-glance table doesn't claim that the trading allowance is new. It's the PDF's badge for measures that weren't on our pre-Budget list. The corrected proposal.md uses it that way at line 228 ("New … Not on our list") and at line 73, and the Household Energy Payment row carries the same label. The row is therefore accurate. The table just doesn't explain the label. The coordinator has offered Max an optional rebuild that spells it out: "Not on our list: raised from £1,000 to £3,000".

🤖 Generated with Claude Code

This branch was successfully deployed

2 active deployments
Preview – policyengine-website — b87ba4b8 Deployed Oct 28, 2026 by vercel[bot]
Preview – policyengine-calculator-next — b87ba4b8 Deployed Oct 28, 2026 by vercel[bot]
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