UK rowwise local candidate: rulings, registers, receipts, and the dense release line (#762 PR B) - #870
UK rowwise local candidate: rulings, registers, receipts, and the dense release line (#762 PR B)#870juaristi22 wants to merge 29 commits into
Conversation
685e26f to
cd7f856
Compare
|
Review pass at One process blocker, then substance1. CI cannot run on this PR as filed. Findings2. Should-fix — the dense contract does not bind the signed gate report to the run it validates. 3. Should-fix — the A16 register's 4. Should-fix — the assembler does not hash-join the score to the candidate. 5. Should-fix — stale K in signed text. 6. Nit — the round-trip is not tested exactly. Questions
Verified good
Needs the licensed engine or dataThat No code-level blocker. Retarget to main so CI runs, then 2 and 3 are the two I would land before merge — the contract binding because it is what a consumer runs, the tracking ids because they are what the October expiry points at. 4 through 6 are tightening. The uprating, the expiry refusal, the single canonical form with tamper tests and the assembler's hash-join are the substance, and they check out. |
9f4efc7 to
5c86c5f
Compare
|
Thanks. Retargeted to main (rebased onto b875d4c) so CI runs; fixes in 5c86c5f. (2) The contract now binds (3) The five A16 rows track #866–#869 per row. (4) The assembler hash-joins (5) The three sentences now state K=15 with history: Scilly 24 rows / ESS 8.1, City of London 72 / 11.0 on R17; band H unsupported in 76 of 296 authorities at K=15; K=10 refused 86 authority cells, 84 of them band H. Register regenerated from the pinned feed, rationale strings only. (6) Round-trip is exact, weights compared as the typed vector. Questions: a |
vahid-ahmadi
left a comment
There was a problem hiding this comment.
Second pass at d5f04a80 (Claude Code, high effort; worktree checkout, the fix commit 5c86c5fd and the two later commits read against the dispositions; the 21 suites from round one: 853 passed, 0 failed, 0 skipped; both census tools current; ruff check clean; the merge from main carries only #849 with an import reconciliation in one test file and no evil-merge content).
All six findings closed as described, with tests that fail on the previous head where a failing test is possible.
2. Verified. The contract reads build_manifest.attempt_id, fails on a missing or empty value, and _check_uk_dense_gate_report fails when report.release_id differs from it (contract.py:4230-4242, :4290-4332); build_manifest.json is a required release file so a missing manifest cannot bypass it. The two new contract tests — a validly signed report from another attempt, and a manifest with the attempt id deleted — both fail on 9f4efc77. The driver signs with state.build_id and the assembler already writes the Logbook build_id as attempt_id, so an R17-style directory still validates.
3. Verified. Savings interest → #866, housing benefit → #867, both plan-2 stocks → #868, JSA → #869, matching the issue titles, pinned in test_uk_measure_simulation.py. One pre-existing slip in a row the fix touched: the JSA reason says "1.8x at initialization" while 199k against 71k is 2.8×, which is what #869's title says.
4. Verified. The assembler requires the score's candidate_diagnostics.sha256 to equal the measured diagnostics digest and the two incumbent digests to equal --incumbent-manifest outputs (assemble_uk_dense_release_dir.py:255-283); git_dirty is taken from the candidate manifest when it is a bool and recorded as unmeasured otherwise (:504-518), with the driver measuring it by git status --porcelain --untracked-files=no and returning None outside a repository. Three new assembler tests, all failing on the old head. One policy observation rather than a finding: the dense contract never inspects git_dirty, so a candidate measured dirty, or unmeasured, still assembles and validates with exit 0 — the new test asserts exactly that. "Never asserted" is satisfied; whether a dirty candidate should ship is a call for María.
5. Verified and internally consistent. The three sentences agree on K=15 with the K=10 history (84 band-H plus the two micro-authorities = 86), and the receipts corroborate the K=10 line. The K=15 figures themselves (Scilly 24 rows / ESS 8.1, City of London 72 / 11.0, 76 of 296) are not in the receipts file, so they rest on R17. The membership regeneration is rationale strings only: 298 leaf changes, 297 of them rationale text and one the disclosed source_fact_feed rename. One wording note: with 72 rows City of London now clears the 50-row floor, so "unreachable by clone count" is true only of the ESS leg.
6. Verified. Per-entity assert_frame_equal on all columns and the household weights compared as the written column with assert_array_equal. check_dtype=False is unnecessary — it passes with dtypes checked — so it could be tightened.
Questions. _is_census_vintage_hold now derives its years from the ladder's oa_vintage; the new test fails on the old head. One residual: a hold from a non-census vintage is skipped silently — tenure_cells counts only uprated cells, and if oa_vintage were missing the year set would be empty while applied could still read true. A count of skipped holds in the receipt would close that. Both bound-name forms are tested. The A17 answer (no country-level tenure control bound) settles that question.
Nit. ruff format --check flags one long assert in test_uk_council_tax_targets.py:97 from 88c45551; CI runs only ruff check, so not blocking.
Approving. The two things worth a line from you rather than a change: whether a measured-dirty candidate should be allowed to assemble, and a skipped-hold count in the uprating receipt.
anth-volk
left a comment
There was a problem hiding this comment.
I found six release-affecting issues in this revision. I think the first two should be resolved before publication.
-
High — Failed accuracy checks still permit release. Local target accuracy, per-program accuracy, weight concentration, and effective sample size are configured with
criticality: diagnostic, meaning their failure is only recorded and does not prevent release (configuration). The release decision excludes those failures (release decision), and a test explicitly accepts a weight ratio above the limit while assertingreleasable is True(test). The real run recorded a maximum-to-median weight ratio of 400 and 42 local targets more than 25% wrong, yet was accepted (run record). These limits should prevent release, with tests proving that excessive program totals and concentrated weights are rejected. -
High — The comparison that exposed the worst results is optional. The release assembler requires
score_vs_incumbent.jsonbut not the later evaluation against the current dataset's own target set (assembler inputs, packaged evidence). The required comparison reports 98.8% versus 60.4% on this branch's selected targets, while the omitted evaluation finds only 62.7% of local targets within 10%, versus 77.3% for the current dataset, as well as very large council-tax and program discrepancies (results). The assembler should require and preserve this evaluation, then apply explicit limits to the reported discrepancies. The assembler test currently uses only 30 households and two targets, so it cannot exercise these real-output conditions (test fixture). -
High — The evaluation tool permits a processing mode already proven to multiply national totals.
--engine-blocksaccepts any integer and passes it directly into the calculation (argument and use, calculation call). The branch documents that processing 15 groups inflated corporate land value exactly fifteen-fold, from £2.04tn to £30.7tn (evidence). This evaluator should reject every value except1, and an end-to-end command test should verify the refusal. -
Medium — The reported held-back score is not comparable to the fitted scores shown beside it. Held-back targets are weighted to give geographic categories equal influence and exclude national targets (calculation). The fitted candidate and current-dataset scores instead give each target row equal influence (scoring). Using the same per-row error cap does not put differently weighted results on one scale, so the direct comparison of
0.1895with0.1815is unsupported. Existing tests verify the cap and fold count but notloss_weight_scaleor the target-weighting rule (tests). All displayed scores should be recomputed with one weighting method, or clearly separated and no longer compared directly. -
Medium — A release produced from uncommitted code is accepted. The specialized UK validator reads the build description but does not call the general validation that requires
code.git_dirtyto be false; it checks only the build identifier and attempt identifier in this section (validator). The assembler test explicitly accepts both an unknown state andgit_dirty: true(test). This can produce data from code that differs from the recorded commit. The specialized validator should require a measured, clean working tree and test both rejection cases. -
Medium — Time-limited exclusions can expire after assembly without preventing upload. Expiry is checked while preparing the candidate (preparation check), but the assembled release validator only checks the copied coverage data structurally and the upload path only calls that validator (assembled validation, upload path). Several exclusions expire on 2026-10-03, so a release assembled in September could still be uploaded after its approvals expire. Publication should re-check every required expiry date, and tests should cover both expired and missing dates.
I ran all 17 changed test modules relevant to this work; they passed, as did git diff --check. I could not reproduce the full UK calculation because its private input data is not present locally. The real-output evidence above is therefore based on the committed run records; a sanitized machine-readable result should be retained and exercised by the release tests.
…usions (PR B) Maria's rulings of 2026-09-02: accept the SPI-frame proxy, the unbanded-only HMRC surface, the ONS total-population universe for age structure, and the VOA household proxy for council-tax bands; replace the UC household-grain basis with benefit-unit grain; re-word the census disclosure-control record to cover the local-authority leg the ladder binds; and exclude the Isles of Scilly and the City of London from the local-authority support floor on the measured K=4 and K=10 shortfalls. Windows to 2026-12-02. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…feed (#762 A13, PR B) The sixth licensed dry-run reached the cross-grain reconciliation and the engine refused the council-tax band groups: England and Scotland carry country-grain stock-by-band controls, Wales carries none in the pinned feed, so the 174 active Welsh local-authority cells form an unparented leg. Per Maria's A13 ruling those cells are signed-deferred (council_tax_wales_country_control_absent) until a Wales control exists; no Welsh control is minted from the local cells. Deferring an available fact needs an explicit opt-in on the area deferral (defer_if_compiles), scoped to this adjudication; ordinary missing-cell deferrals still go stale when their cell compiles. Surface 19,618 -> 19,444 active; council tax 2,541 -> 2,367; pins moved accordingly. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…t the receipts Measured at f100 on spine-m: K=4 refused 172 constituency UC child-band cells with zero support; K=10 cleared every constituency cell and refused 86 local-authority cells, 84 of them council-tax band H, because the spine carries 170 band-H households from 49 raw FRS sources. Per Maria's A14 ruling the 296 band-H local-authority cells are signed-deferred (council_tax_band_h_spine_support_absent) and the two support-floor exclusion areas' own local-authority cells are signed-deferred (local_authority_support_floor_excluded); the exclusion reasons record the amendment. Surface 19,444 -> 19,105 active; pins moved accordingly. The receipts document opens with R0-R5 (identity, dry-run K sweep and cross-grain receipt, f001, f010, the K=4 refusal, the K=10 measurement). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Both rules fit the local surface (every family but council tax at or above 99 percent within 10 percent); grain_equal lifts the national rows from 78 to 92 percent within 10 percent and concentrates weight harder (189 versus 12 constituencies below the ESS floor). Both sit on the 100x stretch bound, so A3 is the binding decision; the 20 and 10 measurements follow. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ement) Tightening the bound from 100 to 10 leaves loss and every fit share unchanged to a tenth of a point under both rules; bound 10 under uniform is the only run that clears the support floor (min constituency ESS 54.1, exit 0). grain_equal at 10 keeps the 92 percent national fit and misses the floor in five constituencies by 0.3 to 7.7 ESS; the K=15 escalation is R9. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ion) grain_equal at K=15 and bound 10 passes every release-blocking gate (min constituency ESS 54.1) while keeping the national rows at 92 percent within 10 percent; uniform at K=15 passes with more margin and 79 percent national. Memory stays flat with per-block engine resolution; wall grows 50 percent. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1500 epochs is close to converged under uniform and still moving under grain_equal; uniform spends the extra epochs on the national rows (78.6 to 85.2 percent within 10 percent), grain_equal spends them chasing the unreachable housing-benefit row (max/median 827 to 2,857). Health audit: mechanics clean across 14 runs; flags are the epoch cap, the census-2021 household mass cut landing on single pensioners, and six unreachable national rows (proposed rulings A15, A16). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…762) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…er uprating; A16 exclusions (#762) María's rulings of 2026-09-03, each the measured choice in receipts R6-R10: - UK_LOCAL_MAX_WEIGHT_RATIO 100 -> 10 (A3): no fit cost at 100/20/10, the only bound that clears the ESS floor, and the national doctrine's bound. - UK_LOCAL_TARGET_WEIGHT_RULE = grain_equal (A2): national rows 92-93 percent within 10 percent versus 78-85 under uniform; uniform stays a receipted override. - UK_LOCAL_CLONE_COUNT = 15 and UK_LOCAL_SOLVE_EPOCHS = 1500 as doctrine constants; the driver defaults read them and --release-candidate refuses other values. - A15: every ladder census household row is scaled by one national factor from the Ledger's ons.households_total fact at the calibration year (29,003,000 / 28,060,832 = 1.033577), fail-closed by name, receipted in the manifest, mandatory under --release-candidate. - A16: seven reviewed measure exclusions (land value x2, savings interest, housing benefit, SLC plan-2 borrowers x2, JSA claimants), unreachable by reweighting on spine-m, one-month window to 2026-10-03, tracked on microcosm#736. Receipt R12 records the applied values and the verification. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…e posture; manifest records measure exclusions (#762) Under the ruled doctrine (bound 10, grain_equal, K=15, 1500 epochs, A15 uprating, A16 exclusions) every release-blocking gate passes: national 94.7 percent within 10 percent, max/median weight 398 (was 2,857), median constituency ESS 219, households 28.93M, holdout mean 0.204 versus 0.304 uncalibrated. Tenure falls to 87 percent within 10 percent because its census-2021 cells were not uprated with the household rows (proposed A17). Driver: the gate battery now receives release_candidate from the CLI instead of a hard-coded False, and the manifest carries the measure exclusions the national compile stood on. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ipt areas the incumbent lacks (#762) On the 19,089 rows both can estimate the candidate's capped loss is 0.0146 against the incumbent's 0.181 (98.0 versus 60.4 percent within 10 percent; 16,973 versus 2,116 head-to-head wins). The incumbent has no weights for Northern Ireland's N09000011, so the scorer now records incumbent_missing_areas and scores those 16 rows candidate-only instead of refusing; the candidate's full-surface loss and its loss on the compared rows are both reported. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…on; withdraw two A16 exclusions; receipt block sensitivity (#762) Comparing initial national estimates between the 15-block and single-block runs: corporate land value is exactly 15x under blocks (the policyengine-uk formula allocates a fixed national aggregate by share of the block's total weighted corporate wealth), total land value 5.4x, SLC repayments 1.7 percent; 361 of 364 rows identical. Single-block resolution puts the land rows within 3 and 9 percent of the ONS balance sheet, so their two exclusions are withdrawn (register 51 -> 49; A16 is five rows). The manifest's measure_resolution now names the known population-normalised measures and says a per-block run is not evidence for adjudicating them. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…-candidate pre-flight (#762) María's A17 ruling (2026-09-03): the 1,436 census tenure cells (Census 2021; Scotland 2022) held to the calibration period take the same national household factor as the ladder rows, so the tenure partition keeps its published shares at the uprated level. Keyed on the hold metadata: a tenure cell compiled from a fact at the calibration period is never touched. The receipt rides ladder_household_uprating.tenure_cells. tools/preflight_uk_local_release_candidate.py checks, fail-closed and by name, the launch environment (signing key, pins, digests, doctrine) and a finished run (release posture attested, shippable, every release-blocking gate passed, single-block engine, doctrine values, A15/A17 uprating, measure exclusions and their windows, holdout, Logbook row, artifact digest). On R13 it names the four defects the re-run fixes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ation, registry entry, assembler, pre-flight release check (#762 A18) microcosm-uk-2024-25-dense follows the national constant-id approach under the non-default local-area role with UK evidence: the signed local gate-battery report verified with the executor's key (release posture, shippable, the six local entries, scoped digests pinned and lockstep-tested, HMAC recomputed), the incumbent score, and a uk_source_coverage.json naming the spine, Ledger artifact, ladder, incumbent, doctrine, exclusions, signed deferrals, holdout and uprating. Artifacts pin to the release id or a per-cut tag; the registry gains ("uk", 2025, "dense") in the private repo. tools/assemble_uk_dense_release_dir.py verifies the hash join, re-runs the candidate pre-flight, stages, validates and renames; it prints the --no-latest publication command for the human step. Runbook in docs/. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…t within 10 percent, shippable, holdout 0.190 (#762) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…re-flight authenticates the report as the contract will (#762) Found when assembling the dense line from R16: the release contract could not authenticate the signed local report. resign_uk_gate_report (used by finalize_uk_scoped_gate_report for the local and the national seam reports) signed with the Logbook's canonical JSON, which renders integral floats without the .0 (50 instead of 50.0), while the battery and every verifier use json.dumps's form. Any report whose gate details carry an integral float - the local battery's ESS floor 50.0 - therefore failed verification. Sign with the battery's canonical bytes; a regression test finalizes a report carrying 50.0 and verifies it under the contract. The candidate pre-flight now runs the contract's report verification so this class of defect surfaces right after a run. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ical form (#762) The test had encoded the Logbook canonical form the defective re-signer used; it now recomputes the HMAC the way every verifier does. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…dentical weights to R16) and the first contract-valid dense release directory (#762) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…, signed items included (#762 I9) tools/evaluate_uk_incumbent_surface.py scores a dense candidate on the vendored, hash-pinned fixtures of the incumbent's national (637 rows) and local (23,545 rows) target surfaces: the national rows join to our compiled specs by name, normalised name or single-cell contract id and are estimated through the un-excluded registry's constraint matrix over the calibrated weights, so the signed-out rows are measured too; the local rows map to our metrics by name (the VOA bands by alias) and are estimated from the engine-resolved household metrics; every row carries our status - bound, measure-excluded (with tracking and expiry), signed-deferred (with the reason id), no fact, or not ported with the parity register's concern - and the incumbent's own estimates on its local surface come from the extractor tables. Summaries by grain, source and metric; a markdown report that leads with the ugly part. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…the export rename (#762) The rowwise writer renames every entity's clone-index column to the artifact's shared clone_index at export; the Frame's flattening rule then refuses the artifact in the compact national loader, so no tool of ours could open the dense H5 (found by the incumbent-surface evaluator). The reader renames clone_index to <entity>_clone_index per table and assembles and validates the frame as the national loader does. The end-to-end test pins both behaviours; the evaluator loads through it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…repared frame (#762 I9) The resolver returns the adapter's prepared frame carrying the resolved measure columns; building the matrix over the raw frame skipped all 403 rows. Also keys the counterfactual filter on the contract's measurement kind, since compiled specs carry the measure as a column name. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ows; fix the local target-id lookup (#762 I9) The metric -> target-id map was inverted, so every incumbent local row read 'no_reference'; a unit test pins the direction. The incumbent's 198 regional rows (ONS age by region, VOA council-tax band by region) are now measured by rolling the frame up by assigned-area region, with the FRS region agreement receipted, instead of being reported as unmatched. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…items measured (#762 I9) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
#762 PR B) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… --engine-blocks K, exact golden frame (#762 PR B) An f100 run resolved in two engine blocks now has an end-to-end assertion that the manifest writes releasable: false with release_posture naming single_block_engine, so a future caller bypassing _release_verdict is caught. The dense builder's golden target_frame is compared exactly, like its matrix. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…er-row A16 issues, score hash-joins, measured git_dirty, K=15 texts, exact round-trip (#762) - The dense contract binds the signed gate report to the build's attempt_id (a validly signed report from another run is refused; a build manifest without attempt_id is refused). - The five A16 register rows point at their own spine-defect issues (#866-#869) so the October expiry follows the per-row pointer. - The assembler hash-joins the score receipt to the candidate diagnostics bytes and to the incumbent manifest's outputs, and records git_dirty as measured by the candidate build (the driver now measures it) or as unmeasured, never asserted clean. - The three K sentences state K=15 with history: Scilly 24 rows / ESS 8.1 and City of London 72 rows / ESS 11.0 on R17; band H has no support in 76 of the 296 deferred authorities at K=15 (84 at K=10); K=10 refused 86 local-authority cells (84 band-H plus the two micro-authorities). The membership register is regenerated from the pinned feed with only the rationale strings changed; the generator records the artifact-relative feed name instead of the operator's path. - The row-wise round-trip test compares every table exactly and the weight vector against the written column. - _is_census_vintage_hold takes its census years from the ladder's oa_vintage instead of a constant; a hold from a non-census vintage never takes the household factor. - Both bound-name forms (with and without the period) are tested. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The council-tax deferral test still pinned the K=10 sentence the review round replaced; it now pins the K=15 fact and the K=10 history. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
d5f04a8 to
3516100
Compare
|
@vahid-ahmadi @anth-volk Thanks for the reviews. I've addressed Anthony's findings and Vahid's second-pass points, and rebased onto For Anthony's six findings:
For Vahid's second pass, I've corrected the JSA ratio to 2.8×, clarified that City of London's 72 rows meet the row floor while ESS 11 remains below 50, enabled exact dtype checks in the roundtrip test, and formatted the council-tax assertion. Tenure-uprating receipts now distinguish attempted, eligible, applied and skipped holds with vintage/reason metadata, including missing and non-census cases; preflight checks the actual tenure holds. The dirty-code question is addressed above. These rationale edits preserve the approval fields. The rebase preserves main's 314 newly activated PIPR rows and all 513 signed deferrals, giving 19,419 active references. Regeneration from the authenticated updated Chronicle feed is reproducible, and both census checks pass. Final validation on the rebased code: 355 tests passed on Python 3.13.14 and 355 on Python 3.14.6 across the affected 17 modules. Independent implementation and rebase verification are clean; Ruff, changed-file formatting, CI inventory and diff checks pass. Hosted CI is still running, with no completed failures at posting time. The runbook, historical receipts and PR description now state the release limitation explicitly. No licensed build or calibration was rerun, no approval was renewed, and no historical verdict was re-signed. The additional review evidence is labelled as a transcription of published aggregates, not an original R18 replay. The existing dense candidate remains blocked from release. |
This completes PR B of #762, following the merged joint-solve machinery in #852: the measured UK local calibration doctrine, reviewed registers, census-vintage uprating, licensed-run receipts, and the dense dataset's assembly and validation path.
The retained R16/R17 candidate is release-blocked under the revised contract. Its historical shippable verdict and assembled-directory validation used the earlier policy. No calibration was rerun, historical result changed, or old gate report re-signed for these review fixes.
Build approach and reviewed scope
grain_equal, K=15 and 1,500 epochs. Release candidates require one engine block and the rotated holdout.Release checks strengthened after review
The four existing quality gates now block release with unchanged numerical limits: 25% target error, the existing hard family-fit rule, max/median weight ratio 100, and ESS fraction 0.01. The 10% family-fit diagnostic remains diagnostic.
Assembly and standalone validation require a complete incumbent-surface evaluation, authenticated against the candidate dataset, run manifest, diagnostics, Ledger and incumbent extraction. The checks rederive accuracy from finite row evidence, including measurable signed-deferred rows, and apply the existing absolute limits. Missing measurements or failed limits prevent release. The evaluation and its supporting manifests enter the artifact/checksum inventory.
The evaluator refuses engine-block counts other than one. Assembly and subsequent validation require measured clean source code and valid exclusion approval windows at the time of validation, closing the later-upload expiry gap. Signed gate reports remain bound to the candidate attempt, and score receipts remain joined to their inputs by hash.
Historical comparison and remaining data gaps
The run receipts preserve both comparisons. R16/R17 achieved 98.8% versus 60.4% within 10% on the selected comparison rows. R18's broader incumbent surface showed 62.7% versus 77.3% locally, exposing council-tax, housing-cost, program and demographic gaps. R17's max/median weight ratio was 400 against the unchanged limit of 100.
Holdout 0.1895 and incumbent fitted loss 0.1815 use different weighting and populations; they cannot be ranked directly. Scoring now carries and validates these separate bases. The review evidence is explicitly a transcription of published aggregates; original R18 row artifacts were unavailable for replay.
The assembly runbook covers
microcosm-uk-2024-25-dense, its non-default inspect role and separate human publication step. No data was published.Validation
At
35161003, rebased ontomainat5ab1b056, the final affected 17-module suite passed 355 tests on Python 3.13.14 and 355 on Python 3.14.6. Independent implementation and rebase verification are clean. Ruff, formatting of changed files, both census checks, reproducible target regeneration, CI inventory and diff checks pass. Hosted checks report separately. No fresh licensed build or calibration was run for these review fixes.Refs #762, #495, #665, #736, #796, #802, #866, #867, #868, #869. Merge remains subject to María's explicit go-ahead.