Repository navigation
Fix silent UC health reform routes - #2434
Conversation
|
Continuation handoff at
Evidence and handoff are in Published by the UK hub from the continuation job's bundle (head |
|
Addressed both round-three defects at pushed head P1 checks effective ordered writes, including later recorded/direct overrides. Both reported ordering examples now produce Final-head validation: 112 targeted passed, 45 scoped integration passed, the unchanged callback reproducer 1 passed, and 98 reviewer checks across 20 records passed. All 37 construction routes plus 2 MOCK baselines are byte-identical to merged main (SHA256 The six-hour wall limited the required local bulk run: 275 passed, 3 skipped, no observed failures, then interrupted with exit #2423, #2354 and merged #2428 have clean head/main merge controls. #2421 retains the identical untouched dataset-source test conflict as main; W1 functions/docstring remain unchanged. The hub owns independent re-review and W4 coordination; #2427 item 2 remains open. All model processes are stopped and generated |
juaristi22
left a comment
There was a problem hiding this comment.
Program review
Base repository: PolicyEngine/policyengine-uk
PR number: 2434
Reviewed head SHA: 636796c
Merge base SHA: 36d2feb
Mode: full
Scope: All changed reform-modifier replay/order/no-op/annualisation, construction compatibility, warning deferral and restored Core dataset claimant draw through finalUC.
Source manifest: /private/tmp/policyengine-command-runs/202cefbfced3/pr-2434-review-sources.json
Review status: COMPLETE
Source Documents
No source documents registered; see scope and validation.
Critical
None.
Should Address
None.
Suggestions
None.
Evidence Gaps
No material gaps reported.
Notes
- 112changedfile +10directrepositorytests PASS; two validfinalUCcontrols verify Coreseed43/suppliedstatus andstandaloneoverride+explicitrebalancing throughUC/HBAI.
- Rawcombinedcommand123PASS/1FAILED exit1: solefailure invalidreviewerperiodfixture, preservedasrawfailure. Correctedexternalcaseonly reran1PASS; noPRtestfailure orchangedsettings.124validselectedcases, notcombinedexit0.
- No statutoryvalue/reference/forecast/seed/share changes; amountYAMLdescriptiononly. Rootperformedpolicy/sourceapplicabilityrole; validemptyv1manifest,0newsourceacquisition, no legalcertification orencoder.
- Authorparent-local332casebulk remainsincomplete, mixed279/332coverage distinct; fullcapturedheadhostedCIallSUCCESS is separateevidence. No privatepopulation/replay/fulllocalmodelsuite.
- LocalCore3.32.27/Hypothesis6.168.2 differsfromlockedCore3.33.2/Hypothesis6.169. Sixproductionhashesmatchbody/capturedcommit; snapshotimports/cleanlinessverified.
- Implementationreviewclear; bodyW4coordinationremainsopen. FreshrequiredCI/activity/conflict/stackgates stillapply, no merge-readyclaim. Rootpolicyworkinterleaved/notseparatelytimed.
Validation Summary
124validselectedcases PASS (122repository+2finalUCcontrols). Initialcombined123pass/1invalidreviewerfixturefailure,312.34spytest/317.51sprocess; correctedonecase1PASS1.26s/4.11s. ExactheadallhostedCIchecksSUCCESS inclLint/TestResult/YAML/4Python/Fixevidence/docs. Allsixproductionhashesmatch, unchangedamountvalues/source/helper/pipeline.0sourceoriginals/renders;0findings/gaps. Originalparentbulk completionnotclaimed.
Timing
elapsed seconds: 877.43s; setup seconds: 2.08s; code role seconds: 686.07s; source acquisition seconds: 0.00s; adjudication seconds: 0.00s; consolidation cleanup seconds: 146.16s
Review Severity
APPROVE. Open findings: 0 critical, 0 should address, 0 suggestions.
|
Addressed the round-four mixed-order finding at 2ffa1b1 (fix A standalone mixed statutory/legacy composite now replays its complete requested order through the same override flag as Validation at the pushed head:
Current main's only merge conflict was a standard-allowance comment overlapping the warning call; both were retained. Final #2423/#2354 merge-tree controls are clean; #2421 retains the same untouched dataset-test conflict as main. All 2,753 source hashes stayed unchanged through validation. Generated The work is pushed and |
juaristi22
left a comment
There was a problem hiding this comment.
Rereviewed 2ffa1b13ede68cd8170262e078319fcd60840c6a against the previous reviewed ancestor 636796c89edd0ac7419ffa1105f3c2b1d5a455d3. Independent code/test and policy-applicability reviews are COMPLETE, with no actionable findings or material evidence gaps. The conservative no-op proof and full replay of an unproved mixed composite preserve the requested statutory/legacy write order, construction readings and per-child rollback.
Accepted coverage is 54 head cases and 10 separate cases on the clean integration with actual main 14999dc03502a2a269f0c955685593574da014d6 (tree 7f31ad2fa6ad88cb22d67596c7ecf4986ddd9993). This includes all ten new fixed cases, both original 32-example sequence properties and the unchanged 25-example warning property. The initial command retained 60 repository passes and four failures in two reviewer lifecycle premises repeated across both trees. The modifier does not rebuild stored UC inputs; correcting only those probes to use explicit rebalancing or a statutory construction disable passed all four separately. No passing repository cases were rerun, no PR code changed, and no single all-pass initial session is claimed. The final hypothetical UC controls give £8,698.80 and £12,298.80 through the documented routes.
Applicability checks independently confirmed unchanged statutory amounts, references, uprating, eligibility, seed and claimant shares; the amount YAML changes only its description. axiom: n/a is supported for this routing/data-plumbing scope. No external legal certification, private population replay, author 231-test count or rerun of all 124 prior-review cases is claimed. Local Core 3.32.27/Hypothesis 6.168.2 differs from locked 3.33.2/6.169.0.
W4 coordination, #2427 item 2 and the recorded #2421 integration issue remain separate merge conditions. This approval covers the implementation at the captured head and does not clear those conditions.
juaristi22
left a comment
There was a problem hiding this comment.
Incremental re-review of 546e351aeaeb: COMPLETE, no new findings.
Independent policy/source and code/test reviews checked the main integration: 101 of 103 incoming paths match captured main, while the dated-reform changes preserve the previously reviewed routing/replay logic. All 38 focused cases passed, including copy/order/no-op, indexation, rollback and final-UC lifecycle controls. Earlier test totals remain historical. This is an engineering review; no new statutory policy or encoded parity is certified.
Required hosted CI is still pending. The inherited constructor boundary in #2480, W4 coordination, #2427 item 2's active=False interpretation and data-source integration qualifications remain; this approval does not establish merge readiness.
Local validation used Core 3.32.27 rather than locked 3.33.2. Tests ran against captured main 1bdc7a0; main subsequently advanced to 3f8d4bd with release packaging/version-only changes, separately checked as outside this review scope. No tests on the new main combination are claimed.
|
Landed by the UK hub (merge queue, pinned to head
|
Fixes #2426
Part of #2427 (items 1 and 3; item 2 stays open).
Current head:
2ffa1b13ede68cd8170262e078319fcd60840c6a. Merged main:e7610ac52570b4f96d389aef98db9bb994bc3542.A downstream Budget replay called
Scenario.from_reform(d).simulation_modifier(sim)on an existing simulation and silently retained the old UC health-element amounts. The modifier now applies outstanding changes as annualised overrides and reports paths and keys when an override cannot affect an annual value. LCWRA amount reforms warn when UC rebalancing supersedes them, and Core simulations built from data receive the existing seeded claimant draw.Round 4: strict no-op boundary and mixed write order
The previous guard considered statutory assignments and legacy overrides separately. That could accept a mixed composite after checking the legacy writes after the statutory timeline, even when the requested order ended with a statutory write. For example, build with a 2027 window setting the basic rate to
.31, apply a legacy"2027-01-01"override of.35, then request(legacy, window): the modifier kept.35whereScenario.applygives.31.The shortcut now requires a conservative proof of the requested sequence. It skips a standalone dated composite only when:
Every standalone mixed statutory/legacy composite on a built simulation replays its full requested order using the same override flag as
Scenario.apply. A failed composite no-op proof replays all its children, retaining their joint order. A single pure reform can retain independently proven paths while applying its outstanding paths. Duplicate override-log entries are accepted, as on the existing legacy route. Overrides that cannot affect an annual value still raise with their paths and keys.Actual construction keeps its existing statutory and legacy readings. A proven pure legacy construction reform remains a no-op on a clone or branch, including a single-day 6 April key; an external 6 April-only override still raises because it contains no 1 January. Actual construction still runs each modifier once; the passing copy controls retain the original construction values without reapplying the proven sequence.
The new regressions cover the external legacy override, reversed mixed tuple/sum order, reversed key order within one dict, clones, and branches with
clone_system=True. The sequence property now samples legacy January keys alongside interval keys on shared paths and includes an explicit mixed counterexample.Mechanism and invariants
utils/scenario.pypreserves each dict or CoreReform.from_dictreading.utils/dated_reforms.py:591,684,711restricts the no-op shortcut to the exact suffix/current-value checks;utils/scenario.py:202replays an unproved dated composite through the apply flag.utils/dated_reforms.pyvalidates annualised overrides and reports malformed paths/keys together; malformed Core keys retain the existing atomic per-child rollback route. The modifier does not rebuild parameters or rerun build-time UC inputs and structural reforms. The durable route isSimulation(scenario=...).The outermost standalone composite defers
UCHealthElementOverrideWarninguntil all children finish. An amount change followed byactive=Falsecompletes without that warning, including under warning escalation; a single amount application still warns once. Warning years come from the shared productionuc_reform.REBALANCING_YEARS, used by the overwrite loop and derived from the projection horizon. The data-source gate usesutils.data_source.built_from_data, restoring the seeded draw for Core dataset simulations.Scenario.apply, or raise naming paths; proven already-applied construction changes retain their construction reading.Simulation/Microsimulationretain their existing draw status: datasets draw; situations draw nobody.The behavior changes are standalone modifiers applying outstanding writes or rejecting unreadable overrides, the diagnostic warning, and the Core dataset draw. #2427 item 2, the interpretation of
active=False, remains open.Ownership and integration
Round 4 changes the new guard code in
dated_reforms.pyand adds approximately 20 lines of routing in W1-ownedutils/scenario.py. It adds no changes tosimulation.pyortax_benefit_system.py. Earlier minimal simulation build hooks remain. W1'swrite_assignment,requires_projection,_entryand the dated-reforms module docstring remain untouched. The amount YAML keeps main's values, references and uprating, with the earlier description clarification.The PR already integrated #2284's LCWRA freeze, #2241's SDLT changes, the Scottish top-rate correction and #2428's horizon-based rebalancing years, protected amounts, index reform and claimant-share parameter. Round 4 main merge result: Merged at 2ffa1b1. Current main is newer than the reviewed a94c65d base; one standard-allowance comment overlapped the diagnostic call in uc_reform.py. Kept main's uprating-index comment plus warn_shadowed_lcwra_reform(sim), retaining every executable main change.
Inherited round-three merge-tree controls: #2423 (
08d177662), #2354 (11b806732) and merged #2428 (a66d1adbc) were clean against the then-head and main. #2421 (8e42bbdd5) had the same untouched dataset-source test conflict as its main control;simulation.pymerged cleanly. Any refreshed integration results: Final-head merge-tree controls remain clean for #2423 and #2354; #2421 retains the same dataset-source-test conflict as current main. Raw outputs are in .job/artifacts/final-merge-*.Modifier call sites
policyengine_uk/simulation.py, own before/after-load modifierssimulation.py, UC reform modifier;tests/test_uc_rebalancing.pyutils/scenario.py,Scenario.applytests/test_scenario_sum_timing.pyNone.Validation
Inherited round-three evidence at
636796c89: 112 targeted tests passed; independent revalidation confirmed 146 tests on the merged tree, all 54 previously pending nodes, 78 ordering probes, warning deferral and legacy-copy behavior against main. The 37 construction routes and both MOCK baselines were byte-identical. Full CI passed at that head. The round-four review identified the additional mixed-order cases described above.Round-four results:
636796c89: All ten new fixed regression cases and the widened prebuilt sequence-property node fail for the reported behavioral reason (.35 != .31): 11 failures, no import/setup failures.2ffa1b13e(-n4, numerical threads=1, MOCK only). Includes all ten new mixed cases and both widened sequence properties. Evidence:.job/artifacts/required-targeted-results.jsonand JUnit XML.e7610ac52, cloned main and cloned head2ffa1b13eare byte-identical (1,054,315 bytes each; SHA2563d6d8ecd36fa3444b29c4e110650a28a4fbb1e9b580dbcafaf528381c35ca3ef). All differential processes and the supplied summarizer exited 0; exact revisions and 37-route/two-baseline assertions are in.job/artifacts/differential-summary.json.p1/order_probes.py,p2/warning_probe.pyandscripts/legacy_and_rollback.py: All four supplied-script invocations exited 0: 78 order comparisons, 53 warning checks and ten legacy/rollback records on each source. Against accepted round-three payloads, all order/warning/main records and eight of ten head legacy records are unchanged. The only differences are the two diagnostic prefixes described below; all parameter values and override counts agree.make formatanduvx ruff format --check .: Passed before both commits and before the single successful push (1730 files already formatted on the merged tree).2ffa1b13esucceeded, including all four Python shards, YAML, Test / Result, Python 3.11–3.14 smoke imports, lint, fix evidence and documentation. Workflow. Captured independently from local validation in .job/artifacts/ci-final.json.The auxiliary round-three payload comparator exits 1 to flag exactly two differences: malformed
tuple_classesandsum_classesstandalone modifiers now raiseValueError: Cannot apply annualised overrides:rather thanValueError: Cannot read reform overrides:. The affected path (gov.hmrc.vat.standard_rate), invalid key (bad-vat-key), remaining error detail, before/after values (.20/.31) and override count (1) are identical. This is 149/151 unchanged payloads, with no value or log-count differences. Evidence:.job/artifacts/r3-probe-comparison.jsonandr3-diagnostic-changes.json.All local model validation uses MOCK data, foreground processes, at most four pytest workers and BLAS/OpenMP threads capped at four. Documentation build: not run locally for the small prose correction; both hosted documentation checks passed at the pushed head. Independent hub review and W4 coordination remain open.
Reproducer: policyengine_uk/tests/test_from_reform_modifier.py::test_mixed_composite_modifier_replays_after_external_legacy_override, policyengine_uk/tests/test_from_reform_modifier.py::test_mixed_composite_modifier_replays_reversed_statutory_and_legacy_order, policyengine_uk/tests/test_from_reform_modifier.py::test_scorecard_modifier_changes_parameters_and_lcwra, policyengine_uk/tests/test_uc_health_warnings.py::test_standalone_composite_defers_warning_until_active_override_runs
axiom: n/a: reform routing diagnostics and simulation data-source plumbing do not change statutory policy rules
Hub note (10/17): branch updated with main
1bdc7a0ab(merge546e351ae, tree8e9f00af). Main's changes since the review's baseb4dbaf57aare #2061's Pension Credit files only, with no file in common with this PR. Hub review round 4 (APPROVE WITH NITS at2ffa1b13e) ran its six test files, probes and differential on2ffa1b13emerged withb4dbaf57a. Its docs, changelog and test nits are in #2480.